matplotlib散点图,每个数据点都有不同的文本

Lab*_*bah 202 python text annotate matplotlib scatter-plot

我正在尝试制作散点图并使用列表中的不同数字注释数据点.所以例如我想绘制y vs 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')
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Rut*_*ies 385

我不知道任何采用数组或列表的绘图方法,但您可以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]))
Run Code Online (Sandbox Code Playgroud)

有很多格式化选项annotate(),请参阅matplotlib网站:

在此输入图像描述

  • 在 Seaborn `regplot`s 之上也能很好地工作而不会造成太多干扰。 (2认同)
  • 对于恰好非常接近的点,是否有任何方法可以偏移注释并绘制从数据点指向标签的线,以便很好地分离否则重叠的标签? (2认同)
  • @aviator,不幸的是不是内置的。但请参阅使用networkx的布局引擎的示例:/sf/answers/2428797591/ (2认同)

raf*_*lle 29

在早于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]))
Run Code Online (Sandbox Code Playgroud)

在此链接中,您可以在3d中找到一个示例.

  • 这太棒了!感谢您分享这个解决方案。您还可以分享设置图形大小的正确代码吗?诸如“plt.figure(figsize=(20,10))”之类的实现无法按预期工作,因为调用此代码实际上不会更改图像的大小。期待您的帮助。谢谢! (2认同)

Hea*_*ton 14

如果有人试图将上述解决方案应用于.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]))
Run Code Online (Sandbox Code Playgroud)

但是遇到错误,指出“无法解压不可迭代的PathCollection对象”,该错误专门指向代码行无花果,ax = plt.scatter(z,y)

我最终使用以下代码解决了该错误

plt.scatter(z, y)

for i, txt in enumerate(n):
    plt.annotate(txt, (z[i], y[i]))
Run Code Online (Sandbox Code Playgroud)

我没想到我应该更清楚地知道.scatter()和.subplot()之间没有区别。

  • 这是因为“plt.scatter”并不像“plt.subplots()”那样创建“Figure”和“Axes”,而是创建一个包含散点的“PathCollection”。您应该事先创建图形和轴。 (3认同)

pal*_*ash 9

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]))
Run Code Online (Sandbox Code Playgroud)

  • 在这一点上,为什么不做 `copies = [('a',(1,2)), ('b',(3,4)), ('c',(5,6))]` 和 ` plt.注释(*x)`? (7认同)

big*_*nty 9

对于有限的一组值,matplotlib 很好。但是当您有很多值时,工具提示开始与其他数据点重叠。但是由于空间有限,您不能忽略这些值。因此最好缩小或放大。

使用情节

import plotly.express as px
df = px.data.tips()

df = px.data.gapminder().query("year==2007 and continent=='Americas'")


fig = px.scatter(df, x="gdpPercap", y="lifeExp", text="country", log_x=True, size_max=100, color="lifeExp")
fig.update_traces(textposition='top center')
fig.update_layout(title_text='Life Expectency', title_x=0.5)
fig.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 恕我直言,这种速度的动画不会增加任何东西,精心设计的固定图像不会那么令人沮丧。 (2认同)

Anw*_*vic 8

我想补充一点,您甚至可以使用箭头/文本框来注释标签。这就是我的意思:

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()
Run Code Online (Sandbox Code Playgroud)

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


iru*_*yak 6

您也可以使用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)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明