Tôi muốn có thể đặt các xticks chính và phụ và nhãn của chúng cho biểu đồ chuỗi thời gian được vẽ từ đối tượng chuỗi thời gian Pandas.
Trang "có gì mới" của Pandas 0.9 cho biết:
"bạn có thể sử dụng to_pydatetime hoặc đăng ký bộ chuyển đổi cho loại Dấu thời gian"
nhưng tôi không thể tìm ra cách thực hiện điều đó để có thể sử dụng các lệnh matplotlib ax.xaxis.set_major_locator
và ax.xaxis.set_major_formatter
(và lệnh nhỏ).
Nếu tôi sử dụng chúng mà không chuyển đổi thời gian của gấu trúc, các dấu và nhãn trục x sẽ kết thúc sai.
Bằng cách sử dụng tham số 'xticks', tôi có thể chuyển các dấu chính cho pandas.plot, sau đó đặt các nhãn đánh dấu chính. Tôi không thể tìm ra cách làm sạch bọ ve nhỏ bằng cách sử dụng phương pháp này. (Tôi có thể đặt nhãn trên các bọ ve nhỏ mặc định do pandas.plot đặt)
Đây là mã thử nghiệm của tôi:
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']
và đầu ra của nó:
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
Cập nhật: Tôi đã có thể tiến gần hơn đến bố cục mà tôi muốn bằng cách sử dụng một vòng lặp để tạo các nhãn xtick chính:
# 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'))
Tuy nhiên, điều này hơi giống như thực hiện trục x bằng cách sử dụng ax.annotate
: có thể nhưng không lý tưởng.