Plot sebar Matplotlib dengan teks berbeda di setiap titik data

252

Saya mencoba membuat plot pencar dan membubuhi keterangan titik data dengan nomor yang berbeda dari daftar. Jadi, misalnya, saya ingin merencanakan yvs xdan membubuhi keterangan dengan nomor yang sesuai dari 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')

Ada ide?

Labibah
sumber
Anda juga bisa mendapatkan sebar plot dengan label tooltip di hover menggunakan perpustakaan mpld3. mpld3.github.io/examples/scatter_tooltip.html
Claude COULOMBE

Jawaban:

466

Saya tidak mengetahui adanya metode plotting yang mengambil array atau daftar tetapi Anda bisa menggunakannya annotate()saat iterasi nilai-nilai di 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]))

Ada banyak opsi pemformatan untuk annotate(), lihat situs web matplotlib:

masukkan deskripsi gambar di sini

Kassi Rutger
sumber
1
Bekerja dengan baik di atas Seaborn regplot's tanpa terlalu banyak gangguan juga.
ijoseph
@ Rutger saya menggunakan datframe panda dan saya entah bagaimana mendapatkan KeyError- jadi saya kira sebuah dict()objek diharapkan? Apakah ada cara lain untuk memberi label data menggunakan enumerate, annotatedan bingkai data panda?
Rachel
@ Rachel, Anda dapat menggunakan for row in df.iterrows():, dan kemudian mengakses nilai dengan row['text'], row['x-coord']dll. Jika Anda memposting pertanyaan terpisah saya akan melihatnya.
Rutger Kassies
@RutgerKassies Terima kasih, Rutger! Saya memposting pertanyaan di sini stackoverflow.com/questions/41481153/... Saya khawatir hal itu mungkin mirip dengan pertanyaan ini. Tapi saya tidak bisa menyelesaikannya. Terima kasih untuk bantuannya!
Rachel
1
@aviator, sayangnya tidak built-in. Tapi lihat misalnya ini menggunakan mesin layout networkx: stackoverflow.com/a/34697108/1755432
Rutger Kassies
32

Dalam versi yang lebih awal dari matplotlib 2.0, ax.scattertidak perlu merencanakan teks tanpa spidol. Di versi 2.0 Anda harus ax.scattermengatur rentang dan penanda yang tepat untuk teks.

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

Dan di tautan ini Anda dapat menemukan contoh dalam 3d.

rafaelvalle
sumber
Ini luar biasa! Terima kasih telah berbagi solusi ini. Bisakah Anda juga membagikan kode yang tepat untuk mengatur ukuran gambar? Implementasi seperti plt.figure(figsize=(20,10))tidak berfungsi seperti yang diharapkan, dalam hal menerapkan kode ini sebenarnya tidak mengubah ukuran gambar. Kami menantikan bantuan Anda. Terima kasih!
Levine
ara, kapak = plt.subplots (figsize = (20,10))
rafaelvalle
21

Jika ada orang yang mencoba menerapkan solusi di atas untuk. Hamburkan () daripada .subplot (),

Saya mencoba menjalankan kode berikut

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

Tetapi mengalami kesalahan yang menyatakan "tidak dapat membongkar objek PathCollection yang tidak dapat diubah", dengan kesalahan secara khusus menunjuk pada codeline fig, ax = plt.scatter (z, y)

Saya akhirnya memecahkan kesalahan menggunakan kode berikut

plt.scatter(z, y)

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

Saya tidak berharap akan ada perbedaan antara .scatter () dan .subplot () saya seharusnya tahu lebih baik.

Heather Claxton
sumber
11

Anda juga dapat menggunakan pyplot.text(lihat di sini ).

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)

masukkan deskripsi gambar di sini

irudyak
sumber
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]))
palash
sumber
2

Sebagai satu liner menggunakan pemahaman daftar dan numpy:

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

pengaturan dikirim ke jawaban Rutger.

andor kesselman
sumber
1

Saya ingin menambahkan bahwa Anda bahkan dapat menggunakan panah / kotak teks untuk membubuhi keterangan label. Inilah yang saya maksud:

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

Yang akan menghasilkan grafik berikut: masukkan deskripsi gambar di sini

Anwarvic
sumber