在一个子图matplotlib中使用两个不同行的滑块

时间:2017-05-17 11:20:59

标签: python matplotlib

我在matplotlib的一个图中绘制了六个子图。我正在使用matplotlib滑块绘制一个具有不同参数值的函数。一个子图中有两行,每行代表函数。如果我要更改功能参数,我想看看它们在哪里交叉以及它们的行为方式。但是我还没想出如何绘制两条线并在一个子图中用滑块改变两条线的ydata

以下是代码的一部分:

#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)

这是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)

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我只更改了代码中的一些内容以获取此信息:

#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)

你看我评论了我改变了什么。大多数情况下,这是添加图p1p2并在更新时重新调整。

我希望这适合你。我无法帮助您处理该错误代码,因为您提供的代码甚至没有109行......

答案 1 :(得分:1)

如果绘图中有两行,则需要将它们解压缩为两个不同的变量,

p2,p3 = ax2.plot(N, V_fc_list, 'r-', N, E_list, 'b-', lw = 3)

然后您可以按如下方式设置两行数据:

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()