简体   繁体   English

如何将滑块与动画结合?

[英]How to combine a slider with an animation?

Using matplotlib.animation and matplotlib.widgets (sliders and buttons), I wanted to create an animated simulation of a distribution (starting from a sample and ending in a big one), which takes as input from the user the parameters of the distribution using widgets. 我想使用matplotlib.animation和matplotlib.widgets(滑块和按钮),来创建一个分布的动画模拟(从一个样本开始到一个大样本结束),该模拟将来自用户的分布参数用作小部件。 This is my code: 这是我的代码:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
from matplotlib.widgets import Slider, Button

#create fig
fig,((ax1,ax2))=plt.subplots(2,1,sharex=True)
fig.suptitle("Sampling of Distributions\n\n(Parametrize and then run)", fontsize="x-large")

#animation function
def update(curr):
    # check if animation is at the last frame, and if so, stop the animation 
    if curr*100+100 == n: 
        a.event_source.stop()

    plt.subplot(2, 1, 1)
    plt.cla()
    plt.axis([np.round(np.percentile(x1,.05)),np.round(np.percentile(x1,99.5)),0,1])   #plot 99% cuantile
    plt.hist(x1[:curr*100+100], normed=True, bins=20, alpha=0.5)
    plt.gca().set_title('\n\nNormal n={}'.format(curr*100+100))


#sliders axis
ax2=plt.subplot(2, 1, 2)             
ax2.axis('off')
ax2.set_title('\nParametrize Normal Distribution')
axis_color = 'lightgoldenrodyellow'
E0_slider_ax = fig.add_axes([0.13, .22, 0.3, 0.02], axisbg=axis_color)
E1_slider_ax = fig.add_axes([0.13, .17, 0.3, .02], axisbg = axis_color)
E0_slider = Slider(E0_slider_ax, r'Normal $\mu$', valmin = -5, valmax = 5, valinit = -2.5)
E0_slider.label.set_size(15)
E1_slider = Slider(E1_slider_ax, r'Normal $\sigma$', 0, 5, valinit = 1)
E1_slider.label.set_size(15)

#generate random numbers with slider values
def slider_on_change(val):   #generate the random numbers 
    x1 = np.random.normal(E0_slider.val, E1_slider.val, n)
E0_slider.on_changed(slider_on_change)
E1_slider.on_changed(slider_on_change)

#create animation start button
def animate_button(self):
    a = animation.FuncAnimation(fig, update, frames=100,interval=100)
    plt.Figure.canvas.show()

#animation button
axnext = fig.add_axes([0.785, 0.02,0.1, 0.075], axisbg = axis_color)
bnext = Button(axnext, 'Run Simulations!')
bnext.on_clicked(animate_button)


plt.show()

The slider is created but the animation never starts. 滑块已创建,但动画从未开始。 Could please provide me some clues? 能给我一些线索吗?

在此处输入图片说明

The order of operations is a little off and some variables are not accessible as this is written. 操作顺序略有偏离,并且某些变量在编写时无法访问。 For example n is never defined. 例如,从未定义n I went ahead and set it to 5000 to draw a pretty reasonably sized distribution. 我继续将其设置为5000,以绘制相当合理的分布。 You also don't explicitly need to do anything when the slider is changed, but rather reference the value of the sliders within update . 更改滑块后,您也无需明确地执行任何操作,而是在update内引用滑块的值。 Something like this should work. 这样的事情应该起作用。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
from matplotlib.widgets import Slider, Button

#create fig
fig,((ax1,ax2))=plt.subplots(2,1,sharex=True)
fig.suptitle("Sampling of Distributions\n\n(Parametrize and then run)", fontsize="x-large")

#sliders axis
ax2=plt.subplot(2, 1, 2)             
ax2.axis('off')
ax2.set_title('\nParametrize Normal Distribution')
axis_color = 'lightgoldenrodyellow'
E0_slider_ax = fig.add_axes([0.13, .22, 0.3, 0.02], axisbg=axis_color)
E1_slider_ax = fig.add_axes([0.13, .17, 0.3, .02], axisbg = axis_color)
E0_slider = Slider(E0_slider_ax, r'Normal $\mu$', valmin = -5, valmax = 5, valinit = -2.5)
E0_slider.label.set_size(15)
E1_slider = Slider(E1_slider_ax, r'Normal $\sigma$', 0, 5, valinit = 1)
E1_slider.label.set_size(15)

#animation function
def update(curr, x1):
    plt.subplot(2, 1, 1)
    plt.cla()


    plt.axis([np.round(np.percentile(x1,.05)),np.round(np.percentile(x1,99.5)),0,1])   #plot 99% cuantile
    plt.hist(x1[:curr*100+100], normed=True, bins=20, alpha=0.5)
    plt.gca().set_title('\n\nNormal n={}'.format(curr*100+100))

#create animation start button
def animate_button(self):
    x1 = np.random.normal(E0_slider.val, E1_slider.val, 5000)
    a = animation.FuncAnimation(fig, update, , fargs=(x1, ), frames=100,interval=500, repeat=False)
    fig.canvas.draw()

#animation button
axnext = fig.add_axes([0.785, 0.02,0.1, 0.075], axisbg = axis_color)
bnext = Button(axnext, 'Run Simulations!')
bnext.on_clicked(animate_button)

plt.show()

Upon clicking the Run Simulation button it creates x1 based on the set values of mu and sigma. 单击“ Run Simulation按钮后,它将基于mu和sigma的设置值创建x1 For each iteration it draws a sample of size iteration_num * 100 + 100 and plots the updated distribution. 对于每次迭代,它都会绘制一个大小为iteration_num * 100 + 100的样本,并绘制更新后的分布。 The process stops and does not repeat after 100 iterations. 该过程停止,并且在100次迭代后不再重复。 This is an image of the last frame. 这是最后一帧的图像。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM