【发布时间】:2021-10-23 02:24:36
【问题描述】:
试图解决这个问题超过一个星期。
我正在使用 matplotlib 创建一个声学标签交互式应用程序,我希望用户能够单击频谱图顶部的一条线并使用 line.set_xdata() 向左/向右拖动它。它基本上可以工作,但非常慢 - 每秒更新 2-4 个位置。当不显示频谱图时,它的工作原理有些合理。添加一个随机矩阵来模拟效果。
Python==3.8.1 Matplotlib==3.4.3
我试过了:
交互模式开/关
canvas.draw_idle() 而不是画图
canvas.flush_events()
仍然没有运气。有人吗? 提前致谢!
重现示例:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.lines as lines
class draggable_lines:
def __init__(self, ax, kind, XorY):
self.ax = ax
self.c = ax.get_figure().canvas
self.o = kind
self.XorY = XorY
if kind == "h":
x = [-1, 1]
y = [XorY, XorY]
elif kind == "v":
x = [XorY, XorY]
y = [0, 800]
self.line = lines.Line2D(x, y, color='white', picker=5)
self.ax.add_line(self.line)
self.c.draw_idle()
self.sid = self.c.mpl_connect('pick_event', self.clickonline)
def clickonline(self, event):
if event.artist == self.line:
print("line selected ", event.artist)
self.follower = self.c.mpl_connect("motion_notify_event", self.followmouse)
self.releaser = self.c.mpl_connect("button_press_event", self.releaseonclick)
def followmouse(self, event):
if self.o == "h":
self.line.set_ydata([event.ydata, event.ydata])
else:
self.line.set_xdata([event.xdata, event.xdata])
self.c.draw_idle()
def releaseonclick(self, event):
if self.o == "h":
self.XorY = self.line.get_ydata()[0]
else:
self.XorY = self.line.get_xdata()[0]
print(self.XorY)
self.c.mpl_disconnect(self.releaser)
self.c.mpl_disconnect(self.follower)
fig = plt.figure()
ax = fig.add_subplot(111)
stft = np.random.rand(1025, 1500)
ax.pcolormesh(stft, cmap='magma')
Tline = draggable_lines(ax, "v", 700)
plt.show(block=True)
【问题讨论】:
-
也许你可以
imshow而不是pcolormesh?在这种情况下,pcolormesh正在创建1537500小矩形。pcolormesh还包括边缘,对于这么多单元格,这些边缘根本没有用。 -
感谢@JohanC!
pcolormesh是这里的瓶颈。pcolorfast和imshow的表现明显更好,所用时间大致相同。
标签: python python-3.x matplotlib user-interface plot