はじめに
信頼区間付きの棒グラフはよく見かけます。複数グループの差が優位かどうかという議論に向いているからです。
他のツールだと割と簡単に描けるグラフだったりするのですが、Pythonでやろうとするとmatplotlibは勝手に信頼区間を計算してくれません。信頼区間を計算してからエラーバーを出して……といったノウハウが紹介されていますが、正直面倒くさいです。
そこでseabornを使います。こちらは何もしなくても信頼区間を出してくれるタイプのライブラリです。ただし、使い勝手には癖があります。
リファレンス通りに使ってみる
凝ったことをする意味はあまりないので、まずはリファレンス通りに使います。
seaborn.barplot — seaborn 0.9.0 documentation
リファレンスの記述を多少補ったのが以下のコードです。tipsデータセットでやっているようです。
import seaborn as sns import matplotlib.pyplot as plt tips = sns.load_dataset("tips") print(tips.head()) """ => total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4 """ sns.barplot(x="day", y="total_bill", data=tips) plt.savefig("result.png")
折れ線グラフのときと使い方はほとんど変わりません。というか、見え方が違うだけのようにも見えます(折れ線の方だとx軸の位置は指定できますが)。
【python】seabornで折れ線グラフを信頼区間付きで描く - 静かなる名辞
なお、エラーバーの形式はいじれます。普通は傘がほしいと思うので、capsizeを指定します。また、デフォルトでは少しエラーバーが濃すぎる気がするので、errwidthで調整するとよさげです。
適当に調整したのが下のものです。
sns.barplot(x="day", y="total_bill", data=tips, capsize=0.1, errwidth=1.2)
もともとDataFrameになっていない任意のデータで行う
例によって例のごとく、seabornの開発方針はpandasべったりなので、どんな形式・内容のデータであっても一回DataFrameに突っ込んでからやった方が良さそうです。ただ、受け付けてくれる形式が少し特殊なので、変換方法を覚えておいた方が得です。
普通のデータはこんな感じで定義したいことが多いと思います。棒ごとに配列があるイメージですね。
df = pd.DataFrame({"A": [11, 12, 11, 10, 10, 13, 11, 10, 15, 11, 10], "B": [20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20]})
meltを使って縦持ちに変換すると、seabornと親和性の高いフォーマットになります。結論から言うと、こう書くと良いでしょう。
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt df = pd.DataFrame({"A": [11, 12, 11, 10, 10, 13, 11, 10, 15, 11, 10], "B": [20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20]}) sns.barplot(x="class", y="data", data=df.melt(var_name="class", value_name="data"), capsize=0.1, errwidth=1.2) plt.savefig("result.png")
これでちゃんとABごとに集計してくれます。ちなみにmeltした結果はこうなります。
class data 0 A 11 1 A 12 2 A 11 3 A 10 4 A 10 5 A 13 6 A 11 7 A 10 8 A 15 9 A 11 10 A 10 11 B 20 12 B 21 13 B 20 14 B 21 15 B 20 16 B 21 17 B 20 18 B 21 19 B 20 20 B 21 21 B 20
まとめ
データを縦持ちに変換するところでひと手間余計にかかりますが、matplotlibでゼロからやるよりは楽だし、間違いも少なさそうなので良いと思います。