How to merge Isosurface and Scatter3d in plotly frame?

@spataphore @AIMPED The solution given by @AIMPED is a workaround, but not a typical way to update two or more traces in each frame.

import plotly.graph_objects as go
import numpy as np

colorscales = ['algae', 'balance',
                'deep', 'delta', 'dense',
              'ice', 'icefire', 'inferno', 'turbo', 'plasma']
             
 
fig = go.Figure([go.Scatter3d(
        x=np.random.randint(1,3,4), 
        y=np.random.randint(1,3,4), 
        z=np.random.randint(1,3,4), 
        mode='markers',
        marker_color=[0.5, 1, 0.75, 1.25],
       marker_colorscale="haline"
    ), go.Isosurface(
        x=[0,0,0,0,1,1,1,1],
        y=[1,0,1,0,1,0,1,0],
        z=[1,1,0,0,1,1,0,0],
        value=[1,2,3,4,5,6,7,8],
        isomin=2,
        isomax=6,
        colorscale="haline"
    )
])

# Each frame updates some attributes from scatter3d trace and other attributes from isosurface
# in this case it updates marker_colorscale, respectively isosurface colorscale
frames = [go.Frame(data=[go.Scatter3d(marker_colorscale=colorscales[k]), 
                         go.Isosurface(colorscale=colorscales[k])],
                   traces=[0,1]) for k in range(len(colorscales))]

fig.update(frames=frames)
fig.update_layout( width=600, height=600,
                  scene_camera_eye=dict(x=1.5, y=1.5, z=1),
        title="Your title",
        updatemenus=[
            dict(
                type="buttons",
                buttons=[
                    dict(
                        label="Play",
                        method="animate",
                        args=[None]
                    )
                ]
            )
        ],
    )

Note that in each frame one updates only attributes from the first and the second trace that are changimg from frame to frame.

trace=[0,1]

in a frame definition tells to plotly.js that the first update from
a frame is for the fig.data[0], while the second update is for fig.data[1].

1 Like