Anotar puntos de datos al trazar desde Pandas DataFrame

Me gustaría anotar los puntos de datos con sus valores al lado de los puntos en la ttwig. Los ejemplos que encontré solo tratan con xey como vectores. Sin embargo, me gustaría hacer esto para un DataFrame de pandas que contiene múltiples columnas.

ax = plt.figure().add_subplot(1, 1, 1) df.plot(ax = ax) plt.show() 

¿Cuál es la mejor manera de anotar todos los puntos para un DataFrame de varias columnas?

¿Desea utilizar una de las otras columnas como el texto de la anotación? Esto es algo que hice recientemente.

Comenzando con algunos datos de ejemplo

 In [1]: df Out[1]: xy val 0 -1.015235 0.840049 a 1 -0.427016 0.880745 b 2 0.744470 -0.401485 c 3 1.334952 -0.708141 d 4 0.127634 -1.335107 e 

Traza los puntos. Tramo y contra x, en este ejemplo.

 In [2]: ax = df.set_index('x')['y'].plot(style='o') 

Escriba una función que pase por encima de x, y, y el valor para anotar al lado del punto.

 In [3]: def label_point(x, y, val, ax): a = pd.concat({'x': x, 'y': y, 'val': val}, axis=1) for i, point in a.iterrows(): ax.text(point['x'], point['y'], str(point['val'])) In [4]: label_point(df.x, df.y, df.val, ax) In [5]: draw() 

Puntos anotados

Aquí hay una versión (muy) ligera de la respuesta de Dan Allan :

 import matplotlib.pyplot as plt import pandas as pd import numpy as np import string df = pd.DataFrame({'x':np.random.rand(10), 'y':np.random.rand(10)}, index=list(string.ascii_lowercase[:10])) 

Lo que da:

  xy a 0.541974 0.042185 b 0.036188 0.775425 c 0.950099 0.888305 d 0.739367 0.638368 e 0.739910 0.596037 f 0.974529 0.111819 g 0.640637 0.161805 h 0.554600 0.172221 i 0.718941 0.192932 j 0.447242 0.172469 

Y entonces:

 fig, ax = plt.subplots() df.plot('x', 'y', kind='scatter', ax=ax) for k, v in df.iterrows(): ax.annotate(k, v) 

Finalmente, si estás en modo interactivo, es posible que necesites actualizar la ttwig:

 fig.canvas.draw() 

Que produce: Boring scatter plot

O, dado que se ve increíblemente feo, puedes embellecer las cosas con bastante facilidad:

 from matplotlib import cm cmap = cm.get_cmap('Spectral') df.plot('x', 'y', kind='scatter', ax=ax, s=120, linewidth=0, c=range(len(df)), colormap=cmap) for k, v in df.iterrows(): ax.annotate(k, v, xytext=(10,-5), textcoords='offset points', family='sans-serif', fontsize=18, color='darkslategrey') 

Que se ve mucho mejor: Bonito diagrama de dispersión

Supongamos que su df tiene varias columnas, y tres de las cuales son x , y y lbl . Para anotar su diagtwig de dispersión (x,y) con lbl , simplemente:

 ax = df.plot(kind='scatter',x='x',y='y') df[['x','y','lbl']].apply(lambda x: ax.text(*x),axis=1); 

Las respuestas anteriores me parecieron bastante útiles, especialmente el ejemplo de LondonRob que mejoró un poco el diseño.

Lo único que me molestó es que no me gusta sacar datos de DataFrames para luego recorrerlos. Parece un desperdicio del DataFrame.

Aquí hay una alternativa que evita el ciclo usando .apply (), e incluye las anotaciones de aspecto más agradable (pensé que la escala de colores era un poco exagerada y no conseguía que la barra de colores desapareciera):

 ax = df.plot('x', 'y', kind='scatter', s=50 ) def annotate_df(row): ax.annotate(row.name, row.values, xytext=(10,-5), textcoords='offset points', size=18, color='darkslategrey') _ = df.apply(annotate_df, axis=1) 

enter image description here

Editar notas

Edité mi ejemplo de código recientemente. Originalmente usaba lo mismo:

 fig, ax = plt.subplots() 

como las otras publicaciones para exponer los ejes, sin embargo esto es innecesario y hace que:

 import matplotlib.pyplot as plt 

línea también innecesaria.

También tenga en cuenta:

  • Si está intentando reproducir este ejemplo y sus gráficos no tienen los puntos en el mismo lugar que cualquiera de los nuestros, puede ser porque el DataFrame estaba usando valores aleatorios. Probablemente hubiera sido menos confuso si hubiéramos usado una tabla de datos fija o una semilla aleatoria.
  • Dependiendo de los puntos, puede que tenga que jugar con los valores xytext para obtener mejores ubicaciones.