python numpy matplotlib scipy

plot python 3



matplotlib: ¿cómo anotar un punto en una flecha de dispersión colocada automáticamente? (2)

Básicamente, no, no hay.

Los motores de diseño que manejan la colocación de etiquetas de mapas similares a esto son sorprendentemente complejos y están fuera del alcance de matplotlib. (Las intersecciones del cuadro delimitador son en realidad una forma bastante mala de decidir dónde colocar las etiquetas. ¿Cuál es el punto al escribir una tonelada de código para algo que solo funcionará en un caso de 1000?)

Aparte de eso, debido a la cantidad de texto complejo que representa matplotlib (p. Ej., Látex), es imposible determinar la extensión del texto sin procesarlo por completo (lo que es bastante lento).

Sin embargo, en muchos casos, encontrará que usar una caja transparente detrás de la etiqueta colocada con anotar es una solución adecuada.

P.ej

import numpy as np import matplotlib.pyplot as plt np.random.seed(1) x, y = np.random.random((2,500)) fig, ax = plt.subplots() ax.plot(x, y, ''bo'') # The key option here is `bbox`. I''m just going a bit crazy with it. ax.annotate(''Something'', xy=(x[0], y[0]), xytext=(-20,20), textcoords=''offset points'', ha=''center'', va=''bottom'', bbox=dict(boxstyle=''round,pad=0.2'', fc=''yellow'', alpha=0.3), arrowprops=dict(arrowstyle=''->'', connectionstyle=''arc3,rad=0.5'', color=''red'')) plt.show()

Si hago un diagrama de dispersión con matplotlib:

plt.scatter(randn(100),randn(100)) # set x, y lims plt.xlim([...]) plt.ylim([...])

Me gustaría anotar un punto dado (x, y) con una flecha apuntando hacia él y una etiqueta. Sé que esto se puede hacer con annotate , pero me gustaría que la flecha y su etiqueta se coloquen "de manera óptima" de tal manera que, si es posible (dadas las escalas / límites del eje actual), la flecha y la etiqueta no Se superponen con los otros puntos. por ejemplo, si desea etiquetar un punto atípico. ¿Hay alguna forma de hacer esto? no tiene que ser perfecto, sino simplemente una colocación inteligente de la flecha / etiqueta, dadas solo las coordenadas (x,y) del punto a etiquetar. Gracias.


Use adjustText (revelación completa, lo escribí).

Vamos a etiquetar los primeros 10 puntos. El único parámetro que cambié fue reducir la fuerza de repulsión de los puntos, ya que hay muchos de ellos y queremos que el algoritmo tome un poco más de tiempo y coloque las anotaciones con más cuidado.

import numpy as np import matplotlib.pyplot as plt from adjustText import adjust_text np.random.seed(1) x, y = np.random.random((2,500)) fig, ax = plt.subplots() ax.plot(x, y, ''bo'') ts = [] for i in range(10): ts.append(plt.text(x[i], y[i], ''Something''+str(i))) adjust_text(ts, x=x, y=y, force_points=0.1, arrowprops=dict(arrowstyle=''->'', color=''red'')) plt.show()

No es lo ideal, pero los puntos son realmente densos aquí y, a veces, no hay forma de colocar el texto cerca de su objetivo sin que se superpongan. Pero todo es automático y fácil de usar, y tampoco permite que las etiquetas se superpongan entre sí.

PS Utiliza intersecciones de cuadro delimitador, pero más bien con éxito, diría!