簡體   English   中英

如何在同一圖上顯示條形圖和折線圖

[英]How to show a bar and line graph on the same plot

我無法在同一個圖上顯示條形圖和折線圖。 示例代碼:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

Df = pd.DataFrame(data=np.random.randn(10,4), index=pd.DatetimeIndex(start='2005', freq='M', periods=10), columns=['A','B','C','D'])

fig = plt.figure()
ax = fig.add_subplot(111)

Df[['A','B']].plot(kind='bar', ax=ax)
Df[['C','D']].plot(ax=ax, color=['r', 'c'])

你也可以試試這個:

fig = plt.figure()
ax = DF['A','B'].plot(kind="bar");plt.xticks(rotation=0)
ax2 = ax.twinx()
ax2.plot(ax.get_xticks(),DF['C','D'],marker='o')

我也想知道,但是所有現有的答案都不是為了在同一個圖上顯示條形圖和折線圖,而是在不同的軸上。

所以我自己尋找答案並找到了一個有效的例子 - 在同一個圖表上將 Pandas DataFrame 繪制為條形圖和線形圖 我可以確認它有效

讓我感到困惑的是,幾乎相同的代碼在那里工作,在這里不起作用 即,我復制了 OP 的代碼並且可以驗證它沒有按預期工作

我唯一能想到的是將索引列添加到Df[['A','B']]Df[['C','D']] ,但我不知道如何因為索引列沒有名稱供我添加。

今天,我意識到即使我可以讓它工作,真正的問題是Df[['A','B']]給出了一個分組(聚集)條形圖,但不支持分組(聚集)折線圖。

問題在於,pandas 條形圖函數將日期視為分類變量,其中每個日期都被視為一個唯一類別,因此 x 軸單位設置為從 0 開始的整數(就像沒有分配時的默認 DataFrame 索引一樣)。

pandas 線圖使用對應於 DatetimeIndex 的 x 軸單位,其中 0 位於 1970 年 1 月,整數表示從那時起的周期數(本例中為月)。 那么讓我們來看看在這種特殊情況下會發生什么:

import numpy as np     # v 1.19.2
import pandas as pd    # v 1.1.3

# Create random data
rng = np.random.default_rng(seed=1) # random number generator
df = pd.DataFrame(data=rng.normal(size=(10,4)),
                  index=pd.date_range(start='2005', freq='M', periods=10),
                  columns=['A','B','C','D'])

# Create a pandas bar chart overlaid with a pandas line plot using the same
# Axes: note that seeing as I do not set any variable for x, df.index is used
# by default, which is usually what we want when dealing with a dataset
# containing a time series
ax = df.plot.bar(y=['A','B'], figsize=(9,5))
df.plot(y=['C','D'], color=['tab:green', 'tab:red'], ax=ax);

pandas_bar_line_wrongx

酒吧無處可見。 如果您檢查正在使用的 x 個刻度,您會看到 1 月份的單個主要刻度是420然后是其他月份的這些次要刻度:

ax.get_xticks(minor=True)
# [421, 422, 423, 424, 425, 426, 427, 428, 429]

這是因為自 1970 年以來有 35 年 * 12 個月,編號從 0 開始,因此 2005 年 1 月落在 420。這解釋了為什么我們看不到條形。 如果您將 x 軸限制更改為從零開始,您將得到以下結果:

ax = df.plot.bar(y=['A','B'], figsize=(9,5))
df.plot(y=['C','D'], color=['tab:green', 'tab:red'], ax=ax)
ax.set_xlim(0);

pandas_bar_line_setxlim

從 1970 年 1 月開始,條形向左壓扁。 這個問題可以通過在 line plot 函數中設置use_index=False來解決,這樣線條也從 0 開始:

ax = df.plot.bar(y=['A','B'], figsize=(9,5))
df.plot(y=['C','D'], color=['tab:green', 'tab:red'], ax=ax, use_index=False)
ax.set_xticklabels(df.index.strftime('%b'), rotation=0, ha='center');

# # Optional: move legend to new position
# import matplotlib.pyplot as plt    # v 3.3.2
# ax.legend().remove()
# plt.gcf().legend(loc=(0.08, 0.14));

pandas_bar_line

如果您想要更高級的刻度標簽格式,您可以查看與此示例兼容的此問題的答案。 如果您需要更靈活/自動化的刻度標簽格式,由matplotlib.dates模塊中的刻度定位器和格式化程序提供,最簡單的方法是使用 matplotlib 創建繪圖,如本答案中所示

你可以在同一張圖上做類似的事情:

In [4]: Df = pd.DataFrame(data=np.random.randn(10,4), index=pd.DatetimeIndex(start='2005', freq='M', periods=10), columns=['A','B','C','D'])

In [5]: fig, ax = plt.subplots(2, 1) # you can pass sharex=True, sharey=True if you want to share axes.

In [6]: Df[['A','B']].plot(kind='bar', ax=ax[0])
Out[6]: <matplotlib.axes.AxesSubplot at 0x10cf011d0>

In [7]: Df[['C','D']].plot(color=['r', 'c'], ax=ax[1])
Out[7]: <matplotlib.axes.AxesSubplot at 0x10a656ed0>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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