以下是代码:
#!/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)
########################################
line0, = ax[0].plot(t,s, lw=2, color='red', label="red")
# IS THIS LINE NECESSARY
line1, = ax[1].plot(t,s, lw=2, color='green', label="green")
########################################
ax[0].set_xlim([0, 1])
ax[0].set_ylim([-10, 10])
########################################
axcolor = 'lightgoldenrodyellow'
left = 0.25
bottom = 0.20
width = 0.65
# DIFFERENT SCALE
# height = fig.get_size_inches()[1] * 0.1
height = 0.03
vgap = 0.02
print "fig height %s" % fig.get_size_inches()[1]
f1 = plt.axes([left, bottom-0*(height+vgap), width, height], axisbg=axcolor)
a1 = plt.axes([left, bottom-1*(height+vgap), width, height], axisbg=axcolor)
sf1 = Slider(f1, 'Freq1', 0.1, 30.0, valinit=f0)
sa1 = Slider(a1, 'Amp1', 0.1, 10.0, valinit=a0)
########################################
def update1(val):
amp = sa1.val
freq = sf1.val
line0.set_ydata(amp*np.sin(2*np.pi*freq*t))
line1.set_ydata(2*amp*np.sin(2*np.pi*freq*t))
sf1.on_changed(update1)
sa1.on_changed(update1)
plt.show()
当使用滑块改变第1点上的波幅/频率时,也会改变第2图上的波幅/频率(使第2图上的振幅加倍)。问题是,当第一幅图的幅值超过3时,它根本不适合第二幅图。因为它的y
范围从-6到6。
三个问题:
ax[1].set_ylim([-20, 20])
来设置它,但是我想要一些更一般的东西。让我们假设第二幅图的y
值可以超过20 (这可能是一些复杂计算的结果,在绘图过程中不为人所知)。当第一幅幅值较小时,第二幅图的y
应缩小,振幅较大时,y
应扩展。发布于 2015-07-09 09:20:32
编辑:用户击打对最初的答案在评论中提供了一些有用的改进--我采用了这些方法,并且通常使答案更深、更通用。
我会一个接一个地回答问题
这是matplotlib的最佳猜测,基于最初绘制在轴上的数据。如果不指定任何值,它将尽可能地满足轴的限制。
对于那些有着更深层次兴趣的人,matplotlib默认在没有指定标度的情况下自动缩放轴,而这些代码行实际上应用了自动缩放。
你快到了。在update1()
中,添加ax[1].autoscale_view()
,在添加新数据时,必须先加上 ax[1].relim()
。这将使matplotlib自动缩放轴,以适应您在其上绘制的任何数据的值,这是一个通用的解决方案。如果您需要‘手动’但动态控制自己的斧头,请参阅我最初的建议如下。
N.B.在最初的版本中,我建议只编写ax[1].set_ylim(-2.2*amp,2.2*amp)
或类似的东西,其中2.2
是一个任意因素:由滑块设置的正弦波振幅的限制加上一点( 0.2
)。
是。一种方法是替换
line1, = ax[1].plot(t,s, lw=2, color='green', label="green")
使用
line1, = ax[1].plot([],[], lw=2, color='green', label="green")
这将在您可以更新的轴上创建一个行对象,但该对象最初没有数据。注:我最初建议使用0,0
而不是[],[]
,但这将在0,0绘制一个点,这可能不符合您的目的。
然后在update1()
中
line1.set_xdata(t)
update1()
函数的最终代码
def update1(val):
amp = sa1.val
freq = sf1.val
line0.set_ydata(amp*np.sin(2*np.pi*freq*t))
line1.set_xdata(t)
line1.set_ydata(2*amp*np.sin(2*np.pi*freq*t))
ax[1].relim()
ax[1].autoscale_view()
https://stackoverflow.com/questions/31322394
复制相似问题