pandas dataframe
に複数の列をプロットし、seaborn.boxplot
内でgroupby
を使用してすべてを別の列でグループ化します。 matplotlib
matplotlib:Group boxplots の同様の問題についてはいい答えがありますが、seaborn.boxplot
にはgroupby
オプションが付いているという事実がありますseaborn
でこれを行う方がはるかに簡単です。
失敗する再現可能な例を次に示します。
import seaborn as sns
import pandas as pd
df = pd.DataFrame(
[
[2, 4, 5, 6, 1],
[4, 5, 6, 7, 2],
[5, 4, 5, 5, 1],
[10, 4, 7, 8, 2],
[9, 3, 4, 6, 2],
[3, 3, 4, 4, 1]
], columns=['a1', 'a2', 'a3', 'a4', 'b'])
#Plotting by seaborn
sns.boxplot(df[['a1','a2', 'a3', 'a4']], groupby=df.b)
私が得るものは、groupby
オプションを完全に無視するものです:
一方、1つの列でこれを行うと、別のSO質問 Seaborn groupby pandas Series のおかげで機能します。
sns.boxplot(df.a1, groupby=df.b)
したがって、1つのプロットですべての列を取得したいと思います(すべての列は同様のスケールになります)。
編集:
上記のSOの質問は編集され、この問題に対する「クリーンではない」回答が含まれていますが、誰かがこの問題についてより良いアイデアを持っているといいでしょう。
他の回答のメモにあるように、boxplot
関数はボックスプロットの単一の「レイヤー」のプロットに制限され、groupby
パラメーターは入力がシリーズで2番目の場合にのみ効果があります。観測値を各ボックスにバインドするために使用する変数。
ただし、kind="box"
を使用して、factorplot
関数を使用して、期待していることを実現できます。ただし、最初にサンプルデータフレームを「長い形式」または「整頓された」形式と呼ばれる形式に「溶かす」必要があります。ここで、各列は変数であり、各行は観測値です。
df_long = pd.melt(df, "b", var_name="a", value_name="c")
次に、プロットするのは非常に簡単です。
sns.factorplot("a", hue="b", y="c", data=df_long, kind="box")
Seabornのgroupby関数はDataFrameではなくSeriesを使用するため、機能しません。
回避策として、これを行うことができます:
_fig, ax = plt.subplots(1,2, sharey=True)
for i, grp in enumerate(df.filter(regex="a").groupby(by=df.b)):
sns.boxplot(grp[1], ax=ax[i])
_
それは与えます :
df.filter(regex="a")
は_df[['a1','a2', 'a3', 'a4']]
_と同等であることに注意してください
_ a1 a2 a3 a4
0 2 4 5 6
1 4 5 6 7
2 5 4 5 5
3 10 4 7 8
4 9 3 4 6
5 3 3 4 4
_
お役に立てれば
実際にリンクした答えよりも優れているわけではありませんが、seabornでこれを達成する方法は FacetGrid
機能を使用することだと思います。 boxplot関数に渡されます。
ここにいくつかのコードがあります-pd.melt
が必要なのは、(私が知る限り)ファセットマッピングが個々の列のみをパラメーターとして受け取ることができるため、データを「長い」形式に変換する必要があるためです。
g = sns.FacetGrid(pd.melt(df, id_vars='b'), col='b')
g.map(sns.boxplot, 'value', 'variable')