Matplotlib:如何单独标记点?
在使用matplotlib这个库时,我用scatter
方法画了一些点(见下面的代码)。我想给每个点单独加上标签。
这段代码会用labels
数组给每个点加标签,但我希望第一个点用labels[0]
来标记,第二个点用labels[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()
这个方法返回的数据我看不懂。
谢谢!
2 个回答
2
所有这些内容都可以放在一个函数或类里面,隐藏起来。
# 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)
4
假设你并不是要绘制很多散点图,你可以为每个点单独调用一次 scatter
方法:
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>]
如果你只是想获取坐标轴中的散点集合,最简单的方法是通过 ax.collections
。这个 list
包含了在坐标轴中绘制的所有 collections
实例(散点属于 PathCollection
)。
In [9]: ax.collections
Out[9]: [<matplotlib.collections.PathCollection at 0x10308ba10>]
如果你为每个点都单独绘制了一个 scatter
,那么遍历这些点就非常简单了:
# iterate over points and turn them all red
for point in ax.collections:
point.set_facecolor("red")