it-swarm.com.de

Label python Datenpunkte im Plot

Ich habe nach Ewigkeiten gesucht, um die Antwort auf ein wirklich ärgerliches (scheinbar grundlegendes) Problem zu finden. Da ich keine Frage finde, die genau zu der Antwort passt, stelle ich eine Frage und beantworte sie in der Hoffnung, dass dies der Fall ist spart jemand anderem die enorme Zeit, die ich gerade für meine Fähigkeiten zum Zeichnen von Noobies aufgewendet habe.

Wenn Sie Ihre Diagrammpunkte mit python matplotlib beschriften möchten

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()

Ich weiß, dass xytext = (30,0) zusammen mit den Textkoorden verwendet wird. Sie verwenden diese 30,0-Werte, um den Datenbeschriftungspunkt so zu positionieren, dass er auf der 0-y-Achse und auf der x-Achse auf seiner eigenen kleinen Fläche liegt.

Sie benötigen sowohl die Linien, die i als auch j zeichnen, ansonsten zeichnen Sie nur die x- oder y-Datenbeschriftung.

Du bekommst so etwas raus (beachte nur die Labels):
My own plot with data points labeled

Es ist nicht ideal, es gibt immer noch einige Überlappungen - aber es ist besser als nichts, was ich hatte.

66
ashley

Wie wäre es mit Drucken (x, y) auf einmal.

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

Ich hatte ein ähnliches Problem und kam zu folgendem Ergebnis:

enter image description here

Für mich hat dies den Vorteil, dass sich Daten und Anmerkungen nicht überlappen.

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()

Verwenden des Textarguments in .annotate endete mit ungünstigen Textpositionen. Das Zeichnen von Linien zwischen einer Legende und den Datenpunkten ist ein Chaos, da die Position der Legende schwer zu bestimmen ist.

0
Markus Dutschke