How to update a shown figure in Jupyter notebook?

I would like to dynamically modify a figure after it has been shown in a jupyter notebook. Ideally this could be done in a single cell, but manipulating a figure in a following cell would work as well.

Currently if I try to call ‘add_traces’ on a figure in a cell following an initial call to .show() I get a new figure displayed. If I do this in a loop N times with a sleep between calls I get N new figures.

The messages system seems to imply that python should be able to communicate with an existing JS frontend, but I don’t seem to be able to get this to work in a notebook.

Is this possible and, if so, how would I accomplish this?

Thanks for any help or pointers!

@iandanforth

In order to stop displaying a new figure after each update, just add a semicolon at the end of an update line:

import plotly.graph_objects as go
import numpy as np


trace = dict(
            x=np.arange(8),
            y=-1.5*np.random.rand(8),
            line=dict(color='magenta'))

fig = go.Figure([trace])
fig.show()
for  k in range(N):
      fig.add_trace(...);   
fig.show()        

In this case you displayed the initial figure and the final one, resulted after all updates.

But if you want to display just one figure, define it as an instance of go.FigureWidget, and each update can be seen on the initially displayed figure:

fig  = go.FigureWidget([trace])
fig
for  k in range(N):
      fig.add_trace(...);   

That doesn’t make a lot of sense to me, can you elaborate please? The semi-colon is only needed if the add_trace() call is the last call in a notebook cell.

Hi @empet

What should I do if I want Update my data using update_traces if a loop and then update same figure without plotting new plots and implement changes on the initial figure?

Hi

What can I do to prevent plotting new figure and my new data be plotted on previous figure?

import plotly.graph_objects as go

fig = go.FigureWidget();

fig.add_trace(go.Bar(x=[1, 2, 3], y=[1, 3, 2]));

fig.show();

fig.update_traces(go.Bar(x=[4, 1, 6], y=[2, 5, 4]));

fig.show();

This is what I get, But I want only the first plot remain and get updated and prevent plotting new figure!

@Bijan
It seems that you want to animate the bar plot updates using FigureWidget.
Here is an example you can adapt to your needs:

import plotly.graph_objects as go
import numpy as np
import ipywidgets as iw
fw = go.FigureWidget();

fw.add_trace(go.Bar(x=[1, 2, 3], y=[1, 3, 2]));

N=10
test_data = np.random.randint(2, 8, (3, N))
ymax = test_data.max()
fw.update_yaxes(range=[0, ymax+0.5])
slider = iw.IntSlider(value=1, min=1, max=N, step=1, description='Step')
slider.layout = dict(margin='12px 80px 40px 5px', width='700px')#margin represents top, right, bottom, left distances
def step_changed(change):
    fw.data[0].y = test_data[:, slider.value-1]
    
slider.observe(step_changed, 'value')  
play_button = iw.Play(value=1, min=1, max=N,  interval=225)
play_button.layout = dict(margin='12px 10px 50px 100px')
iw.link((play_button, 'value'), (slider, 'value'))
iw.VBox([fw, iw.HBox([play_button, slider])])#from slider to plot

Please don’t address questions within old threads, and don’t address them directly ( as you did with @empet, and Jon Mease on plotly.py). Just open a new thread and wait for answer from someone who is available.

1 Like