[英]Grouped Bar-Chart with customized DateTime Index using pandas and Matplotlib
我想創建一個顯示自定義日期時間索引的分組條形圖 - 僅顯示月份和年份而不是完整日期。 我希望條形圖被分組而不是堆疊。
我假設 pandas 可以輕松處理這個問題,使用:
import pandas as pd
import matplotlib.pylab as plt
import matplotlib.dates as mdates
testdata = pd.DataFrame({"A": [1, 2, 3]
,"B": [2, 3, 1]
, "C": [2, 3, 1]}
,index=pd.to_datetime(pd.DatetimeIndex(
data=["2019-03-02", "2019-04-01","2019-05-01"])))
ax = testdata.plot.bar()
這將創建我想要的 plot,我只想將日期更改為更簡單的內容,例如 2019 年 3 月、2019 年 4 月、2019 年 5 月。
我認為使用自定義日期格式化程序會起作用,因此我嘗試了
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
但比我的標簽完全消失了。 而這個問題意味着 pandas 和 DateFormatter 的關系有點困難。 因此,我嘗試使用 Matplotlib 基礎知識來做到這一點:
fig, ax = plt.subplots()
width = 0.8
ax.bar(testdata.index, testdata["A"])
ax.bar(testdata.index, testdata["B"])
ax.bar(testdata.index, testdata["C"])
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
plt.show()
現在日期表示符合預期(盡管可以減少空格),但數據重疊,這無濟於事。
由於我使用的 DateTime-Index,定義寬度並從 x 值中減去它(如通常建議的那樣)將無濟於事。 我收到一個錯誤,即不支持減去 DatetimeIndes 和 float。
fig, ax = plt.subplots()
width = 0.8
ax.bar(testdata.index-width, testdata["A"])
ax.bar(testdata.index, testdata["B"])
ax.bar(testdata.index+width, testdata["C"])
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
plt.show()
所以現在我的想法已經用完了,希望得到輸入
Pandas 條形圖是分類的。 所以也許你想多了,只是想使用你想看到的字符串作為軸上的類別 label 作為索引?
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({"A": [1, 2, 3]
,"B": [2, 3, 1]
, "C": [2, 3, 1]}
,index=pd.to_datetime(pd.DatetimeIndex(
data=["2019-03-02", "2019-04-01","2019-05-01"])))
df.index = [d.strftime("%b %Y") for d in df.index]
ax = df.plot.bar()
plt.show()
ax.xaxis.set_major_locator(mdates.MonthLocator())
失敗的原因是在幕后, pandas 將條形圖與range(len(df))
相對應,然后相應地重命名刻度。
您可以在 plot 之后獲取 xticklabels,然后重新格式化:
ax = testdata.plot.bar()
ticks = [tick.get_text() for tick in ax.get_xticklabels()]
ticks = pd.to_datetime(ticks).strftime('%b %Y')
ax.set_xticklabels(ticks)
這給出了與 ImpotanceOfBeingErnest 相同的結果:
另一種可能更好的方法是移動每列的條形。 當您有很多列並且想要減少 xticks 的數量時,這會更好。
fig, ax = plt.subplots()
# define the shift
shift = pd.to_timedelta('1D')
# modify the base of each columns, can do with a for loop
ax.bar(testdata.index + shift, testdata["A"])
ax.bar(testdata.index, testdata["B"])
ax.bar(testdata.index - shift, testdata["C"])
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
plt.show()
Output:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.