如何在Plotly.js的3D图表中实现多坐标轴?
Hey there! Great question—Plotly doesn’t have native support for dual Z-axes in 3D charts like it does for 2D, but we can use overlapping 3D scenes (subplots) to replicate that exact effect you’re aiming for. Let me walk you through a step-by-step solution that works:
Core Idea: Overlapping Scenes
The trick is to create two identical 3D scenes that occupy the entire plot area, share the same X/Y axes and camera perspective, but display separate Z-axes. One scene will handle your first dataset (with its own Z-axis), and the second will handle the second dataset (with a distinct Z-axis placed on the opposite side).
Step-by-Step Code Example
Here’s a working Plotly.js implementation using scatter3d traces—this translates easily to other 3D trace types like surface or mesh3d too:
// Sample datasets (same X/Y, different Z scales) const xVals = [1, 2, 3, 4, 5]; const yVals = [1, 2, 3, 4, 5]; const zDataset1 = [10, 20, 30, 40, 50]; // Larger scale const zDataset2 = [0.1, 0.2, 0.3, 0.4, 0.5]; // Smaller scale // First trace (uses default "scene") const trace1 = { x: xVals, y: yVals, z: zDataset1, type: "scatter3d", mode: "markers", marker: { color: "#1f77b4", size: 8 }, name: "Dataset 1" }; // Second trace (uses "scene2") const trace2 = { x: xVals, y: yVals, z: zDataset2, type: "scatter3d", mode: "markers", marker: { color: "#ff7f0e", size: 8 }, name: "Dataset 2", scene: "scene2" // Assign to second scene }; // Layout configuration to overlap scenes const layout = { width: 800, height: 600, // Configure main scene (shows X/Y/Z1 axes) scene: { xaxis: { range: [0, 6], title: "X Axis" }, yaxis: { range: [0, 6], title: "Y Axis" }, zaxis: { title: "Z Axis 1 (Large Scale)", side: "left" }, domain: { x: [0, 1], y: [0, 1] } // Occupy full plot area }, // Configure second scene (hides X/Y, shows Z2 axis) scene2: { xaxis: { visible: false }, // Hide duplicate X axis yaxis: { visible: false }, // Hide duplicate Y axis zaxis: { title: "Z Axis 2 (Small Scale)", side: "right" }, domain: { x: [0, 1], y: [0, 1] }, // Overlap with main scene camera: { eye: { x: 1.25, y: 1.25, z: 1.25 } // Match camera to main scene } }, legend: { x: 0.05, y: 0.95 } }; // Render the plot Plotly.newPlot("3d-dual-z", [trace1, trace2], layout);
Key Details to Get Right
- Camera Alignment: Make sure
scene2uses the exact same camera position asscene—otherwise, the two datasets will look misaligned when rotating the plot. - Axis Visibility: Hide the X/Y axes of the second scene to avoid clutter.
- Z-Axis Placement: Use the
sideproperty ("left"vs"right") to position the two Z-axes on opposite sides of the plot for clarity. - Domain Matching: Set both scenes’
domainto[0,1]for X and Y so they fully overlap.
Alternative: Custom Scaled Z-Axis (For Static Visuals)
If you don’t need interactive zoom/pan for both Z-axes, you could also:
- Scale one of your Z datasets to match the range of the other.
- Add custom tick labels to a secondary Z-axis using annotations.
- Draw vertical reference lines to link the scaled values to their original scale.
This method is simpler but lacks the full interactivity of the overlapping scenes approach.
内容的提问来源于stack exchange,提问作者Pierre GUILLAUME

