Biểu đồ thời gian gấu trúc thiết lập dấu tích và nhãn chính và phụ trục x


87

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

Biểu đồ với các ngày kỳ lạ trên 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

Vẽ biểu đồ với ngày tháng chính xác

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.


1
Tôi biết điều này không thực sự trả lời được câu hỏi, nhưng là một cách tiếp cận chung khi tôi thực sự quan tâm đến cách một cốt truyện trông như thế nào, tôi thường cố gắng lấy một phiên bản vector của nó và làm cho nó trông đẹp mắt trong Illustrator hoặc Inkscape. Tôi thấy hầu hết những người khác mà tôi biết dường như cũng làm như vậy.
John McDonnell

2
Bạn có thể bỏ qua hoàn toàn các đối số cho plothàm pandas và đặt tất cả các dấu tích sau khi vẽ biểu đồ, bằng cách sử dụng các phương thức matplotlib của axđối tượng trả về (ví dụ ax.set_xticks:) không?
BrenBarn

@BrenBarn Tôi không thể tìm ra cách lấy ngày làm ngày trong trăn thay vì ngày giờ cho gấu trúc cho các phương thức matplotlib. Câu trả lời của bmu khắc phục điều đó bằng cách chuyển đổi ngày trước khi vẽ biểu đồ.
brenda

Câu trả lời:


89

Cả hai pandasmatplotlib.datessử dụng matplotlib.unitsđể xác định vị trí của bọ ve.

Nhưng trong khi matplotlib.datescó những cách thuận tiện để đặt dấu kiểm theo cách thủ công, gấu trúc dường như tập trung vào định dạng tự động cho đến nay (bạn có thể xem chuyển đổi ngày và định dạng ở gấu trúc).

Vì vậy, hiện tại, nó có vẻ hợp lý hơn để sử dụng matplotlib.dates(như @BrenBarn đã đề cập trong nhận xét của anh ấy).

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

(ngôn ngữ của tôi là tiếng Đức, vì vậy thứ Ba [Thứ] trở thành Dienstag [Di])

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.