使用 matplotlib 中的滑块调整参数方程的常数值

问题描述

我正在尝试绘制此 parametric equation 并使用 matplotlib 中的 Slider 小部件使绘图具有交互性。我希望能够调整常量 ak 的值,看看情节如何变化。到目前为止,我已经能够生成 this,但是尽管滑块是交互式的(即我可以更改它们上的值),但更改滑块上的值根本不会影响绘图。我无法弄清楚我做错了什么。这是我的代码。如果您能指出我正确的方向或提供任何帮助,我将不胜感激。谢谢。

注意:初始值(a_init 和 k_init)是随机的,没有任何意义。不过,我不认为问题出在他们身上。

from matplotlib.widgets import Slider
import numpy as np
import matplotlib.pyplot as plt

a_init = 15
k_init = 25

t = np.linspace(0,2*np.pi,100)

x = 2*k_init*np.cos(t)-a_init*np.cos(k_init*t)
y = 2*k_init*np.sin(t)-a_init*np.sin(k_init*t)

fig = plt.figure(figsize=(8,8))

parametric_ax = plt.axes([0.1,0.2,0.8,0.65])
slider_ax = plt.axes([0.1,0.03,0.05])
slider2_ax = plt.axes([0.1,0.10,0.05])

plt.axes(parametric_ax)
parametric_plot,= plt.plot(x,y)

a_slider = Slider(slider_ax,'a',1000,valinit=a_init)

k_slider = Slider(slider2_ax,'k',valinit=k_init)

def update(a,k):
    parametric_plot.set_ydata((2*k*np.cos(t)-a*np.cos(t*k)),(2*k*np.sin(t)-a*np.sin(t*k)))
    fig.canvas.draw_idle()          

a_slider.on_changed(update)
k_slider.on_changed(update)

plt.show()

解决方法

在滑块更新上调用的函数 update 只接受一个参数(比如 val,它对应于修改后的滑块的新值)。由于此回调函数由两个滑块共享,因此我建议不要在函数体中使用此 val 参数。相反,可以直接检索滑块的当前值。

方法 set_ydata 只更新 y 的数据,因此只需要一个一维数组作为输入。您可以通过 set_data 同时更改 x 和 y 的值,或者通过 set_xdataset_ydata 分别更新它。第一个解决方案需要一个二维数组,因此在这里不是最合适的。

最后给了我们类似的东西

def update(*val):
    a = a_slider.val
    k = k_slider.val
    parametric_plot.set_ydata(2 * k * np.sin(t) - a * np.sin(t * k))
    parametric_plot.set_xdata(2 * k * np.cos(t) - a * np.cos(t * k))

其他细微改进

  • 参数方程的定义出现两次:在 update 函数中和在显示初始化时。通过调用一次 update 可以避免初始化时的这种冗余。
  • 增加样本数量。
  • 调整 x 和 y 限制
a_init,k_init = 15,25
t = np.linspace(0,2 * np.pi,10000)

fig = plt.figure(figsize=(8,8))

## Main axes
ax = plt.axes([0.125,0.15,0.775,0.80])
plt.axis("equal")

parametric_plot,= plt.plot(0,c="royalblue") # do not define x and y
plt.xlim(-200,200)
plt.ylim(-200,200)

## Create sliders
ax_slider_a = plt.axes([0.125,0.03,0.03])
ax_slider_k = plt.axes([0.125,0.07,0.03])

a_slider = Slider(ax_slider_a,r"$a$",100,valinit=a_init)
k_slider = Slider(ax_slider_k,r"$k$",valinit=k_init,valstep=1)

def update(*args):
    a,k = a_slider.val,k_slider.val 
    parametric_plot.set_ydata(2 * k * np.sin(t) - a * np.sin(t * k))
    parametric_plot.set_xdata(2 * k * np.cos(t) - a * np.cos(t * k))

a_slider.on_changed(update)
k_slider.on_changed(update)

update()  # initialize the plot and thus avoid redundancies
plt.show()

enter image description here

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...