我已经扩展following示例以使用多个子图。这是我的代码:
#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
########################################
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
########################################
plt.close('all')
fig, ax = plt.subplots(nrows=2, ncols=1)
plt.subplots_adjust(bottom=0.30)
########################################
ax[0].plot(t,s, lw=2, color='red', label="red")
ax[1].plot(t,s, lw=2, color='green', label="green")
########################################
# plt.axis([0, 1, -10, 10])
ax[0].set_xlim([0, 1])
ax[0].set_ylim([-10, 10])
ax[1].set_xlim([0, 1])
ax[1].set_ylim([-10, 10])
########################################
axcolor = 'lightgoldenrodyellow'
f1 = plt.axes([0.25, 0.20, 0.65, 0.03], axisbg=axcolor)
a1 = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
f2 = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
a2 = plt.axes([0.25, 0.05, 0.65, 0.03], axisbg=axcolor)
sf1 = Slider(f1, 'Freq1', 0.1, 30.0, valinit=f0)
sa1 = Slider(a1, 'Amp1', 0.1, 10.0, valinit=a0)
sf2 = Slider(f2, 'Freq2', 0.1, 30.0, valinit=f0)
sa2 = Slider(a2, 'Amp2', 0.1, 10.0, valinit=a0)
########################################
def update1(val):
amp = sa1.val
freq = sf1.val
# DOES NOT WORKS - set_ydata DOES NOT EXISTS
# ax[1].set_ydata(amp*np.sin(2*np.pi*freq*t))
# ax[2].set_ydata(amp*np.sin(2*np.pi*freq*t))
# WORKS BUT IT SEEMS SLOW
s = amp*np.sin(2*np.pi*freq*t)
ax[0].clear()
ax[0].plot(t,s, lw=2, color='red', label="red")
ax[0].set_xlim([0, 1])
ax[0].set_ylim([-10, 10])
# THIS HAS NO EFFECT ON SPEED
fig.canvas.draw_idle()
sf1.on_changed(update1)
sa1.on_changed(update1)
def update2(val):
amp = sa2.val
freq = sf2.val
# DOES NOT WORKS - set_ydata DOES NOT EXISTS
# ax[1].set_ydata(amp*np.sin(2*np.pi*freq*t))
# ax[2].set_ydata(amp*np.sin(2*np.pi*freq*t))
# WORKS BUT IT SEEMS SLOW
s = amp*np.sin(2*np.pi*freq*t)
ax[1].clear()
ax[1].plot(t,s, lw=2, color='green', label="green")
ax[1].set_xlim([0, 1])
ax[1].set_ylim([-10, 10])
# THIS HAS NO EFFECT ON SPEED
fig.canvas.draw_idle()
sf2.on_changed(update2)
sa2.on_changed(update2)
plt.show()
唯一的问题是它比原始速度慢(当点击滑块时)。我怀疑这是由update1
和update2
函数中使用的一堆代码引起的。我不知道如何更有效地重写它。原始示例使用set_ydata
函数,但似乎子图不具有此功能。我一直在考虑所有四个滑块的update
函数,但我不知道是否可以区分触发更新的对象并在函数内处理它。感谢
答案 0 :(得分:1)
您尝试分别在set_ydata
(或ax[0]
)上致电ax[1]
。这显然不起作用,因为这些是轴实例。 set_ydata
是Line2D
艺术家的一种方法。在您已链接的示例中,在开头创建了一行l
,它在更新函数中接收新的y数据。你在代码中忘记了这一点。
所以你需要创建一行:
line0, = ax[0].plot(t,s, lw=2, color='red')
line1, = ax[1].plot(t,s, lw=2, color='green')
在开头,然后在您的更新功能中,您可以致电:
line0.set_ydata(amp*np.sin(2*np.pi*freq*t))
或
line1.set_ydata(amp*np.sin(2*np.pi*freq*t))
注意:这里的想法是只更改线条的y坐标。通过解决方法,您删除了整个图并重新创建了它。这是更多的工作,因此它会使事情变得更慢。