how to sync 3d graphs in plotly JS?

24 views Asked by At

I have multiple 3D scatter graphs setup using scenes.
How can I sync the camera when rotating either graph?

MWE:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <title>Plotly Scenes Example</title>
</head>
<body>

<div id="subplot-container" style="width: 800px; height: 400px;"></div>

<script>
    // Sample data for the first scatter plot
    var trace1 = {
        x: [1, 2, 3],
        y: [4, 5, 6],
        z: [7, 8, 9],
        mode: 'markers',
        type: 'scatter3d',
        name: 'Scatter Plot 1',
        scene: 'scene1' // Assign the trace to a specific scene
    };

    // Sample data for the second scatter plot
    var trace2 = {
        x: [10, 11, 12],
        y: [13, 14, 15],
        z: [16, 17, 18],
        mode: 'markers',
        type: 'scatter3d',
        name: 'Scatter Plot 2',
        scene: 'scene2' // Assign the trace to a specific scene
    };

    // Create scenes
    var scene1 = {
        domain: {
            x: [0, 0.5],
            y: [0, 1]
        },
        xaxis: { title: 'X Axis' },
        yaxis: { title: 'Y Axis' },
        zaxis: { title: 'Z Axis' },
    };

    var scene2 = {
        domain: {
            x: [0.5, 1],
            y: [0, 1]
        },
        xaxis: { title: 'X Axis' },
        yaxis: { title: 'Y Axis' },
        zaxis: { title: 'Z Axis' },
    };

    // Layout with scenes
    var layout = {
        scene: {
            aspectmode: 'cube',
            xaxis: { title: 'X Axis' },
            yaxis: { title: 'Y Axis' },
            zaxis: { title: 'Z Axis' },
        },
        width: 800,
        height: 400,
        title: '3D Scatter Plots with Scenes',
        scenes: [scene1, scene2] // Specify the scenes
    };

    // Combine the data traces into an array
    var data = [trace1, trace2];

    // Create the subplot with scenes
    Plotly.newPlot('subplot-container', data, layout);
</script>

</body>
</html>
1

There are 1 answers

0
nluigi On

By checking on plotly_relayout event and passing the camera value to each scene

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <title>Plotly Scenes Example</title>
</head>
<body>

<div id="subplot-container" style="width: 800px; height: 400px;"></div>

<script>
    // Sample data for the first scatter plot
    var trace1 = {
        x: [1, 2, 3],
        y: [4, 5, 6],
        z: [7, 8, 9],
        mode: 'markers',
        type: 'scatter3d',
        name: 'Scatter Plot 1',
        scene: 'scene1' // Assign the trace to a specific scene
    };

    // Sample data for the second scatter plot
    var trace2 = {
        x: [10, 11, 12],
        y: [13, 14, 15],
        z: [16, 17, 18],
        mode: 'markers',
        type: 'scatter3d',
        name: 'Scatter Plot 2',
        scene: 'scene2' // Assign the trace to a specific scene
    };

    // Create scenes
    var scene1 = {
        domain: {
            x: [0, 0.5],
            y: [0, 1]
        },
        xaxis: { title: 'X Axis' },
        yaxis: { title: 'Y Axis' },
        zaxis: { title: 'Z Axis' },
    };

    var scene2 = {
        domain: {
            x: [0.5, 1],
            y: [0, 1]
        },
        xaxis: { title: 'X Axis' },
        yaxis: { title: 'Y Axis' },
        zaxis: { title: 'Z Axis' },
    };

    // Layout with scenes
    var layout = {
        scene: {
            aspectmode: 'cube',
            xaxis: { title: 'X Axis' },
            yaxis: { title: 'Y Axis' },
            zaxis: { title: 'Z Axis' },
        },
        width: 800,
        height: 400,
        title: '3D Scatter Plots with Scenes',
        scenes: [scene1, scene2] // Specify the scenes
    };

    // Combine the data traces into an array
    var data = [trace1, trace2];

    // Create the subplot with scenes
    var gd = document.getElementById('subplot-container')
    Plotly.newPlot(gd, data, layout);

    function handleRelayout(event){
                            
        console.log(event);
        const [key, value] = Object.entries(event)[0];
                            
        let update = {
            'scene.camera': value,
            'scene2.camera': value
        }
        //Plotly.relayout(gd, update) // don't use, will cause infinite loops
        Plotly.update(gd, {}, update);
                            
    }
    
    gd.on('plotly_relayout', handleRelayout);
    
</script>

</body>
</html>