我希望能够为从Pandas时间序列对象绘制的时间序列图设置主要和次要xtick及其标签。
Pandas 0.9“What's new”页面说:
“您可以使用to_pydatetime或注册Timestamp类型的转换器”
但我不知道如何做到这一点,以便我可以使用matplotlib ax.xaxis.set_major_locator
和ax.xaxis.set_major_formatter
(和minor)命令。
如果我使用它们而不转换pandas时间,x轴刻度和标签最终会出错。
通过使用'xticks'参数,我可以将主要标记传递给pandas的.plot
,然后设置主要标记标签。我无法使用这种方法计算出如何进行次要标记(我可以在pandas的.plot
设置的默认次要标记上设置标签)。
下面是我的测试代码:
xaxis上带有奇怪日期的图表
import pandas as pd
import matplotlib.dates as mdates
import numpy as np
dateIndex = pd.date_range(start='2011-05-01', end='2011-07-01', freq='D')
testSeries = pd.Series(data=np.random.randn(len(dateIndex)), index=dateIndex)
ax = plt.figure(figsize=(7,4), dpi=300).add_subplot(111)
testSeries.plot(ax=ax, style='v-', label='first line')
# using MatPlotLib date time locators and formatters doesn't work with new
# pandas datetime index
ax.xaxis.set_minor_locator(mdates.WeekdayLocator())
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.xaxis.grid(False, which="major")
ax.xaxis.set_major_formatter(mdates.DateFormatter('\n\n\n%b%Y'))
plt.show()
字符串
的数据
日期正确的图表(无小刻度)
# set the major xticks and labels through pandas
ax2 = plt.figure(figsize=(7,4), dpi=300).add_subplot(111)
xticks = pd.date_range(start='2011-05-01', end='2011-07-01', freq='W-Tue')
testSeries.plot(ax=ax2, style='-v', label='second line', xticks=xticks.to_pydatetime())
ax2.set_xticklabels([x.strftime('%a\n%d\n%h\n%Y') for x in xticks]);
# remove the minor xtick labels set by pandas.plot
ax2.set_xticklabels([], minor=True)
# turn the minor ticks created by pandas.plot off
plt.show()
型
的
**更新:**我已经能够通过使用循环来构建主要的xtick标签来接近我想要的布局:
# only show month for first label in month
month = dStart.month - 1
xticklabels = []
for x in xticks:
if month != x.month :
xticklabels.append(x.strftime('%d\n%a\n%h'))
month = x.month
else:
xticklabels.append(x.strftime('%d\n%a'))
型
然而,这有点像使用ax.annotate
来处理x轴:可能但不理想。
在绘制pandas时间序列数据时,如何设置主刻度和次刻度?
3条答案
按热度按时间8yoxcaq71#
pandas
和matplotlib.dates
都使用matplotlib.units
定位刻度。但是,虽然
matplotlib.dates
有方便的方法来手动设置刻度,但到目前为止,pandas似乎专注于自动格式化(你可以看看code在pandas中的日期转换和格式化)。因此,目前使用
matplotlib.dates
似乎更合理(正如@BrenBarn在他的评论中提到的)。字符串
x1c 0d1x的数据
(my”““”
gzszwxb42#
要关闭Pandas日期时间刻度调整,必须添加参数
x_compat=True
范例:
字符串
请参阅Pandas文档中的更多示例:抑制刻度分辨率调整
ecr0jaav3#
在matplotlib的
plot()
中,默认的时间序列单位是1天,但在pandas的plot()
中,1单位等于时间序列的频率,所以如果频率是1天,1单位就是1天;如果是1小时,则是1小时等等。这使得matplotlib和pandas的plot()
调用在时间序列数据上有所不同。如果时间序列的频率为1天,则
matplotlib.dates.WeekdayLocator
、matplotlib.dates.MonthLocator
等。可以“定位”tick位置1,因为pandasplot()
使用1天作为创建xtick位置的基本单位(与matplotlib的默认值一致)。由于pandas的
plot()
调用返回Axes对象,因此可以使用matplotlib.dates
修改Axes对象的刻度标签。字符串
x1c 0d1x的数据
然而,如果频率不是1天,而是1周,那么
matplotlib.dates
将无法定位位置,因为,如前所述,pandas的plot()
将单位设置为与时间序列频率(1周)相同,这“混淆”了matplotlib.dates
。因此,如果我们尝试使用设置s1
的刻度标签相同的代码来设置s2
的刻度标签,那么我们将得到非常错误的刻度标签。要“解决”这个问题,一种方法是通过传递
x_compat=True
来删除pandas的自动刻度分辨率调整。然后可以使用matplotlib的分辨率设置主/次刻度标签;换句话说,它可以以与上述相同的方式设置。型
的
解决这个问题的另一种方法是使用matplotlib的
plot()
来代替(正如@bmu所建议的那样)。因为matplotlib中的单位是固定的,所以我们可以像上面那样设置刻度标签,没有问题。型
1
matplotlib.dates.num2timedelta(1) == datetime.timedelta(days=1)
为真。