熊猫时间序列图设置 x 轴主要和次要刻度和标签
Posted
技术标签:
【中文标题】熊猫时间序列图设置 x 轴主要和次要刻度和标签【英文标题】:Pandas timeseries plot setting x-axis major and minor ticks and labels 【发布时间】:2012-10-08 09:34:20 【问题描述】:我希望能够为从 Pandas 时间序列对象绘制的时间序列图设置主要和次要 xticks 及其标签。
Pandas 0.9“新功能”页面显示:
"您可以使用 to_pydatetime 或为 时间戳类型"
但我不知道如何做到这一点,以便我可以使用 matplotlib ax.xaxis.set_major_locator
和 ax.xaxis.set_major_formatter
(和次要)命令。
如果我在不转换 pandas 时间的情况下使用它们,x 轴刻度和标签最终会出错。
通过使用 'xticks' 参数,我可以将主要刻度传递给 pandas.plot,然后设置主要刻度标签。我不知道如何使用这种方法来做小滴答声。 (我可以在 pandas.plot 设置的默认次要刻度上设置标签)
这是我的测试代码:
import pandas
print 'pandas.__version__ is ', pandas.__version__
print 'matplotlib.__version__ is ', matplotlib.__version__
dStart = datetime.datetime(2011,5,1) # 1 May
dEnd = datetime.datetime(2011,7,1) # 1 July
dateIndex = pandas.date_range(start=dStart, end=dEnd, freq='D')
print "1 May to 1 July 2011", dateIndex
testSeries = pandas.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(matplotlib.dates.WeekdayLocator(byweekday=(1),
interval=1))
ax.xaxis.set_minor_formatter(matplotlib.dates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.xaxis.grid(False, which="major")
ax.xaxis.set_major_formatter(matplotlib.dates.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 = pandas.date_range(start=dStart, end=dEnd, freq='W-Tue')
print "xticks: ", xticks
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]);
# set the text of the first few minor ticks created by pandas.plot
# ax2.set_xticklabels(['a','b','c','d','e'], minor=True)
# remove the minor xtick labels set by pandas.plot
ax2.set_xticklabels([], minor=True)
# turn the minor ticks created by pandas.plot off
# plt.minorticks_off()
plt.show()
print testSeries['6/4/2011':'6/7/2011']
及其输出:
pandas.__version__ is 0.9.1.dev-3de54ae
matplotlib.__version__ is 1.1.1
1 May to 1 July 2011 <class 'pandas.tseries.index.DatetimeIndex'>
[2011-05-01 00:00:00, ..., 2011-07-01 00:00:00]
Length: 62, Freq: D, Timezone: None
xticks: <class 'pandas.tseries.index.DatetimeIndex'>
[2011-05-03 00:00:00, ..., 2011-06-28 00:00:00]
Length: 9, Freq: W-TUE, Timezone: None
2011-06-04 -0.199393
2011-06-05 -0.043118
2011-06-06 0.477771
2011-06-07 -0.033207
Freq: D
更新:通过使用循环来构建主要的 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 轴:可能但并不理想。
【问题讨论】:
我知道这并不能真正回答问题,但作为一种通用方法,当我真正关心情节的外观时,我通常只是尝试获取它的矢量版本并让它看起来不错在 Illustrator 或 Inkscape 中。我发现我认识的大多数其他人似乎也这样做。 你能完全忽略 pandasplot
函数的参数并在绘图后使用返回的ax
对象(例如ax.set_xticks
)的matplotlib 方法设置所有刻度吗?
@BrenBarn 我无法弄清楚如何将日期作为 python 日期而不是用于 matplotlib 方法的 pandas 日期时间。 bmu 的答案通过在绘图前转换日期来解决这个问题。
您实际上可以使用 pandas 进行绘图,并且仍然可以使用 matplotlib.dates 而无需任何日期转换,这要归功于这个参数:testSeries.plot(x_compat=True)
。这是added to pandas,就在您发布此问题几周后。
【参考方案1】:
pandas
和 matplotlib.dates
都使用 matplotlib.units
来定位刻度。
虽然matplotlib.dates
有手动设置刻度的便捷方法,但到目前为止,pandas 似乎专注于自动格式化(您可以查看code 以了解 pandas 中的日期转换和格式化)。
所以目前使用matplotlib.dates
似乎更合理(正如@BrenBarn 在他的评论中提到的那样)。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as dates
idx = pd.date_range('2011-05-01', '2011-07-01')
s = pd.Series(np.random.randn(len(idx)), index=idx)
fig, ax = plt.subplots()
ax.plot_date(idx.to_pydatetime(), s, 'v-')
ax.xaxis.set_minor_locator(dates.WeekdayLocator(byweekday=(1),
interval=1))
ax.xaxis.set_minor_formatter(dates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
ax.xaxis.set_major_locator(dates.MonthLocator())
ax.xaxis.set_major_formatter(dates.DateFormatter('\n\n\n%b\n%Y'))
plt.tight_layout()
plt.show()
(我的语言环境是德语,所以星期二 [Tue] 变成 Dienstag [Di])
【讨论】:
【参考方案2】:要关闭 Pandas 日期时间刻度调整,您必须添加参数x_compat=True
例子:
ds.plot(x_compat=True)
在 Pandas 文档中查看更多示例:Suppressing tick resolution adjustment
【讨论】:
很好的提示,在文档中很难找到(至少 df.plot 是这样)!以上是关于熊猫时间序列图设置 x 轴主要和次要刻度和标签的主要内容,如果未能解决你的问题,请参考以下文章