次のカウントプロットを考えると、棒の上にパーセンテージを配置するにはどうすればよいですか?
import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
ax = sns.countplot(x="class", hue="who", data=titanic)
たとえば、「最初」の場合、それぞれのバーの上に合計男性1人/合計1人、合計女性1人/合計1人、子供1人/合計1人の合計が必要です。
説明が明確でない場合はお知らせください。
ありがとう!
sns.barplot
は、バープロット値を明示的に返しませんmatplotlib.pyplot.bar
は最後のパラグラフを参照してください。ただし、他に何もプロットしていない場合、軸のpatches
がすべて自分の値であると想定してリスクがあります。次に、barplot関数が計算した小計を使用できます。
from matplotlib.pyplot import show
import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
total = float(len(titanic)) # one person per row
#ax = sns.barplot(x="class", hue="who", data=titanic)
ax = sns.countplot(x="class", hue="who", data=titanic) # for Seaborn version 0.7 and more
for p in ax.patches:
height = p.get_height()
ax.text(p.get_x()+p.get_width()/2.,
height + 3,
'{:1.2f}'.format(height/total),
ha="center")
show()
生産する
別のアプローチは、明示的に小計を行うことです。優れたpandas
を使用して、matplotlib
を使用してプロットし、自分でスタイルを設定します。 (ただし、sns
プロット関数を使用している場合でも、matplotlib
コンテキストから非常に多くのスタイルを取得できます。試してみてください-)
cphlewis's ソリューションの助けを借りて、チャートの上に正しいパーセンテージを配置することができたので、クラスの合計は1つになります。
for index, category in enumerate(categorical):
plt.subplot(plot_count, 1, index + 1)
order = sorted(data[category].unique())
ax = sns.countplot(category, data=data, hue="churn", order=order)
ax.set_ylabel('')
bars = ax.patches
half = int(len(bars)/2)
left_bars = bars[:half]
right_bars = bars[half:]
for left, right in Zip(left_bars, right_bars):
height_l = left.get_height()
height_r = right.get_height()
total = height_l + height_r
ax.text(left.get_x() + left.get_width()/2., height_l + 40, '{0:.0%}'.format(height_l/total), ha="center")
ax.text(right.get_x() + right.get_width()/2., height_r + 40, '{0:.0%}'.format(height_r/total), ha="center")
ただし、ソリューションでは、3つのオプション(男性、女性、子供)ではなく、2つのオプション(男性、女性)があると想定しています。
Axes.patches
が奇妙な順序で並んでいます(最初にすべての青いバー、次にすべての緑のバー、次にすべての赤いバー)。それらを分割し、それに従って一緒にジップする必要があります。