如何从Matplotlib

时间:2016-11-18 11:18:46

标签: python matplotlib

我有几个函数可以将各种集合绘制到轴ax

def my_scatter(ax, ...):
    pc = ax.scatter(...)

def plot(ax, ...):
    lc = mpl.collections.LineCollection(...)
    ax.add_collection(lc)

现在,我想为每个集合添加一个选择器,以便最终为每个集合调用一个函数加上已挑选集合成员的索引。伪编码这将实现以下意义上的东西:

def example_pick_fct1(idx):
   ...

def example_pick_fct2(idx):
   ...

def my_scatter(ax, pickfct, ...):
    pc = ax.scatter(...)
    pc.add_pickfct(pickfct)

def my_lines(ax, pickfct, ...):
    lc = mpl.collections.LineCollection(...)
    ax.add_collection(lc)
    lc.add_pickfct(pickfct)

my_scatter(ax, example_pick_fct1, ...)
my_scatter(ax, example_pick_fct2, ...)
my_lines(ax, example_pick_fct2, ...)

我仔细研究了文档,但目前我没有看到如何实现它的好策略。 任何人都可以提供一些建议吗?(再一次,这个例子实际上是伪代码,我完全可以使用相同功能的任何一个好的解决方案。)

1 个答案:

答案 0 :(得分:0)

你的伪代码实际上很好。无法直接向艺术家添加选择功能。相反,您可以应用全局选择器,然后选择要调用的函数。这可以通过预先将地图(艺术家 - >功能)添加到常用字典来控制。根据哪些艺术家触发事件,可以调用相应的功能。

这是一个代码,它紧跟你的示例代码:

import matplotlib
import matplotlib.pyplot as plt
from matplotlib.colors import colorConverter
import numpy as np


a1 = np.random.rand(16,2)
a2 = np.random.rand(16,2)
a3 = np.random.rand(5,6,2)

# Create a pickermap dictionary that stores 
# which function should be called for which artist
pickermap = {}
def add_to_picker_map(artist, func):
    if func != None:
        pickermap.update({artist:func})


def example_pick_fct1(event):
   print "You clicked example_pick_fct1\n\ton", event.artist

def example_pick_fct2(event):
   print "You clicked example_pick_fct2\n\ton", event.artist

def my_scatter(ax, pickfct=None):
    pc = ax.scatter(a2[:,0], a2[:,1], picker=5)
    # add the artist to the pickermap
    add_to_picker_map(pc, pickfct)

def my_lines(ax, pickfct=None):
    lc = matplotlib.collections.LineCollection(a3, picker=5, colors=[colorConverter.to_rgba(i) for i in 'bgrcmyk'])
    ax.add_collection(lc)
    # add the artist to the pickermap
    add_to_picker_map(lc, pickfct)

def onpick(event):
    # if the artist that triggered the event is in the pickermap dictionary
    # call the function associated with that artist
    if event.artist in pickermap:
        pickermap[event.artist](event)


fig, ax = plt.subplots()
my_scatter(ax, example_pick_fct1)
# to register the same artist to two picker functions may not make too much sense, but I leave it here as you were asking for it
my_scatter(ax, example_pick_fct2) 
my_lines  (ax, example_pick_fct1)

#register the event handler
fig.canvas.mpl_connect('pick_event', onpick)

plt.show()