我正在为电生理学数据开发一个自定义交互式图形,将 10-400 条线(EEG 或 MEG 数据通道)绘制为带有偏移的 LineCollection。使用垂直线来评估不同通道上的信号特征如何在时间上对齐通常很有用,因此我有一个button_press_event监听器来创建axvline(或更新该xdata线,如果它已经存在)。axvline如果 LineCollection 中有很多通道,则重绘的成本很高,但据说更有效的重绘方法 ( ax.draw_artist(my_vline)) 根本不起作用(很可能我只是误解了draw_artist应该如何工作)。
复制代码
import matplotlib.pyplot as plt
plt.ion()
def make_vline(event):
ax = event.inaxes
if getattr(ax, 'my_vline', None) is None:
ax.my_vline = ax.axvline(event.xdata, linewidth=4, color='r')
else:
ax.my_vline.set_xdata(event.xdata)
# I thought any 1 of these 3 lines would move the vline to the click location:
ax.draw_artist(ax.my_vline) # this has no visible effect
ax.redraw_in_frame() # TypeError (see below for traceback)
ax.figure.canvas.draw_idle() # works, but slow when figure has many lines
fig, ax = plt.subplots()
callback_id = fig.canvas.mpl_connect('button_press_event', make_vline)
实际结果
如果我使用该ax.draw_artist(ax.my_vline)线,无论我单击何处,结果都是空白轴(除非我随后调整图形大小,这会触发重绘,然后出现该线)。
如果我使用这ax.redraw_in_frame()条线,我会得到:
Traceback (most recent call last):
File "/opt/miniconda3/envs/mnedev/lib/python3.8/site-packages/matplotlib/cbook/__init__.py", line 224, in process
func(*args, **kwargs)
File "<ipython-input-1-08572d18e6b3>", line 11, in make_vline
ax.redraw_in_frame()
File "/opt/miniconda3/envs/mnedev/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 2778, in redraw_in_frame
stack.push(artist.set_visible, artist.get_visible())
TypeError: push() takes 2 positional arguments but 3 were given
如果我使用ax.figure.canvas.draw_idle()它,它会按预期工作,但是一旦图形中有实际数据,速度就会非常慢。这是一个较长的代码片段,您可以在本地运行以查看缓慢情况:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
plt.ion()
rng = np.random.default_rng()
问题
什么时候ax.draw_artist(my_artist)
真正起作用/它应该做什么?
我的示例是位块传输有益的情况吗?
关于如何加快(重新)绘制速度还有其他想法吗?
Matplotlib 版本
操作系统:Xubuntu 20.04
Matplotlib 版本:3.3.1(conda-forge)
Matplotlib 后端:Qt5Agg
Python版本:3.8.5
Jupyter 版本(如果适用):不适用
其他库:numpy 1.19.1(conda-forge)
MM们
相关分类