Matplotlib 中带有 for 循环的滑块
Slider with for loop in Matplotlib
我想求出二次方程 ax^2 + bx + c =0
的两个根,并根据系数 c
绘制它们,同时将 a
保持为可变参数。要更改 a
并查看更改参数后绘图会发生什么情况,我想从 Python 的 Matplotlib 模块为 a
创建一个 Silder
。
我有以下内容,但是,它似乎不起作用。
# Solve the quadratic equation ax**2 + bx + c = 0
from matplotlib.widgets import Slider # import the Slider widget
import numpy as np
import matplotlib.pyplot as plt
import cmath
a_min = -2
a_max = 2
a_init = -2
fig = plt.figure(figsize=(8,3))
# Slider layout
slider_ax = plt.axes([0.1, 0.05, 0.8, 0.05])
b = 10
def sol1(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b-np.sqrt(d))/(2*a)
def sol2(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b+np.sqrt(d))/(2*a)
for c in np.linspace(-2, 2, 11):
print('c=',c,' sol1=',sol1(a_init,b,c),' sol2=',sol2(a_init,b,c))
# Plot with initial parameter value
#plt.axes(func_ax)
plt.xlabel('$c$')
plt.title('Roots of $ax^2 + bx + c = 0$')
plot1, = plt.plot(c, sol1(a_init,b,c), 'r')
plot2, = plt.plot(c, sol2(a_init,b,c), 'b')
# Create a slider
a_slider = Slider(slider_ax, # the axes object containing the slider
'$a$', # the name of the slider parameter
a_min, # minimal value of the parameter
a_max, # maximal value of the parameter
valinit=a_init # initial value of the parameter
)
# Update function
def update(a):
plot1.set_ydata(sol1(a,b,c))
plot2.set_ydata(sol2(a,b,c))
fig.canvas.draw_idle() # redraw the plot
# Execute when parameter gets updated
a_slider.on_changed(update)
plt.show()
有什么帮助吗?
我对您的代码进行了一些修改以使滑块正常工作:
- 首先,
plot1
和 plot2
是在代码的循环中定义的。这意味着它们在每次迭代时都会被删除并重新创建。相反,计算要绘制的所有变量然后在循环外绘制它们更有意义。这是在 update_sols
函数中执行的。
- 其次,我更改了滑块的
update
功能。应使用 a_slider.val
访问滑块更新的变量(参见示例 here)。
- 最后,为了确保您可以看到想要绘制的所有内容,您需要在每次移动滑块时更新绘图的 y 限制。
总体而言,更新后的代码如下所示:
from matplotlib.widgets import Slider
import numpy as np
import matplotlib.pyplot as plt
import cmath
#Initial values
a_min = -2
a_max = 2
a_init = -2
b = 10
c_list=np.linspace(-2, 2, 11)
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
# Slider layout
slider_ax = plt.axes([0.25, 0.1, 0.65, 0.03])
def sol1(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b-np.sqrt(d))/(2*a)
def sol2(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b+np.sqrt(d))/(2*a)
#Function to update solutions after modifying c
def update_sols(a):
res1=[]
res2=[]
for c in c_list:
res1.append(sol1(a,b,c))
res2.append(sol2(a,b,c))
return res1,res2
#Initialising plot with solutions for a_init
sols1,sols2=update_sols(a_init)
plot1,=ax.plot(c_list, sols1, 'r')
plot2,=ax.plot(c_list, sols2, 'b')
ax.set_xlabel('$c$')
ax.set_title('Roots of $ax^2 + bx + c = 0$')
# Create a slider
a_slider = Slider(ax=slider_ax,label='$a$',valmin=a_min,valmax=a_max,valinit=a_init)
# Update function
def update(val):
#updating y data
sols1,sols2=update_sols(a_slider.val)
plot1.set_ydata(sols1)
plot2.set_ydata(sols2)
#updating y limits
sols1_abs=np.abs(sols1)
sols2_abs=np.abs(sols2)
max_ylim=np.amax(np.concatenate((sols1_abs,sols2_abs)))
ax.set_ylim([-1.1*max_ylim,1.1*max_ylim])
fig.canvas.draw_idle() # redraw the plot
# Execute when parameter gets updated
a_slider.on_changed(update)
plt.show()
输出如下所示:
我想求出二次方程 ax^2 + bx + c =0
的两个根,并根据系数 c
绘制它们,同时将 a
保持为可变参数。要更改 a
并查看更改参数后绘图会发生什么情况,我想从 Python 的 Matplotlib 模块为 a
创建一个 Silder
。
我有以下内容,但是,它似乎不起作用。
# Solve the quadratic equation ax**2 + bx + c = 0
from matplotlib.widgets import Slider # import the Slider widget
import numpy as np
import matplotlib.pyplot as plt
import cmath
a_min = -2
a_max = 2
a_init = -2
fig = plt.figure(figsize=(8,3))
# Slider layout
slider_ax = plt.axes([0.1, 0.05, 0.8, 0.05])
b = 10
def sol1(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b-np.sqrt(d))/(2*a)
def sol2(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b+np.sqrt(d))/(2*a)
for c in np.linspace(-2, 2, 11):
print('c=',c,' sol1=',sol1(a_init,b,c),' sol2=',sol2(a_init,b,c))
# Plot with initial parameter value
#plt.axes(func_ax)
plt.xlabel('$c$')
plt.title('Roots of $ax^2 + bx + c = 0$')
plot1, = plt.plot(c, sol1(a_init,b,c), 'r')
plot2, = plt.plot(c, sol2(a_init,b,c), 'b')
# Create a slider
a_slider = Slider(slider_ax, # the axes object containing the slider
'$a$', # the name of the slider parameter
a_min, # minimal value of the parameter
a_max, # maximal value of the parameter
valinit=a_init # initial value of the parameter
)
# Update function
def update(a):
plot1.set_ydata(sol1(a,b,c))
plot2.set_ydata(sol2(a,b,c))
fig.canvas.draw_idle() # redraw the plot
# Execute when parameter gets updated
a_slider.on_changed(update)
plt.show()
有什么帮助吗?
我对您的代码进行了一些修改以使滑块正常工作:
- 首先,
plot1
和plot2
是在代码的循环中定义的。这意味着它们在每次迭代时都会被删除并重新创建。相反,计算要绘制的所有变量然后在循环外绘制它们更有意义。这是在update_sols
函数中执行的。 - 其次,我更改了滑块的
update
功能。应使用a_slider.val
访问滑块更新的变量(参见示例 here)。 - 最后,为了确保您可以看到想要绘制的所有内容,您需要在每次移动滑块时更新绘图的 y 限制。
总体而言,更新后的代码如下所示:
from matplotlib.widgets import Slider
import numpy as np
import matplotlib.pyplot as plt
import cmath
#Initial values
a_min = -2
a_max = 2
a_init = -2
b = 10
c_list=np.linspace(-2, 2, 11)
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
# Slider layout
slider_ax = plt.axes([0.25, 0.1, 0.65, 0.03])
def sol1(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b-np.sqrt(d))/(2*a)
def sol2(a,b,c):
d = (b**2) - (4*a*c) # Discriminant
return (-b+np.sqrt(d))/(2*a)
#Function to update solutions after modifying c
def update_sols(a):
res1=[]
res2=[]
for c in c_list:
res1.append(sol1(a,b,c))
res2.append(sol2(a,b,c))
return res1,res2
#Initialising plot with solutions for a_init
sols1,sols2=update_sols(a_init)
plot1,=ax.plot(c_list, sols1, 'r')
plot2,=ax.plot(c_list, sols2, 'b')
ax.set_xlabel('$c$')
ax.set_title('Roots of $ax^2 + bx + c = 0$')
# Create a slider
a_slider = Slider(ax=slider_ax,label='$a$',valmin=a_min,valmax=a_max,valinit=a_init)
# Update function
def update(val):
#updating y data
sols1,sols2=update_sols(a_slider.val)
plot1.set_ydata(sols1)
plot2.set_ydata(sols2)
#updating y limits
sols1_abs=np.abs(sols1)
sols2_abs=np.abs(sols2)
max_ylim=np.amax(np.concatenate((sols1_abs,sols2_abs)))
ax.set_ylim([-1.1*max_ylim,1.1*max_ylim])
fig.canvas.draw_idle() # redraw the plot
# Execute when parameter gets updated
a_slider.on_changed(update)
plt.show()
输出如下所示: