Bring Drag & Drop to Dash with Dashboard Engine. 💫 Learn how at our next webinar!

Synchronizing 3D plot camera views/zoom in Dash

I have two 3d plots with identical data points (different colors). Here is what I am thinking in terms of code to synchronize the two:

Where the function is the same for each one, so that whichever plot I rotate/zoom/pan/etc., the other matches. Is this acceptable or am I making a mistake?

Hello @pcicales,

I want to do the same,
Did you find any solution ?

Hello, please find below an example synchronizing two 3d figures

I was not sure of how this code would behave since the graph of callbacks has a loop (whn you update fig1 it updates fig2 which should update fig1 etc) but it behaves nicely.

import dash
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
import numpy as np


app = dash.Dash(__name__)

X, Y, Z = np.random.random((3, 50))


app.layout = html.Div([
        dcc.Graph(
            id='main-figure',
            figure=go.Figure(data=go.Scatter3d(x=X, y=Y, z=Z))
            ),
        dcc.Graph(
            id='other-figure',
            figure=go.Figure(data=go.Scatter3d(x=X, y=Y, z=Z))
            ),

        ]
        )

@app.callback(
    Output('other-figure', 'figure'),
    [Input('main-figure', 'relayoutData')])
def sync1(data):
    if data and 'scene.camera' in data:
        fig=go.Figure(data=go.Scatter3d(x=X, y=Y, z=Z))
        fig.update_layout(scene_camera=data['scene.camera'])
        return fig
    else:
        raise PreventUpdate


@app.callback(
    Output('main-figure', 'figure'),
    [Input('other-figure', 'relayoutData')])
def sync2(data):
    if data and 'scene.camera' in data:
        fig=go.Figure(data=go.Scatter3d(x=X, y=Y, z=Z))
        fig.update_layout(scene_camera=data['scene.camera'])
        return fig
    else:
        raise PreventUpdate


if __name__ == '__main__':
    app.run_server(debug=True, port=8065)

2 Likes

@Emmanuelle Thank you so much !

And what if we have 3 graphs instead of 2.

For example if one of three change the 2 others update

Then you can use a multi-output callback like described in https://dash.plot.ly/getting-started-part-2 (search for “multiple outputs”).

1 Like

Hello! I’m trying to do the same, except on subplot: I have a variable number of 3D scatters in the same figure through make_subplots. How could I synchronize the cameras so that if I move any of them they all move the same?

Thank you