Reputation: 1207
I am plotting six subplots in one figure in matplotlib. I am plotting one function with different parameter values using matplotlib sliders. There are two lines in one subplot, each representing function. I want to see where they cross and how they behave if I am changing function parameters. But I havent figured out how to plot two lines and change ydata
for two lines in one subplot with sliders.
Here is part of code:
#imports
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.widgets as mw
import math
import numpy as np
#set variables
E0 = 0.5
E1 = .0003
V = .3
#x axis
N = [i for i in range(10000)]
#functions
V_fc_list = [V for n in N]
E_list = [E0*math.exp(-E1*n) for n in N]
#subplots
fig = plt.figure()
ax1 = fig.add_subplot(321)
ax2 = fig.add_subplot(322)
ax3 = fig.add_subplot(323)
ax4 = fig.add_subplot(324)
ax5 = fig.add_subplot(325)
ax6 = fig.add_subplot(326)
#sliders place
ax6.axis('off')
#Sliders
axis_color = 'lightgoldenrodyellow'
E0_slider_ax = fig.add_axes([0.57, 0.3, 0.3, 0.02], axisbg=axis_color)
E1_slider_ax = fig.add_axes([0.57, 0.25, 0.3, .02], axisbg = axis_color)
V_slider_ax = fig.add_axes([0.57, 0.2, 0.3, .02], axisbg = axis_color)
E0_slider = mw.Slider(E0_slider_ax, r'$\epsilon_0$', valmin = 0, valmax = 1, valinit = E0)
E0_slider.label.set_size(15)
E1_slider = mw.Slider(E1_slider_ax, r'$\epsilon_1$', 0.0001, 0.003, valinit = E1)
E1_slider.label.set_size(15)
V_slider = mw.Slider(V_slider_ax, r'$V_c$', 0.001, 0.99, valinit = V)
V_slider.label.set_size(15)
#slider function HERE IS THE MISTAKE
def sliders_on_change(val):
p2.set_ydata([V_slider.val for n in N])
p2.set_ydata([E0_slider.val*math.exp(-E1_slider.val*n) for n in N])
fig.canvas.draw_idle()
V_slider.on_changed(sliders_on_change)
E0_slider.on_changed(sliders_on_change)
E1_slider.on_changed(sliders_on_change)
Here is the last part of error from python
File "C:/Users/Robert/Desktop/python/multidif_S.py", line 109, in <module>
p2,= ax2.plot(N, V_fc_list, 'r-', N, E_list, 'b-', lw = 3)
ValueError: too many values to unpack (expected 1)
Thx for any help!
Upvotes: 0
Views: 982
Reputation: 339795
If you have two lines in a plot, you need to unpack them to two different variables,
p2,p3 = ax2.plot(N, V_fc_list, 'r-', N, E_list, 'b-', lw = 3)
You can then set the data on the two lines as follows:
def sliders_on_change(val):
p3.set_ydata([V_slider.val for n in N])
p2.set_ydata([E0_slider.val*math.exp(-E1_slider.val*n) for n in N])
fig.canvas.draw_idle()
Upvotes: 1
Reputation: 3493
I changed only a few things in your code to get this:
#imports
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.widgets as mw
import math
import numpy as np
#set variables
E0 = 0.5
E1 = .0003
V = .3
#x axis
N = [i for i in range(10000)]
#functions
V_fc_list = [V for n in N]
E_list = [E0*math.exp(-E1*n) for n in N]
#subplots
fig = plt.figure()
ax1 = fig.add_subplot(321)
ax2 = fig.add_subplot(322)
ax3 = fig.add_subplot(323)
ax4 = fig.add_subplot(324)
ax5 = fig.add_subplot(325)
ax6 = fig.add_subplot(326)
#sliders place
ax6.axis('off')
#Sliders
axis_color = 'lightgoldenrodyellow'
E0_slider_ax = fig.add_axes([0.57, 0.3, 0.3, 0.02], axisbg=axis_color)
E1_slider_ax = fig.add_axes([0.57, 0.25, 0.3, .02], axisbg = axis_color)
V_slider_ax = fig.add_axes([0.57, 0.2, 0.3, .02], axisbg = axis_color)
E0_slider = mw.Slider(E0_slider_ax, r'$\epsilon_0$', valmin = 0, valmax = 1, valinit = E0)
E0_slider.label.set_size(15)
E1_slider = mw.Slider(E1_slider_ax, r'$\epsilon_1$', 0.0001, 0.003, valinit = E1)
E1_slider.label.set_size(15)
V_slider = mw.Slider(V_slider_ax, r'$V_c$', 0.001, 0.99, valinit = V)
V_slider.label.set_size(15)
# Here I introduce the plots p1 and p2. Your code didn't have any plots.
p1 = ax1.plot(np.zeros_like(N)) # plot1
p2 = ax1.plot(np.zeros_like(N)) # plot2, both in ax1
#slider function HERE IS THE MISTAKE
def sliders_on_change(val):
p1[0].set_ydata([V_slider.val for n in N]) # update p1
p2[0].set_ydata([E0_slider.val*math.exp(-E1_slider.val*n) for n in N]) # update p2
ax1.relim() # rescale the shown area (like an automatic call of ax1.set_xlim and ax1.set_ylim with proper inputs)
ax1.autoscale_view() # taken from this question: http://stackoverflow.com/questions/10984085/automatically-rescale-ylim-and-xlim-in-matplotlib
fig.canvas.draw()
V_slider.on_changed(sliders_on_change)
E0_slider.on_changed(sliders_on_change)
E1_slider.on_changed(sliders_on_change)
You see I commented where I changed something. Mostly this was adding the plots p1
and p2
and rescaling on update.
I hope this works for you. I can't help you with that error code because the code you provided does not even have 109 lines...
Upvotes: 1