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
Claude COULOMBE '19

Answers:


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 regplot的顶部也可以很好地工作,也不会造成太大干扰。
ijoseph '16

@Rutger我使用了一个熊猫datframe,我以某种方式得到了KeyError-所以我猜应该有一个dict()对象?是否有任何其他的方式来标记使用的数据enumerateannotate和大熊猫数据帧?
雷切尔

@Rachel,您可以使用for row in df.iterrows():,然后使用row['text'], row['x-coord']etc 访问值。如果您发布单独的问题,我将进行介绍。
罗格·卡西斯

@RutgerKassies谢谢,罗格!我在这里stackoverflow.com/questions/41481153/…发表了一个问题。 我担心这可能与这个问题相似。但是我无法解决。谢谢您的帮助!
雷切尔

1
@aviator,不幸的是不是内置的。但是例如,可以使用networkx的布局引擎查看此信息:stackoverflow.com/a/34697108/1755432
Rutger 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))未如预期那样工作,因为调用此代码实际上不会更改图像的大小。期待您的协助。谢谢!
莱文

无花果,ax = plt.subplots(figsize =(20,10))
拉斐尔瓦莱

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对象”,该错误专门指向代码行无花果,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

作为一个使用列表理解和numpy的班轮:

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

设置与Rutger的答案相同。


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

将生成以下图形: 在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.