Black Lives Matter. Please consider donating to Black Girls Code today.

Update surface plot in a Jupyter Notebook?

Hi all,

Hoping it is not a trivial question. Based on a few examples (notably at https://mybinder.org/v2/gh/jonmmease/plotly_ipywidget_notebooks/master, notably notebooks/Interact.ipynb), I tried to following in a Jupyter notebook:

import numpy
import plotly.graph_objects
import ipywidgets

x = numpy.linspace(0,1,100)
y = numpy.linspace(0,1,100)
z = numpy.outer(x, y)

figure = plotly.graph_objects.FigureWidget()
surface = figure.add_surface(x=x, y=y, z=z)
figure.show()

@ipywidgets.interact(n=ipywidgets.widgets.IntSlider(min=1, max=10, step=1, value=1))
def update_figure(n):
    surface.data[0].z[:,:] = numpy.outer(x, y)**n
    figure.batch_update()

But unfortunately the figure is not updated. If I replace the last figure.batch_update() by figure.show() I get a second figure that gets updated, but that is not optimal. Is there a way to actually update the existing figure? Thank you so much for your help.

Martin

Hi @maaaaaaaartin

Here is a working code:

import numpy
import plotly.graph_objects as go
import ipywidgets as iw
n=1
x = numpy.linspace(0,1,50)
y = numpy.linspace(0,1,50)
z = numpy.outer(x, y)**n


fw = go.FigureWidget(go.Surface(x=x, y=y, z=z))
fw.layout.update(width=600, height=600)
#fw.show()

def surface_changed(change):
    new_z= numpy.outer(x, y)**slider.value
    fw.data[0].update(z = new_z)

slider = iw.IntSlider(value=1, min=1, max=10, step=1, description='n')
slider.layout = dict(margin='10px 80px 40px 5px', width='500px')
play_widget = iw.Play(value=1, min=1, max=10, step=1, interval=500)#the play_widget values are linked to IntSlider values
play_widget.layout = dict(margin='10px 10px 50px 100px')
iw.link((play_widget, 'value'), (slider, 'value'))
slider.observe(surface_changed, 'value')

iw.VBox([fw, iw.HBox([play_widget, slider])])