# How to merge Isosurface and Scatter3d in plotly frame?

**URL:** <https://community.plotly.com/t/how-to-merge-isosurface-and-scatter3d-in-plotly-frame/72934>\
**Category:** 📊 Plotly Python\
**Tags:** question\
**Created:** [February 22, 2023, 6:37am UTC](https://community.plotly.com/t/how-to-merge-isosurface-and-scatter3d-in-plotly-frame/72934 "2023-02-22T06:37:37Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![spataphore](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/spataphore/32/22939_2.png) [@spataphore](https://community.plotly.com/u/spataphore)\
**Post date:** [February 22, 2023, 6:37am UTC](https://community.plotly.com/t/how-to-merge-isosurface-and-scatter3d-in-plotly-frame/72934/1 "2023-02-22T06:37:37Z")

</div>

Using frames, I create an animation of the solar system with impending photon clusters. There was a problem when capturing objects on frames.

I create frames as a list ( **plotly.graph\_objects.Frame** ), passing two objects as the **data** parameter: **Scatter3d** and **Isosurface**. The problem is that for each frame, only the first transferred object is displayed in the **data** field of the **Frame** object.

```auto
frame = Frame(name='some name', data=[Scatter3d(...), Isosurface(...)], traces=[0])

```

In this case, only the **Scatter3d** object will be displayed on the frame. If you swap **data** objects, then **Isosurface** will be displayed, without **Scatter3d**.

Also, it turned out to add **Isosurface** separately from frames via **fig.add\_surface** , but this does not suit me, since each such object changes in time.

Can you suggest which way to look to solve the problem? If you need more information, I will provide. Thank you in advance.

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [February 22, 2023, 8:34am UTC](https://community.plotly.com/t/how-to-merge-isosurface-and-scatter3d-in-plotly-frame/72934/2 "2023-02-22T08:34:14Z")

</div>

Hi @spataphore welcome to the forums. I created a small sample figure based on the examples here:

> **[Intro](https://plotly.com/python/animations/)**
>
> Detailed examples of Intro to Animations including changing color, size, log axes, and more in Python.

```python
import plotly.graph_objects as go
import numpy as np

colors = ['aggrnyl', 'agsunset', 'algae', 'amp', 'armyrose', 'balance',
             'blackbody', 'bluered', 'blues', 'blugrn', 'bluyl', 'brbg',
             'brwnyl', 'bugn', 'bupu', 'burg', 'burgyl', 'cividis', 'curl',
             'darkmint', 'deep', 'delta', 'dense', 'earth', 'edge', 'electric',
             'emrld', 'fall', 'geyser', 'gnbu', 'gray', 'greens', 'greys',
             'haline', 'hot', 'hsv', 'ice', 'icefire', 'inferno', 'jet',
             'magenta', 'magma', 'matter', 'mint', 'mrybm', 'mygbm', 'oranges',
             'orrd', 'oryel', 'oxy', 'peach', 'phase', 'picnic', 'pinkyl',
             'piyg', 'plasma', 'plotly3', 'portland', 'prgn', 'pubu', 'pubugn',
             'puor', 'purd', 'purp', 'purples', 'purpor', 'rainbow', 'rdbu',
             'rdgy', 'rdpu', 'rdylbu', 'rdylgn', 'redor', 'reds', 'solar',
             'spectral', 'speed', 'sunset', 'sunsetdark', 'teal', 'tealgrn',
             'tealrose', 'tempo', 'temps', 'thermal', 'tropic', 'turbid',
             'turbo', 'twilight', 'viridis', 'ylgn', 'ylgnbu', 'ylorbr',
             'ylorrd']
 
scatter = [
    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'
    ) for _ in colors
]

surface = [
    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=cs
    ) for cs in colors
]

# create frames, beginning at index 1
frames = [go.Frame(data=[s, i]) for s, i in zip(scatter[1:], surface[1:])]

# create figure, use first traces for initial plot
fig = go.Figure(
    data=[scatter[0], surface[0]],
    layout=go.Layout(
        title="Start Title",
        updatemenus=[
            dict(
                type="buttons",
                buttons=[
                    dict(
                        label="Play",
                        method="animate",
                        args=[None]
                    )
                ]
            )
        ],
    ),
    frames=frames
)
fig.show()

```

After pressing the play button, you should see the Isosurface changing it’s colorscale and the scatter points changing their position randomly.

I hope this helps!

---

<div class="post-metadata">

**Author:** ![empet](https://avatars.discourse-cdn.com/v4/letter/e/977dab/32.png) [@empet](https://community.plotly.com/u/empet)\
**Post date:** [February 22, 2023, 12:25pm UTC](https://community.plotly.com/t/how-to-merge-isosurface-and-scatter3d-in-plotly-frame/72934/3 "2023-02-22T12:25:29Z")

</div>

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

```auto
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.

```auto
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]`.

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [February 22, 2023, 12:40pm UTC](https://community.plotly.com/t/how-to-merge-isosurface-and-scatter3d-in-plotly-frame/72934/4 "2023-02-22T12:40:31Z")

</div>

I almost never use animations, this was interesting. Thanks for the insight @empet

---

<div class="post-metadata">

**Author:** ![empet](https://avatars.discourse-cdn.com/v4/letter/e/977dab/32.png) [@empet](https://community.plotly.com/u/empet)\
**Post date:** [February 22, 2023, 1:41pm UTC](https://community.plotly.com/t/how-to-merge-isosurface-and-scatter3d-in-plotly-frame/72934/5 "2023-02-22T13:41:46Z")

</div>

A search with the keyword “anim” revealed the following examples:

> **[Plotly Community Forum](https://community.plotly.com/)**
>
> Plotly forum and Q/A site.

> [@Animation - two different plots using traces](https://community.plotly.com/t/animation-two-different-plots-using-traces/63984/2):
>
> @geosphere Here is an example of animating simultaneously and cumulatively a go.Barpolar and go.Bar, displayed in a subplot: import numpy as np import plotly.graph\_objects as go fig=go.Figure().set\_subplots(2,1, vertical\_spacing=0.05, specs=[[{"type": "polar"}], [{"type":"bar"}]]) r=[3.5, 1.5, 2.5, 4.5, 4.5, 4, 3] theta=[65, 15, 210, 110, 312.5, 180, 270] width=[20,15,10,20,15,30,15] x= np.arange(1, 8) bh = [4, 6, 3, 7, 8, 5, 9] fig.add\_trace(go.Barpolar(r=r[:…

[Plotly Community Forum - Join the Plotly Community Forum, an online discussion hub for interactive data apps, data science and analytics initiatives, and expert discussions.](https://community.plot.ly/t/multiple-lines-subplots-and-frames/28150)  
[Controlling animation speed using graph\_objects in python](https://community.plotly.com/t/controlling-animation-speed-using-graph-objects-in-python/41038)  
[Plotly Community Forum - Join the Plotly Community Forum, an online discussion hub for interactive data apps, data science and analytics initiatives, and expert discussions.](https://community.plot.ly/t/subplots-with-geo-rotation/29794)  
[Important update for Chart Studio users](https://chart-studio.plotly.com/~empet/15543)  
but there are also 3d animations.
