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

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

熊猫0.9“最新消息”页面写道:

”您可以使用 to _ pydatetime 或为 时间戳类型”

但是我不知道如何使用 matplotlib ax.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

Graph with strange dates on 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

Graph with correct dates

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 轴: 可能,但不理想。

125822 次浏览

Both pandas and matplotlib.dates use matplotlib.units for locating the ticks.

But while matplotlib.dates has convenient ways to set the ticks manually, pandas seems to have the focus on auto formatting so far (you can have a look at the code for date conversion and formatting in pandas).

So for the moment it seems more reasonable to use matplotlib.dates (as mentioned by @BrenBarn in his comment).

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

(my locale is German, so that Tuesday [Tue] becomes Dienstag [Di])

To turn off Pandas Datetime tick adjustment, you have to add the argument x_compat=True

Example:

ds.plot(x_compat=True)

See more examples in the Pandas documentation: Suppressing tick resolution adjustment