我已经把头发拉了一会儿。我正在尝试使用mpldatacursor
和matplotlib
来提供散点图上的工具提示功能。每个点都有一些与之关联的数据,我希望在点击该点时显示这些数据。
这是一个最小的(不是)工作示例:
import numpy as np
import mpldatacursor
import string
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib import pyplot as mpl
nations = ['Russia', 'America', 'China', 'France']
data = list()
idx = list()
np.random.seed(42) #Seed for repeatability
# Random data
for (id, nation) in enumerate(nations):
for i in range(0,10):
data.append((id+1)*np.random.random((2,1)))
name = list(string.ascii_uppercase[20:])
np.random.shuffle(name)
idx.append(nation + '-' + ''.join(name))
mpl.figure()
data = np.squeeze(np.asarray(data))
m, n = 0, 9
# Plot by group
for (id,nation) in enumerate(nations):
mpl.scatter(data[m:n,0] , data[m:n,1] , label=nation)
m = n + 1
n += 10
formatter = lambda **kwargs: ', '.join(kwargs['point_label'])
mpl.legend()
mpldatacursor.datacursor(formatter=formatter, point_labels=idx)
mpl.show(block=True)
但是当我这样做时,工具提示与传说不符。此外,只有以Russia
和USA
开头的标签会显示在图中。我做错了什么?
答案 0 :(得分:2)
问题是,componentDidMount(){
const mychart = new Chartist.Line('.ct-chart', data);
}
每次调用scatter
都会创建一个新的艺术家对象。解决方法基于source code中的doc字符串。
point_labels:sequence或dict,可选 艺术家“子项目”的标签,传递给格式化程序 作为
matplotlib
kwarg运行。可能是单身 序列(用于所有艺术家)或艺术家的词典:序列对。
它确实涉及导入受保护的matplotlib模块/成员。这看起来像我想要的那样:
point_label
答案 1 :(得分:1)
假设您只是想要名字,如果您将mpldatacursor.datacursor
来电更改为使用'{label}'
,就像mpldatacursor
网站上的第一个example一样,这似乎正常/ p>
mpldatacursor.datacursor(formatter='{label}'.format)
我认为问题出在kwargs
和lambda函数上。如果您想在工具提示中获得更多数据,最好将其添加到plt.scatter
上的标签上,对每个点使用单独的调用,例如
import numpy as np
import mpldatacursor
import string
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib import pyplot as plt
nations = ['Russia', 'America', 'China', 'France']
cDict = {'Russia':'r', 'America':'b', 'China':'g', 'France':'c'}
np.random.seed(42) #Seed for repeatability
# Random data
for (id, nation) in enumerate(nations):
for i in range(0,10):
x = (id+1)*np.random.random((2,1))
name = list(string.ascii_uppercase[20:])
np.random.shuffle(name)
plt.scatter(x[0], x[1], c=cDict[nation], label=nation + '-' + ''.join(name))
mpldatacursor.datacursor(formatter='{label}'.format)
plt.show(block=True)
答案 2 :(得分:1)
通常,您可以将数据放在表格中,或者为了示例,您可以使用多个列表。因此,可能会从数据列创建单个散点图,并使用名称到数字的映射来创建散点图中的颜色。
然后,可以使用matplotlib pick_event
从相应列表中获取数据,给定点击发生点的索引。
这一切都不需要任何外部软件包,如datacursor。
import numpy as np; np.random.seed(42)
import string
from matplotlib import pyplot as plt
nations = ['Russia', 'America', 'China', 'France']
#Create lists data, nat, idx
nat = np.random.choice(nations, 50)
data = np.random.rand(50,2)
strings = ["".join(np.random.choice(list(string.ascii_uppercase), 7)) for _ in range(50)]
idx = ["{}-{}".format(n,w) for n,w in zip(nat,strings)]
labels, i = np.unique(nat, return_inverse=True)
fig, ax = plt.subplots()
scatter = ax.scatter(data[:,0], data[:,1], c=i, cmap="RdYlGn", picker=5)
rect = lambda c: plt.Rectangle((0,0),1,1, color=scatter.cmap(scatter.norm(c)))
handles = [rect(c) for c in np.unique(i)]
plt.legend(handles, labels)
#Create annotation
annot = ax.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
#Create event handler
def onpick(evt):
if evt.artist == scatter:
ind = evt.ind[0]
annot.xy = (data[ind])
annot.set_text(idx[ind])
annot.set_visible(True)
if evt.mouseevent.button == 3:
annot.set_visible(False)
fig.canvas.draw_idle()
fig.canvas.mpl_connect("pick_event", onpick)
plt.show()