I have the following simple exmample of animation across subplots and now I am trying to make it interactive. When I changes the parameters via interaction I have know it is calling run
because my print statement is outputing the new values. However the chart doesn't redraw.
%matplotlib widget
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
from ipywidgets import interact
import ipywidgets as widgets
#sample from a bunch of distributions
def sample(n):
x1 = np.random.normal(0, 1, n)
x2 = np.random.normal(0, 4, n)
return (x1,x2)
# a function that binds data to outer function and holds them in closure to the
# high-order "update" function returned whcih is called for each animation frame
def bind_update(sample1, sample2, ax1, ax2, batch=1):
def update(curr):
if ((curr % batch) != 0):
return
ax1.clear()
ax1.set_xlim(np.min(sample1), np.max(sample1))
ax1.set_title(f'Sample 1')
ax1.hist(sample1[:curr], density=True, bins=20, alpha=0.5)
ax2.clear()
ax2.set_xlim(np.min(sample2), np.max(sample2))
ax2.set_title('Sample 2')
ax2.hist(sample2[:curr], density=True, bins=20, alpha=0.5)
return update
@interact(
interval=widgets.RadioButtons(
options=[5, 50, 100],
value=5,
description='refresh interval:',
disabled=False
),
batch=widgets.RadioButtons(
options=[5, 10, 50, 100],
value=100,
description='batch size:',
disabled=False
),
n=widgets.IntSlider(
value=300,
min=1,
max=1000,
step=1,
description='Number of Smaples:',
disabled=False,
continuous_update=False,
orientation='horizontal',
readout=True,
readout_format='d'
)
)
def run(n, interval, batch):
print('run', n, interval, batch)
# set up figure and subplots
fig, ((ax1,ax2)) = plt.subplots(1, 2, sharex=False, sharey=False)
# I have tried these commands below in this space.
# fig.clf(), fig.clear(), ax1.clear()
fig.suptitle('Working with subplots', fontsize=15)
fig.text(0.5, 0.04, 'Value', ha='center', fontsize=13)
fig.text(0.04, 0.5, 'Frequency', va='center', rotation='vertical', fontsize=13)
# adjust spacing
plt.subplots_adjust(left=0.15, top=0.85, bottom=0.15, wspace=0.4, hspace=0.4)
# bind data and axis to the update function
(x1,x2) = sample(n)
my_update = bind_update(x1, x2, ax1, ax2, batch=batch)
# test the update function
# my_update(n)
# kick off animation
return animation.FuncAnimation(
fig,
my_update,
frames=n+1,
interval=interval,
repeat=False);
It looks as though a solution is to move this line outside of the function definition:
# set up figure and subplots
fig, ((ax1,ax2)) = plt.subplots(1, 2, sharex=False, sharey=False)
why is that a solution?