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))
        
        self.create_image()
        
        # Create the float view
        self._sc = Floatview(title='Floatview Output', mode='split-right')
        self._sl = IntSlider(description='Some slider')
        self._sl.observe(self._on_value_change)
        
        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
        """
        pass
    
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!
-Jon

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

1 Like