La librería joypy toma como entrada un data frame de pandas con varias variables numéricas y también una variable categórica opcional que representa grupos, como en el data frame de muestra del siguiente bloque de código.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
joyplot
Por defecto, si pasas un data frame de pandas como entrada, la función joyplot
creará un ridgeline plot de las variables numéricas. Esto es, mostrará gráficos de densidad apilados para cada una de las variables numéricas del data frame.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df)
# plt.show()
Ridgeline plot por grupo
Sin embargo, puede que quieras crear un joy plot de una única variable pero dividido por grupo. En este escenario habrá tantas densidades como grupos que representarán la distribución de la variable para cada uno de ellos. Para ello tendrás que especificar el nombre de la variable categórica con by
y el nombre de la variable numérica (o variables) con column
.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1")
# plt.show()
Ridgeline plot para cada variable y grupo
La última alternativa es crear un ridgeline plot que muestra la densidad para cada variable y grupo, de forma que cada grupo tendrá tantas densidades como variables numéricas. Puedes hacerlo especificando todas las variables numéricas que quieras con column
(e.g. column = ["var1", "var2"]
) o simplemento utilizando by
para que se tengan en cuenta todas las variables numéricas, como en el ejemplo siguiente.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo")
# plt.show()
Título del gráfico
La función joyplot
también proporciona otros argumentos para personalizar la apariencia visual de los gráficos. Por ejemplo, con title
puedes agregar un título a la figura.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, title = "Título del joy plot")
# plt.show()
Joy plot con leyenda
Si quieres agregar una leyenda al gráfico para identificar las diferentes variables puedes especificar legend = True
de modo que se agregará una leyenda automática.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", legend = True)
# plt.show()
Joy plot con histogramas
Los gráficos ridgeline también pueden mostrar histogramas en lugar de estimaciones de densidad. Tendrás que establecer hist = True
y especificar el número de intervalos de clase que quieras con bins
, que por defecto es 10.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1",
hist = True, bins = 50)
# plt.show()
Agregar un grid
El argumento grid
es por defecto False
y se puede utilizar para agregar un grid vertical al gráfico cuando se establece como True
. Esta característica es interesante para comparar la distribución de los diferentes grupos.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1", grid = True)
# plt.show()
Tipo de densidad
El argumento kind
se puede utilizar para elegir el tipo de densidad que se quiere dibujar. Las posibles opciones son "kde"
(por defecto), "counts"
, "normalized_counts"
y "values"
.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1",
kind = "counts")
# plt.show()
joypy también proporciona varias formas de personalizar la apariencia visual de los gráficos. Si quieres cambiar el color azul por defecto de las densidades puedes especificar un nuevo color con color
.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1", color = "darkseagreen")
# plt.show()
Color diferente para cada grupo
Ten en cuenta que también puedes pasar un array de colores como entrada al argumento color
con tantos colores como grupos (o variables) para que cada densidad tenga un color diferente.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
colores = ["#FDAE61", "#FEE08B", "#FFFFBF", "#E6F598", "#ABDDA4"]
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1", color = colores)
# plt.show()
Usando una paleta de colores
Una alternativa a lo anterior es utilizar alguna paleta de colores predefinida de matplotlib con colormap
. Recuerda que tendrás que importar cm
de matplotlib con from matplotlib import cm
.
import matplotlib.pyplot as plt
from matplotlib import cm
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1", colormap = cm.Pastel1)
# plt.show()
Transparencia del color
En ocasiones las densidades solapan unas sobre otras. Si esto sucede puedes establecer fade = True
de modo que cada densidad será más opaca que la anterior (desde la superior a la inferior), permitiendo una mejor visualización de las densidades.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1", fade = True)
# plt.show()
Color de las líneas
Las líneas de las densidades son negras por defecto, pero con linecolor
puedes elegir el color que prefieras. En el siguiente ejemplo las coloreamos de blanco.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1", linecolor = "white")
# plt.show()
Eliminar el color de fondo
Ten en cuenta que también puedes eliminar el área de las densidades y tan solo dejar la línea con fill = False
.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, by = "grupo", column = "var1", fill = False)
# plt.show()
Color de fondo
Por último, también puedes personalizar el color de fondo del gráfico con el argumento background
, que por defecto es None
.
import matplotlib.pyplot as plt
from matplotlib import cm
import pandas as pd
import numpy as np; np.random.seed(2)
import random; random.seed(2)
import joypy
# Data frame de muestra
df = pd.DataFrame({'var1': np.random.normal(70, 100, 500),
'var2': np.random.normal(250, 100, 500),
'grupo': random.choices(["G1", "G2", "G3", "G4", "G5"], k = 500)})
fig, ax = joypy.joyplot(df, background = "lavender")
# plt.show()
También te puede interesar