web-dev-qa-db-fra.com

Label python points de données sur le tracé

J'ai cherché des âges (des heures qui ressemblent à des âges) pour trouver la réponse à un problème vraiment gênant (apparemment fondamental), et comme je ne trouve pas de question qui corresponde parfaitement à la réponse, je poste une question et y réponds dans l'espoir qu'elle permettra à quelqu'un d'autre d'économiser l'énorme quantité de temps que je viens de consacrer à mes compétences en matière de traçage de noobie.

Si vous souhaitez étiqueter vos points de tracé en utilisant python matplotlib

from matplotlib import pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

A = anyarray
B = anyotherarray

plt.plot(A,B)
for i,j in Zip(A,B):
    ax.annotate('%s)' %j, xy=(i,j), xytext=(30,0), textcoords='offset points')
    ax.annotate('(%s,' %i, xy=(i,j))

plt.grid()
plt.show()

Je sais que xytext = (30,0) va de pair avec les liens de texte. Vous utilisez ces 30,0 valeurs pour positionner le point de l’étiquette de données.

Vous avez besoin des deux lignes traçant i et j, sinon vous ne tracez que les étiquettes de données x ou y.

Vous obtenez quelque chose comme ceci (notez les étiquettes seulement):
My own plot with data points labeled

Ce n’est pas idéal, il y a encore quelques chevauchements - mais c’est mieux que rien, c’est ce que j’avais.

66
ashley

Qu'en est-il de print (x, y) immediatement.

from matplotlib import pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

A = -0.75, -0.25, 0, 0.25, 0.5, 0.75, 1.0
B = 0.73, 0.97, 1.0, 0.97, 0.88, 0.73, 0.54

plt.plot(A,B)
for xy in Zip(A, B):                                       # <--
    ax.annotate('(%s, %s)' % xy, xy=xy, textcoords='data') # <--

plt.grid()
plt.show()

enter image description here

83
falsetru

J'ai eu un problème similaire et fini avec ceci:

enter image description here

Pour moi, cela présente l’avantage que les données et les annotations ne se chevauchent pas.

from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)

A = -0.75, -0.25, 0, 0.25, 0.5, 0.75, 1.0
B = 0.73, 0.97, 1.0, 0.97, 0.88, 0.73, 0.54

plt.plot(A,B)

# annotations at the side (ordered by B values)
x0,x1=ax.get_xlim()
y0,y1=ax.get_ylim()
for ii, ind in enumerate(np.argsort(B)):
    x = A[ind]
    y = B[ind]
    xPos = x1 + .02 * (x1 - x0)
    yPos = y0 + ii * (y1 - y0)/(len(B) - 1)
    ax.annotate('',#label,
          xy=(x, y), xycoords='data',
          xytext=(xPos, yPos), textcoords='data',
          arrowprops=dict(
                          connectionstyle="arc3,rad=0.",
                          shrinkA=0, shrinkB=10,
                          arrowstyle= '-|>', ls= '-', linewidth=2
                          ),
          va='bottom', ha='left', zorder=19
          )
    ax.text(xPos + .01 * (x1 - x0), yPos,
            '({:.2f}, {:.2f})'.format(x,y),
            transform=ax.transData, va='center')

plt.grid()
plt.show()

Utiliser l'argument textuel dans .annotate s'est retrouvé avec des positions de texte défavorables. Tracer des lignes entre une légende et les points de données est un désordre, car il est difficile de localiser la légende.

0
Markus Dutschke