【问题标题】:Slider with for loop in MatplotlibMatplotlib 中带有 for 循环的滑块
【发布时间】:2022-01-17 23:45:34
【问题描述】:

我想找到二次方程 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()

有什么帮助吗?

【问题讨论】:

    标签: python python-3.x matplotlib plot slider


    【解决方案1】:

    我对您的代码进行了一些修改以使滑块工作:

    • 首先,plot1plot2 在代码的循环中定义。这意味着它们会在每次迭代中被删除并再次创建。相反,计算要绘制的所有变量然后在循环外绘制它们更有意义。这是在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()
    

    输出看起来像这样:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 2016-03-16
      • 2016-01-16
      相关资源
      最近更新 更多