usar tablas recorrer para notebook matrices librerias leer hacer graficos graficas graficar funciones datos data como python matplotlib plot dataframe pandas

tablas - hacer parcelas de dispersión matplotlib a partir de marcos de datos en pandas de Python



python graficos 2d (2)

¿Cuál es la mejor manera de hacer una serie de diagramas de dispersión usando matplotlib desde un matplotlib de matplotlib de pandas en Python?

Por ejemplo, si tengo un marco de datos df que tiene algunas columnas de interés, normalmente me encuentro convirtiendo todo en matrices:

import matplotlib.pylab as plt # df is a DataFrame: fetch col1 and col2 # and drop na rows if any of the columns are NA mydata = df[["col1", "col2"]].dropna(how="any") # Now plot with matplotlib vals = mydata.values plt.scatter(vals[:, 0], vals[:, 1])

El problema con la conversión de todo a la matriz antes de trazar es que te obliga a salir de los marcos de datos.

Considere estos dos casos de uso donde tener el marco de datos completo es esencial para el trazado:

  1. Por ejemplo, ¿qué pasaría si ahora quisiera ver todos los valores de col3 para los valores correspondientes que trazó en la llamada para scatter y colorear cada punto (o tamaño) en ese valor? Tendría que retroceder, extraer los valores no col1,col2 de col1,col2 y comprobar cuáles son sus valores correspondientes.

    ¿Hay alguna manera de trazar preservando el marco de datos? Por ejemplo:

    mydata = df.dropna(how="any", subset=["col1", "col2"]) # plot a scatter of col1 by col2, with sizes according to col3 scatter(mydata(["col1", "col2"]), s=mydata["col3"])

  2. Del mismo modo, imagine que desea filtrar o colorear cada punto de forma diferente según los valores de algunas de sus columnas. Por ejemplo, ¿qué pasaría si quisieras trazar automáticamente las etiquetas de los puntos que cumplen un determinado límite en col1, col2 junto a ellas (donde las etiquetas están almacenadas en otra columna de df) o colorear estos puntos de forma diferente, como hacen las personas con marcos de datos en R. Por ejemplo:

    mydata = df.dropna(how="any", subset=["col1", "col2"]) myscatter = scatter(mydata[["col1", "col2"]], s=1) # Plot in red, with smaller size, all the points that # have a col2 value greater than 0.5 myscatter.replot(mydata["col2"] > 0.5, color="red", s=0.5)

¿Cómo puede hacerse esto?

EDITAR Responder a crewbum:

Usted dice que la mejor manera es trazar cada condición (como subset_a , subset_b ) por separado. ¿Qué sucede si tiene muchas condiciones, por ejemplo, desea dividir las dispersiones en 4 tipos de puntos o incluso más, trazando cada uno en diferentes formas / colores. ¿Cómo se puede aplicar elegantemente la condición a, b, c, etc. y asegurarse de trazar "el resto" (cosas que no están en ninguna de estas condiciones) como el último paso?

De manera similar, en su ejemplo, donde traza col1,col2 diferente en función de col3 , ¿qué col1,col2 si hay valores de NA que rompen la asociación entre col1,col2,col3 ? Por ejemplo, si desea trazar todos los valores de col2 función de sus valores de col3 , algunas filas tienen un valor NA en col1 o col3 , lo que le obliga a utilizar dropna primero. Entonces lo harías:

mydata = df.dropna(how="any", subset=["col1", "col2", "col3")

luego puedes trazar utilizando mydata como lo muestras, trazando la dispersión entre col1,col2 usando los valores de col3 . Pero a mydata le col1,col2 algunos puntos que tienen valores para col1,col2 pero son NA para col3 , y los que aún tienen que trazarse ... entonces ¿cómo se col1,col2 básicamente "el resto" de los datos, es decir, los puntos que no son en el conjunto filtrado mydata ?


Hay poco que agregar a la gran respuesta de Garrett, pero los pandas también tienen un método de scatter . Usando eso, es tan fácil como

df = pd.DataFrame(np.random.randn(10,2), columns=[''col1'',''col2'']) df[''col3''] = np.arange(len(df))**2 * 100 + 100 df.plot.scatter(''col1'', ''col2'', df[''col3''])


Intente pasar columnas del DataFrame directamente a matplotlib, como en los ejemplos a continuación, en lugar de extraerlos como matrices numpy.

df = pd.DataFrame(np.random.randn(10,2), columns=[''col1'',''col2'']) df[''col3''] = np.arange(len(df))**2 * 100 + 100 In [5]: df Out[5]: col1 col2 col3 0 -1.000075 -0.759910 100 1 0.510382 0.972615 200 2 1.872067 -0.731010 500 3 0.131612 1.075142 1000 4 1.497820 0.237024 1700

Variar el tamaño del punto de dispersión según otra columna

plt.scatter(df.col1, df.col2, s=df.col3) # OR (with pandas 0.13 and up) df.plot(kind=''scatter'', x=''col1'', y=''col2'', s=df.col3)

Variar el color del punto de dispersión según otra columna

colors = np.where(df.col3 > 300, ''r'', ''k'') plt.scatter(df.col1, df.col2, s=120, c=colors) # OR (with pandas 0.13 and up) df.plot(kind=''scatter'', x=''col1'', y=''col2'', s=120, c=colors)

Diagrama de dispersión con leyenda

Sin embargo, la forma más fácil que he encontrado para crear un diagrama de dispersión con leyenda es llamar a plt.scatter una vez para cada tipo de punto.

cond = df.col3 > 300 subset_a = df[cond].dropna() subset_b = df[~cond].dropna() plt.scatter(subset_a.col1, subset_a.col2, s=120, c=''b'', label=''col3 > 300'') plt.scatter(subset_b.col1, subset_b.col2, s=60, c=''r'', label=''col3 <= 300'') plt.legend()

Actualizar

Por lo que puedo decir, matplotlib simplemente saltea puntos con coordenadas NA x / y o configuraciones de estilo NA (por ejemplo, color / tamaño). Para encontrar puntos omitidos debido a NA, pruebe el método isnull : df[df.col3.isnull()]

Para dividir una lista de puntos en muchos tipos, eche un vistazo a numpy select , que es una implementación vectorizada if-then-else y acepta un valor predeterminado opcional. Por ejemplo:

df[''subset''] = np.select([df.col3 < 150, df.col3 < 400, df.col3 < 600], [0, 1, 2], -1) for color, label in zip(''bgrm'', [0, 1, 2, -1]): subset = df[df.subset == label] plt.scatter(subset.col1, subset.col2, s=120, c=color, label=str(label)) plt.legend()