Python 熊猫:带有两个条形和两个y轴的条形图

Python 熊猫:带有两个条形和两个y轴的条形图,python,matplotlib,plot,pandas,Python,Matplotlib,Plot,Pandas,我有一个如下所示的数据框: 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

我有一个如下所示的数据框:

     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记号应有两条横线,一条表示金额,一条表示价格。我可以通过简单地使用以下工具来实现这一点:

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); 
导致:


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

打印数据帧时,可以使用
ax=…
选择轴对象。另外,为了防止两个图重叠,我修改了它们与
位置
关键字参数对齐的位置,默认值为
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()

还有一种方法:

  • 创建左轴上的所有条
  • 通过更改某些条的
    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);
以下是输出:

您只需编写:df.plot(种类='bar',次项='amount'


如InLaw所述,您应该使用
次要值=“金额”

下面是如何为两个轴设置ylabel,以补充他的答案:

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')

啊,很好,不知道
ax
-参数。这太棒了!但是如果我将其中一个值更改为负值,则结果将中断。知道怎么修吗?太好了。但是传奇只出现在蓝色上,而不是两者都出现。嗨!我试过你的建议,它确实管用。我面临的问题是,
x轴
数据根本不显示。。。但是,如果我只使用一个
ax
,它会显示,但是我不能同时使用两个轴。有什么提示吗?嗨。
111
参数在
fig.add_subplot()
中的含义是什么?很好的一个,感谢关于ax.patches:-)的提示,如果您想缩放
左侧的
值,应该使用
ax.patches[:len(df)]
。只是说:)。真棒且简洁的回答!非常漂亮。你知道这是什么时候添加到API的吗?可能对其他人有帮助:)次要的语义有点出乎意料。如果你想在左边画A,B,在右边画C,你必须说
df.plot(y=['A','B','C'],secondary_y=['C'])
而不是
df.plot(y=['A','B'],secondary_y=['C'])
。当然,如果
df
只有这3列,您可以将
y
保留为未指定。
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')