here code:
#!/usr/bin/python import numpy np import matplotlib.pyplot plt 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") # 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() when amplitude/frequency of wave on 1st plot changed using slider changes amplitude/frequency of wave on 2nd plot (it doubles amplitude on 2nd plot). problem when amplitude of 1st plot exceeds 3. in case not fits in 2nd plot. because has y range -6 6. 
three questions:
- where -6 , 6 number comes from? did not set them.
- how can y limit changed dynamically on 2nd plot? can set using e.g.
ax[1].set_ylim([-20, 20])want more general. let's pretend 2nd plot can haveyvalue more 20 (it might result of complicated computation not known during plotting). when amplitude of 1st plot small valueyof 2nd plot should shrink , when amplitude largeyshould expand. - can leave 2nd plot empty until change amplitude/frequency of 1st plot. in other words can (please show both cases, 1 when 2nd plot existing , when not) achieved without creating 2nd plot first using following line:
line1, = ax[1].plot(t,s, lw=2, color='green', label="green")
edit: user hitzg provided helpful improvements original answer in comments - i've taken these , made answer deeper , more generic.
i'll take questions 1 one
- where did 6 , -6 come from?
that's matplotlib's best guess, based on data plotted on axis originally. if don't specify values, fit axes limits best can.
for deeper interest - these lines of code matplotlib defaults auto-scaling axes if no scales specified, this line applying auto scaling.
- how can y limit changed dynamically on 2nd plot? i
you're there. in update1(), add ax[1].autoscale_view() which, you've added new data, must preceded by ax[1].relim(). let matplotlib autoscale axes suit values of whatever data have plotted on them , generic solution. if need 'manual' dynamic control of axes yourself, see original suggestion below.
n.b. in original version, suggested writing ax[1].set_ylim(-2.2*amp,2.2*amp) or similar 2.2 arbitrary factor: limits of sine wave amplitude set slider plus little bit (the 0.2)
- can leave 2nd plot empty until change amplitude/frequency of 1st plot?
yes. 1 way replace
line1, = ax[1].plot(t,s, lw=2, color='green', label="green") with
line1, = ax[1].plot([],[], lw=2, color='green', label="green") this creates line object on axes can update, has no data. n.b. suggested using 0,0 instead of [],[], plot point @ 0,0 might not suit purposes.
and in update1() put
line1.set_xdata(t) final code update1() function
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()
Comments
Post a Comment