如何在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
相关产品推荐
相关产品推荐

