matplotlib - examples - Agrupar diagramas de caja en el mar cuando la entrada es un DataFrame
seaborn time series (3)
Tengo la intención de trazar múltiples columnas en un pandas dataframe
, todas agrupadas por otra columna usando groupby
dentro de seaborn.boxplot
. Hay una buena respuesta aquí, para un problema similar en matplotlib
matplotlib: agrupar matplotlib
caja pero dado el hecho de que seaborn.boxplot
viene con la opción groupby
, pensé que podría ser mucho más fácil hacerlo en seaborn
.
Aquí vamos con un ejemplo reproducible que falla:
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)
Lo que obtengo es algo que ignora completamente la opción groupby
:
Mientras que si hago esto con una columna, funciona gracias a otra pregunta de SO Sea groupby por pandas Series :
sns.boxplot(df.a1, groupby=df.b)
Así que me gustaría tener todas mis columnas en una parcela (todas las columnas vienen en una escala similar).
EDITAR:
La pregunta SO anterior se editó y ahora incluye una respuesta "no limpia" a este problema, pero sería bueno si alguien tuviera una mejor idea para este problema.
Como señalan las otras respuestas, la función boxplot
se limita a trazar una sola "capa" de boxplots, y el parámetro groupby
solo tiene efecto cuando la entrada es una serie y usted tiene una segunda variable que desea usar para agrupar las observaciones en cada caja..
Sin embargo, puede lograr lo que creo que está esperando con la función factorplot
, utilizando kind="box"
. Pero primero tendrá que "fundir" el marco de datos de muestra en lo que se denomina formato de formato largo o "ordenado", donde cada columna es una variable y cada fila es una observación:
df_long = pd.melt(df, "b", var_name="a", value_name="c")
Entonces es muy simple trazar:
sns.factorplot("a", hue="b", y="c", data=df_long, kind="box")
La función groupby de Seaborn toma Series no DataFrames, por eso no funciona.
Como solución, puedes hacer esto:
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])
da :
Tenga en cuenta que df.filter(regex="a")
es equivalente 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
Espero que esto ayude
Realmente no es mejor que la respuesta que vinculó, pero creo que la forma de lograrlo en el transporte marítimo es mediante la función FacetGrid
, ya que el parámetro groupby solo se define para Series pasadas a la función boxplot.
Aquí hay algo de código: pd.melt
es necesario porque (lo mejor que puedo decir) el mapeo de facetas solo puede tomar columnas individuales como parámetros, por lo que los datos deben convertirse en un formato ''largo''.
g = sns.FacetGrid(pd.melt(df, id_vars=''b''), col=''b'')
g.map(sns.boxplot, ''value'', ''variable'')