【问题标题】:How to include first/last dates in matplotlib plot如何在 matplotlib 图中包含第一个/最后一个日期
【发布时间】:2019-08-16 17:42:25
【问题描述】:

我在 jupyter 笔记本中使用 matplotlib 绘制了一个时间序列图。

import numpy as np
import matplotlib.pyplot as plt
from numpy.polynomial import polynomial as P
from datetime import date

首先,我创建初始图并描述 x 和 y:

fig, ax = plt.subplots(1,1,dpi=200)

dates = ['2017-08', '2017-09', '2017-10', '2017-11', '2017-12', '2018-01',
       '2018-02', '2018-03', '2018-04', '2018-05', '2018-06', '2018-07',
       '2018-08', '2018-09', '2018-10', '2018-11', '2018-12', '2019-01',
       '2019-02', '2019-03', '2019-04', '2019-05', '2019-06', '2019-07']

y = [2002, 2630, 2032, 1816, 1867, 2282, 2064, 2316, 2391, 2134, 1833, 1982, 2053, 1836, 2107, 1891, 1729, 1794, 1908, 2267, 2194, 2248, 2216, 2408,]

# Convert to ordinal dates here so that computation of x degree polynomial is easier
x = list(map(lambda x: date.fromisoformat(f'{x}-01').toordinal(), dates))

其次,我在图中添加两条线(线和多边形拟合):

# plot the line
line, = ax.plot(x, y, 'k', linewidth=3, label='Awesome SO answers')

# create 2nd degree Polynomial series instance
c1 = P.Polynomial.fit(x, y, 2)

# Returns the x, y values at n linearly spaced points across the domain.
x1, y1 = c1.linspace(n=len(x))

poly2, = ax.plot(x1, y1, 'r', linewidth=3, label='2nd deg poly fit')

# create labels and call set_xticklabels
# I think this is were the problem is. 
# How do I set the x ticks to include the first/last date?
new_labels = [date.fromordinal(int(xt)) for xt in ax.get_xticks()]
ax.set_xticklabels(new_labels)

# make plot look nicer, add legend
ax.xaxis.set_tick_params(rotation=30, labelsize=8)
first_legend = ax.legend(handles=[line, poly2], loc='best')

看到下面的输出似乎隐藏了第一个/最后一个日期。请注意,输出中 x 上的最后一个数据点是“2019-05”,但实际上是“2019-07”。 最好包含最后日期,以便清楚数据是最新的。 matplotlib 必须使用一些规则来计算 xticks。如何让 xticks 尊重第一个/最后一个日期?

【问题讨论】:

  • 哦,我想我明白了。首先使用 np.linspace(min(x), max(x), num=6) 在指定间隔内创建均匀间隔的数组,然后使用输出调用 ax.set_xticks()

标签: python-3.x numpy matplotlib plot


【解决方案1】:

当我检查ax.get_xticks() 的值时,我注意到x 的最小值/最大值不包括。所以难怪他们没有出现。为了让它工作,我只需要使用np.linspace重新创建一个包含x的最小值/最大值的序数数组。

要查看之前设置的xticks,我们可以运行:

print(ax.get_xticks()) # [736500. 736600. 736700. 736800. 736900. 737000. 737100. 737200. 737300.]

我们可以验证没有包含最小值/最大值:

print(f'min: {min(x)} max: {max(x)}') # min: 736542 max: 737241

我们想要的是一个从 min(x) 开始到 max(x) 结束的指定间隔内的均匀间隔数组:

# create new array of ordinals
x_ticks = np.linspace(min(x), max(x), num=6) # [736542.  736681.8 736821.6 736961.4 737101.2 737241. ]

# Now set the xticks so that the new_labels array will be computed with the correct values
ax.set_xticks(x_ticks)

# create new labels
new_labels = [date.fromordinal(int(xt)).strftime("%b %Y") for xt in ax.get_xticks()]
# ['Aug 2017', 'Dec 2017', 'May 2018', 'Sep 2018', 'Feb 2019', 'Jul 2019']

# set the labels
ax.set_xticklabels(new_labels)

【讨论】:

  • 除了现在刻度线可以关闭多达(略少于)一个月。 IE。 2017 年 8 月可能是 8 月 1 日,2019 年 7 月可能是 7 月 30 日。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
相关资源
最近更新 更多