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?


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


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.


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.


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


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

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.


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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.