【发布时间】:2021-01-24 22:45:17
【问题描述】:
我在一个有很多图的图形上使用 Matplotlib 小部件滑块。当我移动滑块时,更新图形大约需要 5 秒,这是我的问题。
在解决问题后,似乎罪魁祸首是调用 fig.canvas.draw() 的小部件本身。当在移动滑块时不执行任何操作(不修改任何子图)时,它仍然需要 5 秒来更新滑块,因为 fig.canvas.draw() 每次我触摸滑块时都会使用所有子图重新绘制所有图形.
在所有抱怨 Matplotlib 绘图速度的线程中,例如:why is plotting with Matplotlib so slow?,建议不要使用 fig.canvas.draw(),因为它会重绘整个图形,而是使用 ax.draw_artist() 来仅重新绘制已修改的子图的数据。因此,Matplotlib 小部件正在破坏我为使该绘图具有交互性所做的所有努力(5s 延迟并不是真正的交互性)。我可能会在使用不同的库之前就知道,但现在为时已晚。
这个问题实际上是在 2013 年提出的 (http://matplotlib.1069221.n5.nabble.com/Making-an-interactive-plot-faster-td41312.html),建议可以选择使用 draw_artist。将 drawon 设置为 False 的可能性对我不起作用,因为正如本文所述,小部件至少调用 fig.canvas.draw() 一次。自从这个问题第一次被提出以来,差不多 8 年前,是否有任何改进(我还没有发现)使 Matplotlib 小部件只更新小部件并让用户决定图中的哪些元素也应该更新?
我认为这是 Matplotlib 小部件的主要限制,我真的希望有办法纠正这种行为。在我的情况下,我可以通过将最大的图(静态图)绘制为图像或减少点数来加快绘图速度,但它仍然比让小部件不每次都重绘它的效率低。
--------更新-----------
在创建图形并仅添加小部件(5 个滑块、4 个按钮、1 个单选按钮)和 3 个空子图之后,滑块已经滞后!此时没有数据,一个图上只有 10 个小部件和 3 个空子图,并且每次我想移动滑块时已经有大约 0.5 秒 - 1 秒的延迟(通过眼睛)。 如果我连续上下移动滑块,我的 CPU 会从 15% 跳到 50%!我有一台带有 i7 7660U 的戴尔 XPS13(2 核 4 线程,4GHz turbo)。我不明白移动 1 个滑块如何占用大量 CPU。 matplotlib 计算这么重的东西是什么? 结果,我没有任何解决方法了。我用图像替换最大情节的想法不是很有用,因为即使没有任何数据或图像,滑块也已经太慢了!
有谁知道移动 1 个滑块如何如此疯狂地占用 CPU 资源,最重要的是,如何避免每次触摸滑块时出现这种延迟?
谢谢
这是我用来生成包含 10 个小部件和 3 个空子图的图形的代码示例。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
fig = plt.figure(figsize=(16, 10))
ax1 = plt.subplot2grid((6,10),(0,0), rowspan = 2, colspan = 8)
ax2 = plt.subplot2grid((6,10),(3,0), rowspan = 2, colspan = 7)
ax3 = plt.subplot2grid((6,10),(3,8), rowspan = 2, colspan = 2)
ax_color = 'lightgoldenrodyellow' # Color of the sliders
ax_win = plt.axes([0.23, 0.53, 0.65, 0.023], facecolor=ax_color)
ax_thres = plt.axes([0.23, 0.5, 0.65, 0.023], facecolor=ax_color)
ax_min_dist = plt.axes([0.23, 0.56, 0.65, 0.023], facecolor=ax_color)
ax_move_win = plt.axes([0.55, 0.05, 0.35, 0.023], facecolor=ax_color)
ax_resize_win = plt.axes([0.55, 0.08, 0.35, 0.023], facecolor=ax_color)
ax_save_res = plt.axes([0.20, 0.05, 0.075, 0.04])
ax_save_all = plt.axes([0.30, 0.05, 0.075, 0.04])
ax_previous = plt.axes([0.05, 0.05, 0.05, 0.04])
ax_next = plt.axes([0.1, 0.05, 0.05, 0.04])
ax_cb = plt.axes([0.85, 0.6, 0.12, 0.15])
ax_cb.set_frame_on(False)
ax_cb.text(0.5, 1, 'Plot', horizontalalignment='center', verticalalignment='top', transform=ax_cb.transAxes, fontsize=16)
s_win = Slider(ax_win, 'Res window width [kHz]', 10, 1000, valinit = 2e5/1e3)
s_thresdB = Slider(ax_thres, 'Min res depth threshold [dB]', -10, 0.0, valinit = -0.5)
s_min_dist = Slider(ax_min_dist, 'Min inter-res distance [kHz]', 0, 3, valinit = np.log10(6))
s_move_win = Slider(ax_move_win, 'Zoom position', 0, 1, valinit = 0)
s_resize_win = Slider(ax_resize_win, 'Zoom width', 0, 0.25, valinit = 0.05)
b_save_res = Button(ax_save_res, 'Save res', color='lightblue', hovercolor='gold')
b_save_all = Button(ax_save_all, 'Save all res', color='lightblue', hovercolor='gold')
b_previous = Button(ax_previous, 'Previous', color='greenyellow', hovercolor='gold')
b_next = Button(ax_next, 'Next', color='greenyellow', hovercolor='gold')
cb_plot2 = RadioButtons(ax_cb, ('FPtemp vs fres', 'BBtemp vs fres', 'Close'), (False, False, True))
【问题讨论】:
标签: performance matplotlib widget lag matplotlib-widget