pandas: traza todos los puntos del diccionario en un diagrama de dispersión en Python

CorePress2024-01-25  8

Tengo un diccionario que tiene grupos y cada grupo contiene etiquetas diferentes

Dictonary look like this
demo_dict = {0: [b'3.0',b'3.0', b'3.0', b'5.0',b'5.0',b'5.0', b'6.0', b'6.0'],
 1: [b'2.0', b'2.0', b'3.0', b'7.0',b'7.0'],
 2: [b'1.0', b'4.0', b'8.0', b'7.0',b'7.0']}

Para dibujar un diagrama requerido, estoy usando el siguiente código

comp = demo_dict
df = pd.DataFrame.from_dict(comp, orient='index')
df.index.rename('Clusters', inplace=True)

stacked = df.stack().reset_index()
stacked.rename(columns={'level_1': 'Lable', 0: 'Labels'}, inplace=True)

sns.scatterplot(data=stacked, x='Clusters', y='Labels')
plt.show()

Pero la cuestión es que el código anterior no dibuja todos los puntos, solo menciona qué grupos contienen qué etiquetas, pero quiero tener todos los puntos de cada grupo en el objeto visual.

Es que falta algo en este código para generar todos los puntos. Nota: También probé con stripplot y swarmplot

Podrías probar los enfoques de Cómo hacer jitterplot en matplolib python para agregar fluctuación a los puntos después de que sns.scatterplot los haya dibujado. Todo depende de cuántos puntos se juntan y qué es exactamente lo que quieres mostrar. Puede que sea necesario utilizar un tamaño de punto más pequeño o aplicar algo de alfa.

- JohanC

28 de marzo de 2021 a las 10:52



------------------------------------

Con groupby puedes agrupar usando dos columnas. Los recuentos se pueden mostrar mediante un mapa de calor:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

demo_dict = {}
for i in range(40):
    demo_dict[i] = np.random.choice([b'1.0', b'2.0', b'3.0', b'4.0', b'5.0', b'6.0', b'7.0', b'8.0'],
                                    np.random.randint(10, 30))
df = pd.DataFrame.from_dict(demo_dict, orient='index')
df.index.rename('Clusters', inplace=True)

stacked = df.stack().reset_index()
stacked.rename(columns={'level_1': 'Lable', 0: 'Labels'}, inplace=True)

grouped = stacked.groupby(['Labels', 'Clusters']).agg('count').unstack()

fig = plt.figure(figsize=(15, 4))
ax = sns.heatmap(data=grouped, annot=True, cmap='rocket_r', cbar_kws={'pad': 0.01})
ax.set_xlabel('')
ax.tick_params(axis='y', labelrotation=0)
plt.tight_layout()
plt.show()

Una alternativa es mostrar los recuentos como tamaños en un diagrama de dispersión

grouped = stacked.groupby(['Labels', 'Clusters']).agg('count').reset_index()
fig = plt.figure(figsize=(15, 4))
ax = sns.scatterplot(data=grouped, x='Clusters', y='Labels', size='Lable', color='orchid')
for h in ax.legend_.legendHandles:
    h.set_color('orchid')  # the default color in the sizes legends is black
ax.margins(x=0.01) # less whitespace
# set the legend outside
ax.legend(handles=ax.legend_.legendHandles, title='Counts:', bbox_to_anchor=(1.01, 1.02), loc='upper left')

También puedes probar el enfoquede Cómo hacer un diagrama de jitter en matplolib python, opcionalmente usando diferentes compensaciones de jitter en las direcciones xey. Con tus datos podría quedar de la siguiente manera:

def jitter_dots(dots):
    offsets = dots.get_offsets()
    jittered_offsets = offsets
    jittered_offsets[:, 0] += np.random.uniform(-0.3, 0.3, offsets.shape[0]) # x
    jittered_offsets[:, 1] += np.random.uniform(-0.3, 0.3, offsets.shape[0]) # y
    dots.set_offsets(jittered_offsets)

ax = sns.scatterplot(data=stacked, x='Clusters', y='Labels')
jitter_dots(ax.collections[0])

Así es como podría verse con 8 colores diferentes, alternándose por grupo:

ax = sns.scatterplot(data=stacked, x='Clusters', y='Labels',
                     hue=stacked['Clusters'] % 8, palette='Dark2', legend=False)
jitter_dots(ax.collections[0])
ax.margins(x=0.02)
sns.despine()

4

Agradezco tu respuesta. Con respecto a su primera respuesta, no estoy buscando un histograma. Y con respecto al segundo, no tengo que mostrar los recuentos explícitamente. Necesito dibujar un diagrama de dispersión simple que simplemente describa cada grupo conpuntos equivalen al número de etiquetas de cantidad que tiene.

- RobinHood013

28/03/2021 a las 14:05

Parece estar funcionando como quiero. ¿Podrías decirme también cómo podemos cambiar el color de los puntos para cada grupo?

- RobinHood013

28/03/2021 a las 15:34

Sí, tengose agregó "hue='Clústeres' " y ahora me da exactamente lo que quiero. gracias hombre

- RobinHood013

28/03/2021 a las 15:41

1

Buen truco al final con los tonos del módulo.

-tdy

28/03/2021 a las 18:10



------------------------------------

Si entendí correctamente, puedes usar un diagrama de enjambre (o elargumento similar):

sns.swarmplot(data=stacked, x='Clusters', y='Labels')

1

aquí he publicado el dictado de demostración. Pero en realidad tengo un diccionario donde cada grupo contiene al menos 40 etiquetas. Ya intenté usar swarmplot o stripplot allí. Pero aún así no mostró todos los puntos

- RobinHood013

28 de marzo de 2021 a las 6:16

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare