Cómo crear un diagrama de dispersión por categoría [duplicado]

Resuelto user2989613 asked hace 10 años • 8 respuestas

Estoy tratando de hacer un diagrama de dispersión simple en pyplot usando un objeto Pandas DataFrame, pero quiero una forma eficiente de trazar dos variables pero tener los símbolos dictados por una tercera columna (clave). Probé varias formas de usar df.groupby, pero no tuve éxito. A continuación se muestra un script df de muestra. Esto colorea los marcadores según la 'clave1', pero me gustaría ver una leyenda con las categorías 'clave1'. ¿Estoy cerca? Gracias.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(np.random.normal(10,1,30).reshape(10,3), index = pd.date_range('2010-01-01', freq = 'M', periods = 10), columns = ('one', 'two', 'three'))
df['key1'] = (4,4,4,6,6,6,8,8,8,8)
fig1 = plt.figure(1)
ax1 = fig1.add_subplot(111)
ax1.scatter(df['one'], df['two'], marker = 'o', c = df['key1'], alpha = 0.8)
plt.show()
user2989613 avatar Feb 09 '14 09:02 user2989613
Aceptado

Puedes usarlo scatterpara esto, pero eso requiere tener valores numéricos para tu key1y no tendrás una leyenda, como habrás notado.

Es mejor usarlo solo plotpara categorías discretas como esta. Por ejemplo:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
np.random.seed(1974)

# Generate Data
num = 20
x, y = np.random.random((2, num))
labels = np.random.choice(['a', 'b', 'c'], num)
df = pd.DataFrame(dict(x=x, y=y, label=labels))

groups = df.groupby('label')

# Plot
fig, ax = plt.subplots()
ax.margins(0.05) # Optional, just adds 5% padding to the autoscaling
for name, group in groups:
    ax.plot(group.x, group.y, marker='o', linestyle='', ms=12, label=name)
ax.legend()

plt.show()

ingrese la descripción de la imagen aquí

Si desea que las cosas se vean como el pandasestilo predeterminado, simplemente actualice rcParamscon la hoja de estilo de pandas y use su generador de colores. (También estoy modificando ligeramente la leyenda):

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
np.random.seed(1974)

# Generate Data
num = 20
x, y = np.random.random((2, num))
labels = np.random.choice(['a', 'b', 'c'], num)
df = pd.DataFrame(dict(x=x, y=y, label=labels))

groups = df.groupby('label')

# Plot
plt.rcParams.update(pd.tools.plotting.mpl_stylesheet)
colors = pd.tools.plotting._get_standard_colors(len(groups), color_type='random')

fig, ax = plt.subplots()
ax.set_color_cycle(colors)
ax.margins(0.05)
for name, group in groups:
    ax.plot(group.x, group.y, marker='o', linestyle='', ms=12, label=name)
ax.legend(numpoints=1, loc='upper left')

plt.show()

ingrese la descripción de la imagen aquí

Joe Kington avatar Feb 09 '2014 04:02 Joe Kington

Esto es sencillo de hacer con Seaborn ( pip install seaborn) como una línea

sns.scatterplot(x_vars="one", y_vars="two", data=df, hue="key1") :

import seaborn as sns
import pandas as pd
import numpy as np
np.random.seed(1974)

df = pd.DataFrame(
    np.random.normal(10, 1, 30).reshape(10, 3),
    index=pd.date_range('2010-01-01', freq='M', periods=10),
    columns=('one', 'two', 'three'))
df['key1'] = (4, 4, 4, 6, 6, 6, 8, 8, 8, 8)

sns.scatterplot(x="one", y="two", data=df, hue="key1")

ingrese la descripción de la imagen aquí

Aquí está el marco de datos como referencia:

ingrese la descripción de la imagen aquí

Dado que tiene tres columnas variables en sus datos, es posible que desee trazar todas las dimensiones por pares con:

sns.pairplot(vars=["one","two","three"], data=df, hue="key1")

ingrese la descripción de la imagen aquí

https://rasbt.github.io/mlxtend/user_guide/plotting/category_scatter/ es otra opción.

Bob Baxley avatar Aug 31 '2016 13:08 Bob Baxley