熊猫时间序列图设置x轴主要和次要刻度线和标签


87

我希望能够为从熊猫时间序列对象绘制的时间序列图设置主要和次要xticks及其标签。

熊猫0.9“新增功能”页面显示:

“您可以使用to_pydatetime或为Timestamp类型注册一个转换器”

但是我不知道该怎么做,以便可以使用matplotlibax.xaxis.set_major_locatorax.xaxis.set_major_formatter(和次要)命令。

如果我使用它们而没有转换熊猫时间,则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

在xaxis上带有奇怪日期的图

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轴。


1
我知道这并不能真正回答问题,但是作为一种通常的方法,当我真正关心绘图的外观时,我通常会尝试获取其矢量版本,并使其在Illustrator或Inkscape中看起来不错。我发现我认识的大多数其他人似乎也都这样做。
约翰·麦克唐纳

2
您是否可以完全plot通过使用返回ax对象(例如ax.set_xticks)的matplotlib方法完全忽略pandas函数的参数并设置所有刻度线?
布伦·巴恩(BrenBarn)2012年

@BrenBarn我不知道如何将日期作为python日期而不是matplotlib方法的熊猫日期时间。bmu的答案通过在绘制之前转换日期来解决此问题。
brenda

Answers:


89

两者pandasmatplotlib.datesmatplotlib.units定位蜱。

但是,尽管matplotlib.dates有一些方便的方法可以手动设置刻度线,但到目前为止,熊猫似乎一直专注于自动格式化(您可以查看熊猫中日期转换和格式化的代码)。

因此,目前看来使用起来更合理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()

pandas_like_date_fomatting

(我的语言环境是德语,因此星期二[Tue]成为Dienstag [Di])

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.