Skip to main content
 首页 » 编程设计

python之如何指定回调以处理不同的 matplotlib 子图

2025年05月04日9xing901022

我有一个带有多个子图的 matplotlib 图,如下所示:

我想为这两个子图添加一个交互式组件,这样如果用户单击圆周上的一个节点,则只显示与该节点的连接。

此任务的一个重要元素是知道回调 event 具有引用其轴的 inaxes 属性。但这还不够。

为了完成我的任务,我需要存储一些绘图数据。具体来说,我需要知道哪些边对应于哪些节点,然后根据所选组件属于哪些轴检索该信息。

当图中只有一个轴时,我将这些信息存储在闭包中:

def make_subplot(): 
 
  def _on_button_press(event, indices=None): 
    # callback logic 
 
  callback = partial(indices=indices) 
  figure.mpl_connect('button_press_event',callback) 

但是,当有多个子图时,这不起作用,因为回调被覆盖或必须存储所有图的索引。

我的问题是,最好的方法是什么?据我所知,最简单的方法是将轴到子图的映射存储为全局变量,如下所示:

_indices_table = {} 
 
def make_subplot(): 
 
  def _on_button_press(event,axes=None): 
    indices = _indices_table[axes] 
    #callback logic 
 
  callback = partial(_on_button_press,axes=axes) 
  _indices_table.update({axes, indices}) 
  figure.mpl_connect('button_press_event', callback) 

但我正在寻找一个不那么丑陋的解决方案。也许只是因为我不喜欢全局变量。但我也不想添加大型控制结构的开销来处理此任务,因为全局变量会更简单、更易读。

我意识到我仍然可以将这个字典放在闭包中,但它基本上是相同的解决方案,除了更糟糕的是因为回调需要采用这些与回调逻辑无关的额外参数。

这里最 pythonic 的解决方案是什么?

请您参考如下方法:

只需将您的数据保存在 Ax 对象的属性中:

from matplotlib import pyplot as plt 
 
def _on_button_press(event): 
    ax = event.inaxes 
    if ax is not None: 
        print ax._my_labels 
 
fig, axes = plt.subplots(1,2) 
 
axes[0]._my_labels = [1,2,3] 
axes[1]._my_labels = [4,5,6] 
 
fig.canvas.mpl_connect('button_press_event', _on_button_press) 
 
plt.show()