Python Matplotlib:如何单独标记点?

Python Matplotlib:如何单独标记点?,python,matplotlib,label,scatter,Python,Matplotlib,Label,Scatter,使用maptplotlib,我使用scatter方法绘制了一些点(参见下面的代码)。我想分别给每个点贴上标签 此代码将使用标签数组标记每个点,但我希望我的第一个点使用标签[0]标记,第二个点使用标签[1]标记,依此类推 import numpy as np; import matplotlib.pyplot as plt y = np.arange(10) # points to plot labels = np.arange(10) # labels of the points fig, ax

使用maptplotlib,我使用
scatter
方法绘制了一些点(参见下面的代码)。我想分别给每个点贴上标签

此代码将使用
标签
数组标记每个点,但我希望我的第一个点使用
标签[0]
标记,第二个点使用
标签[1]
标记,依此类推

import numpy as np; import matplotlib.pyplot as plt
y = np.arange(10) # points to plot
labels = np.arange(10) # labels of the points
fig, ax = plt.subplots(nrows=1, ncols=1)
ax.scatter(x=np.arange(10), y=y, label=labels, picker=3)
有办法吗? 顺便问一句,有没有什么方法可以遍历
ax
中的点?方法
ax.get_children()
产生我不理解的数据


谢谢

假设您没有绘制多个散布点,您可以对每个点进行
散布

import numpy as np; import matplotlib.pyplot as plt
y = np.arange(10) # points to plot
x=np.arange(10)
labels = np.arange(10) # labels of the points
fig, ax = plt.subplots(nrows=1, ncols=1)
for x_,y_,label in zip(x,y,labels):
    ax.scatter([x_], [y_], label=label, picker=3)
如果要绘制数千或上万个点,这将开始滞后,但如果只是少数点,则没有问题

要回答问题的第二部分,
ax.get_children()
返回组成这些轴的对象列表,例如:

[<matplotlib.axis.XAxis at 0x103acc410>,
 <matplotlib.axis.YAxis at 0x103acddd0>,
 <matplotlib.collections.PathCollection at 0x10308ba10>, #<--- this is a set of scatter points
 <matplotlib.text.Text at 0x103082d50>,
 <matplotlib.patches.Rectangle at 0x103082dd0>,
 <matplotlib.spines.Spine at 0x103acc2d0>,
 <matplotlib.spines.Spine at 0x103ac9f90>,
 <matplotlib.spines.Spine at 0x103acc150>,
 <matplotlib.spines.Spine at 0x103ac9dd0>]
如果已为每个点绘制了单独的
散点
,则在这些点上进行迭代非常简单:

# iterate over points and turn them all red
for point in ax.collections:
    point.set_facecolor("red") 

所有这些都可以隐藏在函数或类中:

# import stuff
import matplotlib.pyplot as plt
import numpy as np

# create dictionary we will close over (twice)
label_dict = dict()
# helper function to do the scatter plot + shove data into label_dict
def lab_scatter(ax, x, y, label_list, *args, **kwargs):
    if 'picker' not in kwargs:
        kwargs['picker'] = 3
    sc = ax.scatter(x, y, *args, **kwargs)
    label_dict[sc] = label_list
    return sc
# call back function which also closes over label_dict, should add more sanity checks
# (that artist is actually in the dict, deal with multiple hits in ind ect)
def cb_fun(event):
    # grab list of labels from the dict, print the right one
    print label_dict[event.artist][event.ind[0]]
# create the figure and axes to use
fig, ax = plt.subplots(1, 1)
# loop over 5 synthetic data sets
for j in range(5):
    # use our helper function to do the plotting
    lab_scatter(ax,
                np.ones(10) * j,
                np.random.rand(10),
                # give each point a unique label
                label_list = ['label_{s}_{f}'.format(s=j, f=k) for k in range(10)])
# connect up the call back function
cid = fig.canvas.mpl_connect('pick_event', cb_fun)

使用
注释
。它允许您添加指向任意点的标签+箭头。是否要为每个点添加标签(即在指向该点的轴上放置文本标签或)您想为每个点创建一个图例条目吗?@tcaswell这一切背后的要点是将
pick_event
连接到一个回调,该回调将打印艺术家的标签:
def callback(event):print event.artist.get_label()
,所以我想我只需要一个图例条目?我希望每个点都有一个艺术家,但显然这是不可能的,除非我在每个点上使用一个
scatter
(下面的答案)查看
事件
对象携带的数据。我认为它应该带有你击中的点的索引。如果是这样的话,那就把你的回电循环放到你的标签列表上。谢谢你的详细回答。如果我不为每个点使用单独的
散点
,我想就没有办法迭代这些点了?如果是,你知道为什么吗?在我看来,这似乎是一个非常有用/并不奇怪的功能,因为我确实有数千个情节点。@Niourf我不确定,我已经在好几个场合寻找过这样做的方法,但我运气不太好。但是,我认为更好的方法是使用
plot
而不是
scatter
,使用
lw=0
。用于行的类比
PathCollections
类具有更大的灵活性。好的。我使用了
scatter
而不是
plot
,因为我需要使用一些奇特的颜色。我对matplotlib很陌生,但我倾向于发现它比它可能要复杂得多…@Niourf它几乎和它需要的一样复杂(刚开始看起来太复杂的任何东西都是允许其他东西工作的方式)。mpl图的逻辑构建块是“艺术家”(可能知道数据),而不是“点”(数据)。iirc
scatter
返回一个面片集合对象,该对象提供更改颜色映射、标记大小和值的函数(
set_data
)。您应该知道它们在哪里,因为您仍然有
x
y
数组。@tcaswell
PathCollections
没有
set\u data
get\u data
方法。
# import stuff
import matplotlib.pyplot as plt
import numpy as np

# create dictionary we will close over (twice)
label_dict = dict()
# helper function to do the scatter plot + shove data into label_dict
def lab_scatter(ax, x, y, label_list, *args, **kwargs):
    if 'picker' not in kwargs:
        kwargs['picker'] = 3
    sc = ax.scatter(x, y, *args, **kwargs)
    label_dict[sc] = label_list
    return sc
# call back function which also closes over label_dict, should add more sanity checks
# (that artist is actually in the dict, deal with multiple hits in ind ect)
def cb_fun(event):
    # grab list of labels from the dict, print the right one
    print label_dict[event.artist][event.ind[0]]
# create the figure and axes to use
fig, ax = plt.subplots(1, 1)
# loop over 5 synthetic data sets
for j in range(5):
    # use our helper function to do the plotting
    lab_scatter(ax,
                np.ones(10) * j,
                np.random.rand(10),
                # give each point a unique label
                label_list = ['label_{s}_{f}'.format(s=j, f=k) for k in range(10)])
# connect up the call back function
cid = fig.canvas.mpl_connect('pick_event', cb_fun)