簡體   English   中英

使用 pandas 和 Matplotlib 自定義日期時間索引的分組條形圖

[英]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 月。 分組條形圖,但 x 軸標簽很爛

我認為使用自定義日期格式化程序會起作用,因此我嘗試了

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM