滑块更新时绘图不刷新 matplotlib



我不明白为什么当滑块更新时情节不刷新。我使用的是木星笔记本,我选择了带有'nbAgg'参数的后端。

初始化代码:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import use as m_use
from matplotlib.widgets import Slider
m_use('nbAgg')
x1 = np.random.normal(-2.5, 1, 10000)
x2 = np.random.gamma(2, 1.5, 10000)
x3 = np.random.exponential(2, 10000)+7
x4 = np.random.uniform(14,20, 10000)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2,figsize=(7, 5))
plt.subplots_adjust(left=0.1,right=.8)

有一个动画包含了这个函数:

def updateData(curr,divider=7):
global ax1, ax2, ax3, ax4
for ax in (ax1, ax2, ax3, ax4):
ax.cla()
if curr <= 679 :
my_b = int(np.around(curr/divider)+3)
else : my_b = 100

multi = 100
ax1.hist(x1[:curr*multi],bins=my_b)
ax2.hist(x2[:curr*multi],bins=my_b)
ax3.hist(x3[:curr*multi],bins=my_b)
ax4.hist(x4[:curr*multi],bins=my_b)
fig.suptitle('Frame {} on 100'.format((curr+1)))
return None

动画

simulation = animation.FuncAnimation(fig=fig, func=updateData, frames=10,
blit=False, interval=1, repeat=False)

这个滑块卡住了我:

slider_ax = plt.axes([.9, 0.45, 0.01, 0.3])
slider = Slider(ax=slider_ax,label='Divider nfor bins',valmin=1,valmax=15, valinit=7, orientation='vertical',valfmt='%.0f',track_color='black',facecolor='red',
handle_style={'facecolor':'k','edgecolor':'#86a2cf','size':20})
def update():

anim_2 = animation.FuncAnimation(fig=fig, func=updateData, frames=20,
blit=False, interval=1, repeat=False)    

下面的函数没有按预期工作:

slider.on_changed(update)
simulation = animation.FuncAnimation(fig=fig, func=updateData, frames=10,
blit=False, interval=1, repeat=False)
plt.show()

您可以尝试以下操作:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.widgets import Slider
from ipywidgets import interact
import ipywidgets as widget
%matplotlib widget
x1 = np.random.normal(-2.5, 1, 10000)
x2 = np.random.gamma(2, 1.5, 10000)
x3 = np.random.exponential(2, 10000) + 7
x4 = np.random.uniform(14, 20, 10000)
(fig, ((ax1, ax2), (ax3, ax4))) = plt.subplots(2, 2, figsize=(7, 5))
plt.subplots_adjust(left=0.1, right=.8)
divider = 7
def updateData(curr):
global ax1, ax2, ax3, ax4, divider
for ax in (ax1, ax2, ax3, ax4):
ax.cla()
if (curr <= 679):
my_b = int(np.around(curr / divider) + 3)
else:
my_b = 100
multi = 100
ax1.hist(x1[:curr * multi], bins=my_b)
ax2.hist(x2[:curr * multi], bins=my_b)
ax3.hist(x3[:curr * multi], bins=my_b)
ax4.hist(x4[:curr * multi], bins=my_b)
fig.suptitle('Frame {} on 100'.format(curr + 1))
plt.tight_layout()
def update(val):
global divider
divider = val
anim_2 = animation.FuncAnimation(fig=fig, func=updateData, frames=20, blit=False, interval=1, repeat=False)
fig.canvas.draw()
slider = interact(update, val=widget.IntSlider(min=1, max=15, value=7))
simulation = animation.FuncAnimation(fig=fig, func=updateData, frames=10, blit=False, interval=1,repeat=False)
display(slider)

注意事项:

  • 要在Jupyter Notebook中使用matplotlib绘制交互式图形,您需要安装ipympl,然后您可以使用魔术函数%matplotlib widget在Jupyter Notebook中绘制交互式matplotlib图形。

  • 一旦动画存储在变量中,要更新图形,您需要调用fig.canvas.draw()来重新绘制图形。

  • 你的实现没有使用(更新)滑块值作为函数update的参数,因为update不需要任何参数来工作。然而,小部件通常用于调用带参数的函数。例如,检查如何在Jupyter Notebook中提供一个接口,以调用具有不同参数值的相同函数。

    鉴于此,我修改了update函数,该函数采用滑块值来更新全局变量divider的值。

这意味着,当使用FuncAnimationframes作为整数调用updateData函数时,updateData将使用range(frames)的值重复调用。这意味着,每次FuncAnimation调用updateData时,curr将从range(frames)获取一个值。

最新更新