Matplotlib розкидає сюжет з різним текстом у кожній точці даних


252

Я намагаюся зробити графік розкидання і анотувати точки даних із різними числами зі списку. Так, наприклад, я хочу побудувати графік yvs xта анотувати відповідні числа від n.

y = [2.56422, 3.77284, 3.52623, 3.51468, 3.02199]
z = [0.15, 0.3, 0.45, 0.6, 0.75]
n = [58, 651, 393, 203, 123]
ax = fig.add_subplot(111)
ax1.scatter(z, y, fmt='o')

Будь-які ідеї?


Ви також можете отримати графік розкидання з мітками підказки на наведення курсора за допомогою бібліотеки mpld3. mpld3.github.io/examples/scatter_tooltip.html
Клод COULOMBE

Відповіді:


466

Мені невідомий жоден метод побудови графіку, який бере масиви чи списки, але ви можете використовувати annotate()під час ітерації над значеннями в n.

y = [2.56422, 3.77284, 3.52623, 3.51468, 3.02199]
z = [0.15, 0.3, 0.45, 0.6, 0.75]
n = [58, 651, 393, 203, 123]

fig, ax = plt.subplots()
ax.scatter(z, y)

for i, txt in enumerate(n):
    ax.annotate(txt, (z[i], y[i]))

Існує маса варіантів форматування annotate(), дивіться на веб-сайті matplotlib:

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


1
Також добре працює над Seaborn regplots, не надто сильно порушуючи.
ійосеф

@Rutger Я використовую датрамфрейд панди і я якось отримую KeyError- так що я думаю, що dict()об’єкт очікується? Чи є інший спосіб маркувати дані , використовуючи enumerate, annotateі кадр панди даних?
Рейчел

@Rachel, Ви можете використовувати for row in df.iterrows():, а потім отримати доступ до значень і row['text'], row['x-coord']т. Д. Якщо ви опублікуєте окреме питання, я перегляну його.
Rutger Kassies

@RutgerKassies Спасибі, Рутгер! Я розмістив тут питання stackoverflow.com/questions/41481153/… Я боюся, що це може бути подібне до цього самого питання. Але я не можу це якось розробити. Дякую за твою допомогу!
Рейчел

1
@aviator, на жаль, не вбудований. Але дивись, наприклад , макет двигуна це з допомогою NetworkX в: stackoverflow.com/a/34697108/1755432
Рутгер Kassies

32

У версії, раніше, ніж matplotlib 2.0, ax.scatterне потрібно розміщувати текст без маркерів. У версії 2.0 вам потрібно ax.scatterбуде встановити належний діапазон та маркери для тексту.

y = [2.56422, 3.77284, 3.52623, 3.51468, 3.02199]
z = [0.15, 0.3, 0.45, 0.6, 0.75]
n = [58, 651, 393, 203, 123]

fig, ax = plt.subplots()

for i, txt in enumerate(n):
    ax.annotate(txt, (z[i], y[i]))

І за цим посиланням ви можете знайти приклад в 3d.


Це круто! Дякуємо, що поділилися цим рішенням. Чи можете ви також поділитися тим, що належний код, щоб встановити розмір фігури? Такі програми, plt.figure(figsize=(20,10))які не працюють, як очікувалося, оскільки виклик цього коду насправді не змінює розмір зображення. Чекаємо вашої допомоги. Дякую!
Левін

fig, ax = plt.subplots (figsize = (20,10))
rafaelvalle

21

Якщо хтось намагається застосувати вищезазначені рішення до .scatter () замість .subplot (),

Я спробував запустити наступний код

y = [2.56422, 3.77284, 3.52623, 3.51468, 3.02199]
z = [0.15, 0.3, 0.45, 0.6, 0.75]
n = [58, 651, 393, 203, 123]

fig, ax = plt.scatter(z, y)

for i, txt in enumerate(n):
    ax.annotate(txt, (z[i], y[i]))

Але зіткнулися з помилками, що вказують на "не можна розпакувати неітерабельний об'єкт PathCollection", при цьому помилка конкретно вказує на кодову лінію fig, ax = plt.scatter (z, y)

Я врешті-решт вирішив помилку за допомогою наступного коду

plt.scatter(z, y)

for i, txt in enumerate(n):
    plt.annotate(txt, (z[i], y[i]))

Я не очікував, що буде різниця між .scatter () та .subplot (), я мав би знати краще.


11

Ви також можете використовувати pyplot.text(див. Тут ).

def plot_embeddings(M_reduced, word2Ind, words):
""" Plot in a scatterplot the embeddings of the words specified in the list "words".
    Include a label next to each point.
"""
for word in words:
    x, y = M_reduced[word2Ind[word]]
    plt.scatter(x, y, marker='x', color='red')
    plt.text(x+.03, y+.03, word, fontsize=9)
plt.show()

M_reduced_plot_test = np.array([[1, 1], [-1, -1], [1, -1], [-1, 1], [0, 0]])
word2Ind_plot_test = {'test1': 0, 'test2': 1, 'test3': 2, 'test4': 3, 'test5': 4}
words = ['test1', 'test2', 'test3', 'test4', 'test5']
plot_embeddings(M_reduced_plot_test, word2Ind_plot_test, words)

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


7

Python 3.6+:

coordinates = [('a',1,2), ('b',3,4), ('c',5,6)]
for x in coordinates: plt.annotate(x[0], (x[1], x[2]))

2

Як один вкладиш, що використовує розуміння списку та нумерованість:

[ax.annotate(x[0], (x[1], x[2])) for x in np.array([n,z,y]).T]

налаштування - це відповідь на відповідь Рутгера.


1

Я хотів би додати, що для коментування міток ви навіть можете використовувати стрілки / текстові поля. Ось що я маю на увазі:

import random
import matplotlib.pyplot as plt


y = [2.56422, 3.77284, 3.52623, 3.51468, 3.02199]
z = [0.15, 0.3, 0.45, 0.6, 0.75]
n = [58, 651, 393, 203, 123]

fig, ax = plt.subplots()
ax.scatter(z, y)

ax.annotate(n[0], (z[0], y[0]), xytext=(z[0]+0.05, y[0]+0.3), 
    arrowprops=dict(facecolor='red', shrink=0.05))

ax.annotate(n[1], (z[1], y[1]), xytext=(z[1]-0.05, y[1]-0.3), 
    arrowprops = dict(  arrowstyle="->",
                        connectionstyle="angle3,angleA=0,angleB=-90"))

ax.annotate(n[2], (z[2], y[2]), xytext=(z[2]-0.05, y[2]-0.3), 
    arrowprops = dict(arrowstyle="wedge,tail_width=0.5", alpha=0.1))

ax.annotate(n[3], (z[3], y[3]), xytext=(z[3]+0.05, y[3]-0.2), 
    arrowprops = dict(arrowstyle="fancy"))

ax.annotate(n[4], (z[4], y[4]), xytext=(z[4]-0.1, y[4]-0.2),
    bbox=dict(boxstyle="round", alpha=0.1), 
    arrowprops = dict(arrowstyle="simple"))

plt.show()

Який генерує такий графік: введіть тут опис зображення

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