Update an image

I am loading in a multi-slice image (3D) and would like to create a slider bar to rotate through the images.

The code below is what I cobbled together for jupyter lab with plotly. I am not sure which thing must be updated in order to update the image. Some form of this would go into the call back, but I was trying to figure it out first, before I put it in the callback.

data = v._gofig['data']
td = v._3d_data[10]
data[0].update({'z':  td})

# Is this needed?  But doesn't seem to update the image data either.
#v._gofig.update({'data': data})

Is it he data[0] on which I call the update method, or the _gofig that I call the update. Neither seem to update the image. I do have a working example for a 1D plot so I know generally it should work.

Any guidance for a new person would be greatly appreciated.

from floatview import Floatview
from ipywidgets import IntSlider
import ipywidgets
import matplotlib.pyplot as p
import numpy as np
import plotly.graph_objs as go

class Viewer:
    def __init__(self):
        # Load the data
        self._3d_data = np.random.random((100,50,50))
        # Create the float view
        self._sc = Floatview(title='Floatview Output', mode='split-right')
        self._sl = IntSlider(description='Some slider')
        self._fig = go.FigureWidget(self._gofig)
        with self._sc:
            display(ipywidgets.widgets.VBox([self._fig, self._sl]))
    def create_image(self):
        self._trace1 = {
          "x": np.arange(50),
          "y": np.arange(50), 
          "z": self._3d_data[0], 
          "showlegend": False, 
          "type": "heatmap"
        self._data = go.Data([self._trace1])
        layout = {
          "legend": {
            "x": 1, 
            "y": 0.5, 
            "bgcolor": "rgb(255,255,255)"
          "margin": {"r": 10}, 
          "paper_bgcolor": "rgb(255,255,255)", 
          "plot_bgcolor": "rgb(229,229,229)", 
          "showlegend": True, 
          "xaxis": {
            "gridcolor": "rgb(255,255,255)", 
            "showgrid": True, 
            "showline": False, 
            "showticklabels": True, 
            "tickcolor": "rgb(127,127,127)", 
            "ticks": "outside", 
            "title": "x", 
            "type": "linear", 
            "zeroline": False
          "yaxis": {
            "gridcolor": "rgb(255,255,255)", 
            "showgrid": True, 
            "showline": False, 
            "showticklabels": True, 
            "tickcolor": "rgb(127,127,127)", 
            "ticks": "outside", 
            "title": "y", 
            "type": "linear", 
            "zeroline": False
        self._gofig = go.Figure(data=self._data, layout=layout)

    def _on_value_change(self, change):
        Int slider call back
v = Viewer()

Hi @brechmos,

Looking at this line

self._fig = go.FigureWidget(self._gofig)

I think the issue is that you need to call .update on self._fig.data[0] rather than on self._gofig['data']. The reason is that the constructors of the graph_objs objects copy their inputs, so to make inline updates or to install callbacks you need to pull the object out of the FigureWidget instance.

Hope that helps!

NIce! Thank you. That is exactly what I needed.

1 Like