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

时间:2021-07-16 23:46:49

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线应该有两个小节,一个小节表示数量,一个小节表示价格。我可以通过简单地:

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:

问题是规模。价格要高得多,我无法确定这张图的金额,看:

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

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(显然可以通过手工并排放置bar来实现)?

For now, I'm using two single plots within subplots:

目前,我在次要情节中使用了两个单独的情节:

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

resulting in:

导致:

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

3 个解决方案

#1


37  

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.

使用新的熊猫版本(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.

当策划Dataframe你可以选择坐标轴对象使用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()

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

#2


7  

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:

这是输出:

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

#3


4  

You just need to write: df.plot( kind= 'bar', secondary_y= 'amount')

你只需要写:df。绘图(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()

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

#1


37  

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.

使用新的熊猫版本(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.

当策划Dataframe你可以选择坐标轴对象使用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()

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

#2


7  

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:

这是输出:

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

#3


4  

You just need to write: df.plot( kind= 'bar', secondary_y= 'amount')

你只需要写:df。绘图(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()

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