Pandas 时间序列图设置 x 轴主要和次要刻度和标签 [英] Pandas timeseries plot setting x-axis major and minor ticks and labels

查看:98
本文介绍了Pandas 时间序列图设置 x 轴主要和次要刻度和标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to be able to set the major and minor xticks and their labels for a time series graph plotted from a Pandas time series object.

Pandas 0.9新功能"页面说:

The Pandas 0.9 "what's new" page says:

"您可以使用 to_pydatetime 或为时间戳类型"

"you can either use to_pydatetime or register a converter for the Timestamp type"

但我不知道如何做到这一点,以便我可以使用 matplotlib ax.xaxis.set_major_locatorax.xaxis.set_major_formatter(和次要的)命令.

but I can't work out how to do that so that I can use the matplotlib ax.xaxis.set_major_locator and ax.xaxis.set_major_formatter (and minor) commands.

如果我在不转换 pandas 时间的情况下使用它们,则 x 轴刻度和标签最终会出错.

If I use them without converting the pandas times, the x-axis ticks and labels end up wrong.

通过使用 'xticks' 参数,我可以将主要刻度传递给 pandas.plot,然后设置主要刻度标签.我无法弄清楚如何使用这种方法进行小刻度.(我可以在 pandas.plot 设置的默认小刻度上设置标签)

By using the 'xticks' parameter I can pass the major ticks to pandas.plot, and then set the major tick labels. I can't work out how to do the minor ticks using this approach. (I can set the labels on the default minor ticks set by 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
%a'))
ax.xaxis.grid(True, which="minor")
ax.xaxis.grid(False, which="major")
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('


%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
%d
%h
%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 标签,我已经能够更接近我想要的布局:

Update: I've been able to get closer to the layout I wanted by using a loop to build the major xtick labels:

# 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
%a
%h'))
        month = x.month
    else:
        xticklabels.append(x.strftime('%d
%a'))

然而,这有点像使用 ax.annotate 做 x 轴:可能但并不理想.

However, this is a bit like doing the x-axis using ax.annotate: possible but not ideal.

推荐答案

pandasmatplotlib.dates 都使用 matplotlib.units 来定位蜱虫.

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

但是,虽然 matplotlib.dates 有手动设置刻度的便捷方法,但到目前为止,pandas 似乎专注于自动格式化(您可以查看 代码,用于pandas中的日期转换和格式化).

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).

所以目前使用 matplotlib.dates 似乎更合理(正如@BrenBarn 在他的评论中提到的那样).

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
%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
ax.xaxis.set_major_locator(dates.MonthLocator())
ax.xaxis.set_major_formatter(dates.DateFormatter('


%b
%Y'))
plt.tight_layout()
plt.show()

(我的语言环境是德语,所以星期二 [Tue] 变成 Dienstag [Di])

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

这篇关于Pandas 时间序列图设置 x 轴主要和次要刻度和标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆