You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Plotly JS中同步多场景3D散点图的相机视角?

实现Plotly多3D场景的相机视角同步旋转

要实现旋转任意一个3D散点图时同步所有图的相机视角,你可以通过监听Plotly的plotly_relayout事件,捕获当前场景的相机参数并同步到其他场景。以下是修改后的完整可运行代码:

<!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' },
        camera: {
            eye: { x: 1.25, y: 1.25, z: 1.25 }
        }
    };

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

    // Layout with scenes
    var layout = {
        width: 800,
        height: 400,
        title: '3D Scatter Plots with Synced Camera',
        scenes: [scene1, scene2] // Specify the scenes
    };

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

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

    // 标记是否正在同步视角,避免循环触发事件
    let isSyncing = false;

    // 监听relayout事件
    container.addEventListener('plotly_relayout', function(event) {
        if (isSyncing) return;

        // 找到触发事件的场景ID
        let targetSceneId = null;
        const cameraKeys = Object.keys(event).filter(key => key.includes('camera.eye'));
        if (cameraKeys.length > 0) {
            targetSceneId = cameraKeys[0].split('.')[0];
        }

        if (!targetSceneId) return;

        // 获取当前场景的相机参数
        const cameraParams = {};
        Object.keys(event).forEach(key => {
            if (key.startsWith(`${targetSceneId}.camera`)) {
                const newKey = key.replace(`${targetSceneId}.`, '');
                cameraParams[newKey] = event[key];
            }
        });

        isSyncing = true;

        // 同步到其他场景
        const sceneIds = ['scene1', 'scene2'];
        sceneIds.forEach(sceneId => {
            if (sceneId !== targetSceneId) {
                const update = {};
                Object.keys(cameraParams).forEach(key => {
                    update[`${sceneId}.${key}`] = cameraParams[key];
                });
                Plotly.relayout(container, update);
            }
        });

        isSyncing = false;
    });
</script>

</body>
</html>

关键实现说明:

  • 事件监听:通过监听容器的plotly_relayout事件,捕获用户对3D场景的旋转操作(该事件会在相机视角变化时触发)。
  • 避免循环触发:使用isSyncing变量标记同步状态,防止在更新其他场景时再次触发事件,造成循环。
  • 参数提取与同步:从事件对象中提取触发场景的相机参数,然后将这些参数逐一应用到其他场景的相机配置中,实现视角同步。

内容的提问来源于stack exchange,提问作者nluigi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:17:07