Pandas timeseries พล็อตการตั้งค่าแกน x เห็บและป้ายกำกับหลักและรอง


87

ฉันต้องการตั้งค่า xticks หลักและรองและป้ายกำกับสำหรับกราฟอนุกรมเวลาที่พล็อตจากวัตถุอนุกรมเวลาของ Pandas

หน้า 0.9 "มีอะไรใหม่" ของ Pandas ระบุว่า:

"คุณสามารถใช้ to_pydatetime หรือลงทะเบียนตัวแปลงสำหรับประเภท Timestamp"

แต่ฉันไม่สามารถหาวิธีทำได้เพื่อให้ฉันสามารถใช้คำสั่งmatplotlib ax.xaxis.set_major_locatorและax.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'))

อย่างไรก็ตามนี่ก็เหมือนกับการทำแกน x โดยใช้ax.annotate: เป็นไปได้ แต่ไม่เหมาะ


1
ฉันรู้ว่านี่ไม่ได้ตอบคำถามจริงๆ แต่เป็นแนวทางทั่วไปเมื่อฉันสนใจว่าพล็อตจะเป็นอย่างไรโดยทั่วไปฉันเพียงแค่พยายามหาเวอร์ชันเวกเตอร์ของมันและทำให้มันดูดีใน Illustrator หรือ Inkscape ฉันพบว่าคนอื่น ๆ ส่วนใหญ่ที่ฉันรู้จักดูเหมือนจะทำเช่นเดียวกัน
John McDonnell

2
คุณสามารถเพิกเฉยต่ออาร์กิวเมนต์ของplotฟังก์ชันแพนด้าและตั้งค่าเห็บทั้งหมดหลังจากการพล็อตโดยใช้เมธอด matplotlib ของaxอ็อบเจ็กต์ที่ส่งคืน(เช่นax.set_xticks) ได้หรือไม่?
BrenBarn

@BrenBarn ฉันคิดไม่ออกว่าจะรับวันที่เป็นวันที่ python ได้อย่างไรแทนที่จะเป็นวันที่และเวลาของแพนด้าสำหรับวิธี matplotlib คำตอบโดย bmu แก้ไขโดยการแปลงวันที่ก่อนการลงจุด
brenda

จริงๆคุณสามารถมีพล็อตหมีแพนด้าและยังคงใช้ matplotlib.dates วันโดยไม่ต้องแปลงใด ๆ testSeries.plot(x_compat=True)ที่จำเป็นต้องขอบคุณอาร์กิวเมนต์นี้: สิ่งนี้ถูกเพิ่มเข้ามาในหมีแพนด้าเพียงไม่กี่สัปดาห์หลังจากที่คุณโพสต์คำถามนี้
Patrick FitzGerald

คำตอบ:


89

ทั้งสองอย่างpandasและmatplotlib.datesใช้matplotlib.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])

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.