By using this answer to produce a LiveGraph and this answer to update variables to a thread, I was able to generate a graph that updates itself each second and whose amplitude is determined by a slider (code below). Both answers were incredibly helpful!
%matplotlib notebook
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from threading import Thread, Lock
import time
import ipywidgets as widgets
from IPython.display import display
import numpy as np
'''#################### Live Graph ####################'''
# Create a new class which is a live graph
class LiveGraph(object):
def __init__(self, baseline):
self.x_data, self.y_data = [], []
self.figure = plt.figure()
self.line, = plt.plot(self.x_data, self.y_data)
self.animation = FuncAnimation(self.figure, self.update, interval=1200)
# define variable to be updated as a list
self.baseline = [baseline]
self.lock = Lock()
self.th = Thread(target=self.thread_f, args = (self.baseline,), daemon=True)
# start thread
self.th.start()
def update_baseline(self,baseline):
# updating a list updates the thread argument
with self.lock:
self.baseline[0] = baseline
# Updates animation
def update(self, frame):
self.line.set_data(self.x_data, self.y_data)
self.figure.gca().relim()
self.figure.gca().autoscale_view()
return self.line,
def show(self):
plt.show()
# Function called by thread that updates variables
def thread_f(self, base):
x = 0
while True:
self.x_data.append(x)
x += 1
self.y_data.append(base[0])
time.sleep(1)
'''#################### Slider ####################'''
# Function that updates baseline to slider value
def update_baseline(v):
global g
new_value = v['new']
g.update_baseline(new_value)
slider = widgets.IntSlider(
value=10,
min=0,
max=200,
step=1,
description='value:',
disabled=False,
continuous_update=False,
orientation='horizontal',
readout=True,
readout_format='d'
)
slider.observe(update_baseline, names = 'value')
'''#################### Display ####################'''
display(slider)
g = LiveGraph(slider.value)
Still, I would like to put the graph inside a bigger interface which has other widgets. It seems that I should put the LiveGraph inside the Output widget, but when I replace the 'Display section' of my code by the code shown below, no figure is displayed.
out = widgets.Output(layout={'border': '1px solid black'})
with out:
g = LiveGraph(slider.value)
vbox = widgets.VBox([slider,out], align_self='stretch',justify_content='center')
vbox
Is there a way to embed this LiveGraph in the output widget or in a box widget?