1年間のサンプルデータ:
_import pandas as pd
import numpy.random as rnd
import seaborn as sns
n = 365
df = pd.DataFrame(data = {"A":rnd.randn(n), "B":rnd.randn(n)+1},
index=pd.date_range(start="2017-01-01", periods=n, freq="D"))
_
これらのデータを月ごとにグループ化して箱ひげ図にしたい(つまり、月に2つのボックス、1つはA
用、もう1つはB
用)。
単一の列の場合、sns.boxplot(df.index.month, df["A"])
は正常に機能します。ただし、sns.boxplot(df.index.month, df[["A", "B"]])
はエラーをスローします(_ValueError: cannot copy sequence with size 2 to array axis with dimension 365
_)。 seabornのhue
プロパティを回避策として使用するためにインデックス(pd.melt(df, id_vars=df.index, value_vars=["A", "B"], var_name="column")
)でデータを溶かすことも機能しません(_TypeError: unhashable type: 'DatetimeIndex'
_)。
(プレーンなmatplotlibを使用する方が簡単な場合、ソリューションは必ずしもseabornを使用する必要はありません。)
基本的に私が欲しいものを生み出す回避策を見つけました。ただし、DataFrameにプロットしたいよりも多くの変数が含まれていると、操作がやや厄介になります。したがって、よりエレガントで直接的な方法がある場合は、共有してください。
_df_stacked = df.stack().reset_index()
df_stacked.columns = ["date", "vars", "vals"]
df_stacked.index = df_stacked["date"]
sns.boxplot(x=df_stacked.index.month, y="vals", hue="vars", data=df_stacked)
_
pandas融解と海生)を使用した解決策は次のとおりです。
import pandas as pd
import numpy.random as rnd
import seaborn as sns
n = 365
df = pd.DataFrame(data = {"A": rnd.randn(n),
"B": rnd.randn(n)+1,
"C": rnd.randn(n) + 10, # will not be plotted
},
index=pd.date_range(start="2017-01-01", periods=n, freq="D"))
df['month'] = df.index.month
df_plot = df.melt(id_vars='month', value_vars=["A", "B"])
sns.boxplot(x='month', y='value', hue='variable', data=df_plot)
_month_dfs = []
for group in df.groupby(df.index.month):
month_dfs.append(group[1])
plt.figure(figsize=(30,5))
for i,month_df in enumerate(month_dfs):
axi = plt.subplot(1, len(month_dfs), i + 1)
month_df.plot(kind='box', subplots=False, ax = axi)
plt.title(i+1)
plt.ylim([-4, 4])
plt.show()
_
this を与えます
探しているものとは異なりますが、変数を追加すると、読み取り可能なDataFrameを維持できます。
を使用して軸を簡単に削除することもできます
_if i > 0:
y_axis = axi.axes.get_yaxis()
y_axis.set_visible(False)
_
plt.show()
の前のループ内
Altair を使用すると、これは非常に簡単です。
alt.Chart(
df.reset_index().melt(id_vars = ["index"], value_vars=["A", "B"]).assign(month = lambda x: x["index"].dt.month)
).mark_boxplot(
extent='min-max'
).encode(
alt.X('variable:N', title=''),
alt.Y('value:Q'),
column='month:N',
color='variable:N'
)
上記のコードは、DataFrameを溶かし、month
列を追加します。次に、Altairは、プロット列として月ごとに分類された各変数の箱ひげ図を作成します。
私はあなたの質問を完全には理解していませんが、matplotlib
を使用してこのアプローチを検討することをお勧めします。しかし、最善の解決策ではありません。
1)df
をmonth
sで12個のデータフレームに分割し、すべてリストに積み上げます
DFList = []
for group in df_3.groupby(df_3.index.month):
DFList.append(group[1])
2)ループでそれらを次々にプロットします。
for _ in range(12):
DFList[_].plot(kind='box', subplots=True, layout=(2,2), sharex=True, sharey=True, figsize=(7,7))
plt.show()
3)最初の3行のスナップショットは次のとおりです。
matplotlib
の-add_subplot
メソッド もチェックアウトすることをお勧めします