Python Pandas:带有两个条形和两个 y 轴的条形图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24183101/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pandas: Bar-Plot with two bars and two y-axis
提问by tim
I have a DataFrame looking like this:
我有一个如下所示的 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
Now I'd like to plot a bar-plot with the age on the x-axis as labels. For each x-tick there should be two bars, one bar for the amount, and one for the price. I can get this working by using simply:
现在我想用 x 轴上的年龄作为标签绘制条形图。对于每个 x-tick,应该有两根柱线,一根柱线表示数量,一根柱线表示价格。我可以通过简单地使用来完成这项工作:
df.plot(kind='bar')
The problem is the scaling. The prices are so much higher that I can not really identify the amount in that graph, see:
问题是缩放。价格高得多,我无法真正确定该图中的金额,请参阅:
Thus I'd like a second y-axis. I tried it using:
因此我想要第二个 y 轴。我尝试使用:
df.loc[:,'amount'].plot(kind='bar')
df.loc[:,'price'].plot(kind='bar',secondary_y=True)
but this just overwrites the bars and does NOT place them side-by-side. Is there any way to do this without having to access the lower-level matplotlib (which would be possible obviously by placing the bars side by side manually)?
但这只会覆盖条形而不是并排放置它们。有没有办法做到这一点而不必访问较低级别的 matplotlib(这显然可以通过手动并排放置条形图来实现)?
For now, I'm using two single plots within subplots:
现在,我在子图中使用两个单图:
df.plot(kind='bar',grid=True,subplots=True,sharex=True);
resulting in:
导致:
采纳答案by Ffisegydd
Using the new pandas release (0.14.0 or later) the below code will work. To create the two axis I have manually created two matplotlib axes objects (ax
and ax2
) which will serve for both bar plots.
使用新的 pandas 版本(0.14.0 或更高版本),以下代码将起作用。为了创建两个轴,我手动创建了两个 matplotlib 轴对象(ax
和ax2
),它们将用于两个条形图。
When plotting a Dataframe you can choose the axes object using ax=...
. Also in order to prevent the two plots from overlapping I have modified where they align with the position
keyword argument, this defaults to 0.5
but that would mean the two bar plots overlapping.
绘制数据框时,您可以使用 选择轴对象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()
回答by HYRY
Here is an other method:
这是另一种方法:
- create all the bars in left axes
- move some bars to the right axes by change it's
transform
attribute
- 在左轴上创建所有条形
- 通过更改它的
transform
属性将一些条移动到正确的轴
Here is the code:
这是代码:
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);
here is the output:
这是输出:
回答by InLaw
You just need to write: df.plot( kind= 'bar', secondary_y= 'amount')
你只需要写: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()
回答by Thomas G.
As mentioned by InLaw you should use secondary_y = 'amount'
正如 InLaw 提到的,你应该使用 secondary_y = 'amount'
To add to his answer here is how to set the ylabelsfor the two axis:
在这里添加他的答案是如何设置两个轴的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')