Pandas:带有两个条形图和两个 y 轴的条形图

Posted

技术标签:

【中文标题】Pandas:带有两个条形图和两个 y 轴的条形图【英文标题】:Pandas: Bar-Plot with two bars and two y-axis 【发布时间】:2014-08-02 16:50:23 【问题描述】:

我有一个如下所示的 DataFrame:

     amount     price
age
A     40929   4066443
B     93904   9611272
C    188349  19360005
D    248438  24335536
E    205622  18888604
F    140173  12580900
G     76243   6751731
H     36859   3418329
I     29304   2758928
J     39768   3201269
K     30350   2867059

现在我想绘制一个条形图,x 轴上的年龄作为标签。对于每个 x-tick,应该有两根柱线,一根柱线表示数量,一根柱线表示价格。我可以通过简单地使用它来完成这项工作:

df.plot(kind='bar')

问题在于缩放。价格高得多,以至于我无法真正确定该图中的金额,请参阅:

因此,我想要第二个 y 轴。我试过了:

df.loc[:,'amount'].plot(kind='bar')
df.loc[:,'price'].plot(kind='bar',secondary_y=True)

但这只是覆盖了条形,并没有将它们并排放置。 有什么方法可以做到这一点而不必访问较低级别的 matplotlib(显然可以通过手动并排放置条形来实现)?

目前,我在子图中使用了两个单图:

df.plot(kind='bar',grid=True,subplots=True,sharex=True); 

导致:

【问题讨论】:

【参考方案1】:

使用新的 pandas 版本(0.14.0 或更高版本),以下代码将起作用。为了创建两个轴,我手动创建了两个 matplotlib 轴对象(axax2),它们将用于两个条形图。

绘制数据框时,您可以使用ax=... 选择坐标区对象。另外,为了防止两个图重叠,我修改了它们与position 关键字参数对齐的位置,默认为0.5,但这意味着两个条形图重叠。

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO

s = StringIO("""     amount     price
A     40929   4066443
B     93904   9611272
C    188349  19360005
D    248438  24335536
E    205622  18888604
F    140173  12580900
G     76243   6751731
H     36859   3418329
I     29304   2758928
J     39768   3201269
K     30350   2867059""")

df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True)

fig = plt.figure() # Create matplotlib figure

ax = fig.add_subplot(111) # Create matplotlib axes
ax2 = ax.twinx() # Create another axes that shares the same x-axis as ax.

width = 0.4

df.amount.plot(kind='bar', color='red', ax=ax, width=width, position=1)
df.price.plot(kind='bar', color='blue', ax=ax2, width=width, position=0)

ax.set_ylabel('Amount')
ax2.set_ylabel('Price')

plt.show()

【讨论】:

不错,不知道ax-参数。谢谢 这太棒了!但是......如果我将其中一个值更改为负数,那么结果就会中断。知道如何解决吗? 这很棒。但是图例只显示蓝色而不是两者。 嗨!我已经尝试过你的建议,它确实有效。我面临的问题是x-axis 数据根本没有显示......但是它确实显示了如果我只使用一个ax 但我不能同时使用两个轴。有什么提示吗? 嗨。 111 参数在fig.add_subplot() 中是什么意思?【参考方案2】:

这是另一种方法:

在左轴上创建所有条形 通过更改 transform 属性将一些条形移到右轴

代码如下:

import pylab as pl
df = pd.DataFrame(np.random.rand(10, 2), columns=["left", "right"])
df["left"] *= 100

ax = df.plot(kind="bar")
ax2 = ax.twinx()
for r in ax.patches[len(df):]:
    r.set_transform(ax2.transData)
ax2.set_ylim(0, 2);

这是输出:

【讨论】:

也不错,感谢有关 ax.patches 的提示 :-) 如果你想缩放left的值,你应该使用ax.patches[:len(df)]。只是在说' :)。真棒简洁的答案!【参考方案3】:

你只需要写:df.plot(kind= 'bar', secondary_y= 'amount')

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO
s = StringIO("""     amount     price
A     40929   4066443
B     93904   9611272
C    188349  19360005
D    248438  24335536
E    205622  18888604
F    140173  12580900
G     76243   6751731
H     36859   3418329
I     29304   2758928
J     39768   3201269
K     30350   2867059""")
df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True)

_ = df.plot( kind= 'bar' , secondary_y= 'amount' , rot= 0 )
plt.show()

【讨论】:

非常漂亮。你知道这是什么时候添加到熊猫绘图 API 中的吗?可能对其他人有帮助:) secondary_y 的语义有点出乎意料。如果要在左侧绘制 A、B,在右侧绘制 C,则必须说 df.plot(y=['A', 'B', 'C'], secondary_y=['C']) 而不是 df.plot(y=['A', 'B'], secondary_y=['C'])。当然,如果df只有这3列,你可以不指定y【参考方案4】:

正如 InLaw 所说,您应该使用 secondary_y = 'amount'

在这里添加他的答案是如何为两个轴设置 ylabels

df.plot.bar(figsize=(15,5), secondary_y= 'amount')

ax1, ax2 = plt.gcf().get_axes() # gets the current figure and then the axes

ax1.set_ylabel('price')

ax2.set_ylabel('amount')

【讨论】:

以上是关于Pandas:带有两个条形图和两个 y 轴的条形图的主要内容,如果未能解决你的问题,请参考以下文章

将带有次 y 轴的 pandas 条形图的图例放在条形前面

如何在具有不同 Y 轴的同一个 seaborn 图中很好地制作条形图和线图?

对饼图和条形图 Pandas 使用子图 [重复]

对饼图和条形图 Pandas 使用子图 [重复]

我有 2 个不同的条形图,它们有一个共同的 X 轴和 2 个不同的 Y 轴。我想使用 python 将这两个使用 X 轴的图合并为一个

Plotly Python:在具有多个 Y 轴的分组条形图中对齐 X 轴