web-dev-qa-db-ja.com

パンダ:2つのバーと2つのy軸を持つ棒グラフ

次のような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には2つのバーがあります。1つは金額用、もう1つは価格用です。私はこれを簡単に使用して機能させることができます:

df.plot(kind='bar')

問題はスケーリングです。価格が非常に高いため、そのグラフで金額を実際に特定することはできません。

enter image description here

したがって、2番目のy軸が必要です。私はそれを使って試しました:

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

しかし、これは単にバーを上書きし、それらを並べて配置しません。下位レベルのmatplotlibにアクセスせずにこれを行う方法はありますか(手動でバーを並べて配置することで明らかに可能になります)。

今のところ、サブプロット内で2つの単一のプロットを使用しています。

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

その結果:

enter image description here

26
tim

新しいpandasリリース(0.14.0以降)を使用すると、以下のコードが機能します。2軸を作成するには、2つのmatplotlib軸オブジェクト(axおよびax2)両方の棒グラフに使用されます。

Dataframeをプロットするとき、ax=...を使用してAxesオブジェクトを選択できます。また、2つのプロットが重ならないようにするために、positionキーワード引数と位置合わせする場所を変更しました。これはデフォルトで0.5になりますが、それは2つの棒プロットが重なることを意味します.

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

Plot

58
Ffisegydd

書くだけです: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()

Secondary_Y_axis

34
InLaw

他の方法は次のとおりです。

  • 左軸にすべてのバーを作成します
  • 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);

出力は次のとおりです。

enter image description here

7
HYRY