Позначте точки даних Python на графіку


80

Я шукав віки (години, подібні до віків), щоб знайти відповідь на справді надокучливу (здавалося б, базову) проблему, і оскільки я не можу знайти питання, яке цілком відповідає відповіді, я публікую запитання і відповідаю на нього в надії, що воно заощадить комусь іншому величезну кількість часу, який я щойно витратив на свої навички заговору нубі.

Якщо ви хочете позначити точки сюжету за допомогою 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()

Я знаю, що xytext = (30,0) поєднується з текстовими зв’язками, ви використовуєте ці значення 30,0 для позиціонування точки мітки даних, отже, на осі 0 y та 30 на осі x на своїй маленькій області.

Вам потрібні обидві лінії, що наносять i та j, інакше ви наносите лише мітку даних x або y.

Ви отримуєте щось подібне (зверніть увагу лише на ярлики):
Мій власний графік із позначеними точками даних

Це не ідеально, все ще є певне перекриття - але це краще, ніж ніщо, що я мав ..


1
Чому б просто не зробити ax.annotate('(%s, %s)' % (i, j), ...)? (Або якщо ви використовуєте новіше форматування рядків,. '({}, {})'.format(i, j))
Джо Кінгтон,

1
залишаючи це тут matplotlib.org/users/annotations.html
Ешлі

pyplot.text, здається, є альтернативою коментуванню: pythonmembers.club/2018/05/08/… Не впевнений, що він робить щось інше, хоча
10762409 говорить Reinstate Monica

Супроводжувач pythonmembers.club тут. XD це те, що поставило мене на думку як новачка. Ця стаття стала настільки популярною, щоб бути включеною в курс НЛП Стенфордського університету (япке сміливе пряме посилання на статтю)
Абдур-Рахман Янхангер

Відповіді:


95

Як щодо друку (x, y)відразу.

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

введіть тут опис зображення


4
Просто примітка для тих, хто використовує це: textcoords = 'offset points', здається, має змінний ефект залежно від масштабу графіку (для мене це призвело до того, що більшість міток з'явилися поза графіком)
Ерік Г

1
Так, замість цього слід використовувати textcoords = 'data'.
navari

@navari, Дякую за інформацію. Відповідно оновив відповідь.
falsetru

@EricG - Я вважаю, що для цього textcoords='offset points'також потрібен xytextпараметр. Іншими словами, встановіть xytext=(x points, y points)компенсацію і textcoords='offset points'буде працювати так, як ви очікуєте.
DaveL17,

2
Скажімо, у вас є мільйон тривимірних точок даних, вам потрібно вибрати пару з них і позначити їх окремо. Як би ви це зробили?
Червень Ван,

5

У мене була подібна проблема, і я закінчив з цим:

введіть тут опис зображення

Для мене це має ту перевагу, що дані та анотації не перекриваються.

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

Використання текстового аргументу в .annotateкінцевому результаті з несприятливими позиціями тексту. Проведення ліній між легендою та точками даних є безладним, оскільки місцезнаходження легенди важко вирішити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.