
可视化官方
Skill 文件
Skill
references
preview.html
SKILL.md
SKILL.md
| name | plotly-3d-vis |
|---|---|
| title | Plotly.js 3D 可视化组件 |
| description | 当用户需要交互探索科学或工程三维数据,或明确要求 Plotly.js 3D 时,使用此 Skill。该库擅长:3D 散点图、3D 带状图、3D 曲面图、3D 网格图、3D 折线图、三角曲面图、3D 聚类图、3D 向量锥图、3D 流管图、3D 等值面图。不要用于 Three.js 模型与动画场景,也不要用于只需立体柱状图、饼图等展示型商业图表。 |
Plotly.js 3D 可视化组件库
当你需要创建基于 Plotly.js 的 3D 图表时,使用此技能来正确配置和渲染各种类型的 3D 可视化组件。
核心图类型
Plotly.js 支持以下 3D 图表类型,每种对应不同的数据可视场景:
1. 3D Scatter (散点图)
用途: 三维空间中的点云分布、聚类分析、科学数据可视化
javascript
type: 'scatter3d',mode: 'markers' // 'markers' | 'lines' | 'lines+markers'关键属性:
x,y,z: 三轴坐标数组marker.size: 点大小marker.color: 单颜色或根据值映射的颜色数组marker.symbol: 标记形状 ('circle', 'square', 'diamond', 'cross')marker.opacity: 透明度 (0-1)line.width,line.color: 连线样式(当 mode 包含 'lines' 时)
典型场景: 分子结构、空间定位数据、三维聚类
2. 3D Surface (曲面图)
用途: 地形高程、函数曲面、热力图的三维表达
javascript
type: 'surface'关键属性:
z: 二维数组,表示 Z 轴高度值colorscale: 高度映射的颜色梯度,如 'Viridis', 'Jet', 'Hot', 'Greys'contours.z.show: 是否显示等高线contours.z.project.z: 是否在 Z 轴平面投影等高线opacity: 曲面透明度showscale: 是否显示颜色标尺
典型场景: 地形图、数学函数可视化、热力学曲面
3. 3D Mesh (三角网格图)
用途: 三维模型、不规则表面、科学计算网格
javascript
type: 'mesh3d'关键属性:
x,y,z: 所有顶点的坐标数组i,j,k: 三角形三个顶点的索引(定义三角面)color: 网格颜色vertexcolor: 每个顶点的颜色opacity: 透明度flatshading: 是否使用平面着色lighting: 光照配置(ambient, diffuse, specular, roughness)
典型场景: 3D 模型、有限元分析结果、地形网格
4. 3D Line (三维线图)
用途: 三维轨迹、向量场、参数曲线
javascript
type: 'scatter3d',mode: 'lines' // 或 'lines+markers'关键属性:
line.width: 线宽line.color: 可设置为颜色数组实现渐变效果line.colorscale: 颜色梯度映射
典型场景: 运动轨迹、向量场、数学曲线
5. Isosurface (等值面图)
用途: 三维体积数据的等值面提取(类似医学 CT 中的组织边界)
javascript
type: 'isosurface'关键属性:
x,y,z: 网格坐标数组value: 各网格点的数值isomin,isomax: 等值面的最小、最大值colorscale: 颜色梯度surface.count: 等值面数量
典型场景: 医学影像、气象数据、物理场可视化
6. Streamtube / Cone (流管/向量锥)
用途: 流体动力学、向量场可视化
javascript
type: 'streamtube' // 或 'cone'关键属性:
u,v,w: 向量场的三轴分量starts.x/y/z: 流线起始位置sizeref: 向量大小比例anchor: 锥体锚点位置 ('tail', 'tip', 'center')
典型场景: CFD 结果、磁场、流体模拟
Scene 布局配置
3D 图表需要 layout.scene 来配置坐标轴和相机:
javascript
layout: { scene: { xaxis: { title: 'X 轴标签', gridcolor: '#eee', zerolinecolor: '#666' }, yaxis: { title: 'Y 轴标签' }, zaxis: { title: 'Z 轴标签' }, aspectmode: 'cube', // 'auto' | 'cube' | 'manual' - 控制轴比例 aspectratio: { x: 1, y: 1, z: 1 }, // manual 时使用 camera: { eye: { x: 1.5, y: 1.5, z: 1.2 }, // 相机位置 up: { x: 0, y: 0, z: 1 }, // 上方向 center: { x: 0, y: 0, z: 0 } // 注视点 }, bgcolor: '#fafafa' // 3D 场景背景色 }, margin: { l: 0, r: 0, b: 0, t: 0 } // 边距,建议设为 0 充分利用空间}颜色梯度 (Colorscales)
Plotly 内置颜色梯度:
- Sequential: 'Viridis', 'Magma', 'Plasma', 'Inferno', 'Greys', 'Blues', 'Greens'
- Diverging: 'RdBu', 'RdYlGn', 'PiYG', 'BrBG'
- Categorical: 'Set1', 'Set2', 'Set3', 'Pastel1'
- Custom: 可传入数组自定义
[[0, 'blue'], [0.5, 'white'], [1, 'red']]
推荐用于 3D Surface 的梯度:
- 地形: 'Earth', 'YlOrRd', 'Hot'
- 科学: 'Jet', 'Turbo', 'Rainbow'
- 中性: 'Greys', 'Viridis', 'Cividis'
完整示例: 3D 散点图
javascript
const trace = { type: 'scatter3d', mode: 'markers', x: [1, 2, 3, 4, 5], y: [2, 3, 4, 5, 6], z: [3, 4, 5, 6, 7], marker: { size: 10, color: [3, 4, 5, 6, 7], colorscale: 'Viridis', opacity: 0.8, line: { color: 'white', width: 1 } }, text: ['A', 'B', 'C', 'D', 'E'], hovertemplate: '<b>%{text}</b><br>x: %{x}<br>y: %{y}<br>z: %{z}<extra></extra>'};
const layout = { scene: { xaxis: { title: 'X 轴' }, yaxis: { title: 'Y 轴' }, zaxis: { title: 'Z 轴' }, camera: { eye: { x: 1.5, y: 1.5, z: 1 } } }, margin: { l: 0, r: 0, b: 0, t: 30 }, paper_bgcolor: '#111', title: { text: '3D Scatter Plot', font: { color: '#fff' } }};
Plotly.newPlot('chart-div', [trace], layout, { responsive: true });完整示例: 3D 曲面图
javascript
// 生成山峰形状数据const zData = [];for (let i = 0; i < 50; i++) { const row = []; for (let j = 0; j < 50; j++) { const x = (i - 25) / 2; const y = (j - 25) / 2; row.push(Math.sin(Math.sqrt(x*x + y*y)) / Math.sqrt(x*x + y*y + 0.1)); } zData.push(row);}
const trace = { type: 'surface', z: zData, colorscale: 'Viridis', contours: { z: { show: true, usecolormap: true, highlightcolor: '#42f462', project: { z: true } } }};
const layout = { scene: { aspectmode: 'auto', camera: { eye: { x: 1.5, y: -1.5, z: 1 } } }, margin: { l: 0, r: 0, b: 0, t: 50 }, title: '3D Surface with Contours'};
Plotly.newPlot('surface-div', [trace], layout);完整示例: 3D 网格图
javascript
const meshTrace = { type: 'mesh3d', x: [0, 1, 2, 0], y: [0, 0, 1, 0], z: [0, 0, 0, 1], i: [0, 0, 0, 1], j: [1, 2, 3, 2], k: [2, 3, 1, 3], color: 'rgb(200, 100, 100)', opacity: 0.8, lighting: { ambient: 0.5, diffuse: 0.8, specular: 0.7, roughness: 0.5, fresnel: 0.2 }};
const layout = { scene: { xaxis: { title: 'X' }, yaxis: { title: 'Y' }, zaxis: { title: 'Z' }, aspectmode: 'cube' }, margin: { l: 0, r: 0, b: 0, t: 30 }};
Plotly.newPlot('mesh-div', [meshTrace], layout);交互配置
javascript
// 渲染时传入配置对象Plotly.newPlot('div', data, layout, { responsive: true, // 响应式大小 displayModeBar: true, // 显示工具栏 modeBarButtonsToRemove: ['toImage'], // 移除指定按钮 displaylogo: false, // 隐藏 Plotly logo scrollZoom: true, // 启用滚轮缩放 doubleClick: 'reset+autosize' // 双击行为});3D 图表特有的交互:
- 旋转: 按住左键拖动
- 缩放: 滚轮或按住右键上下拖动
- 平移: Shift + 左键拖动
- 重置视角: 双击
性能优化
- 数据量: 3D Scatter 超过 100k 点可能导致卡顿,考虑降采样
- WebGL: Plotly 3D 自动使用 WebGL,无需额外配置
- Surface 分辨率:
z数组过大时考虑插值降采样 - 透明层数: 多层透明 surface 渲染开销高,控制在 3 层以内
CDN 引用
html
<!-- 完整版 --><script src="https://cdn.plot.ly/plotly-3.6.0.min.js"></script>
<!-- 推荐使用精确版本而非 latest --><script src="https://cdn.plot.ly/plotly-3.6.0.min.js"></script>组件封装建议
对于 Vue/React/Angular 等框架,建议封装为组件:
- 接收
data,layout,config三个 props - 在
mounted/useEffect中调用Plotly.newPlot - 监听 props 变化,使用
Plotly.react更新(比newPlot性能更好) - 组件卸载时调用
Plotly.purge清理资源
故障排查
| 问题 | 解决方案 |
|---|---|
| 图表不显示 | 检查容器 div 是否有明确高度;检查 WebGL 是否启用 |
| 颜色不生效 | Surface 等图表确认 colorscale 格式正确;Scatter 确认 marker.color 是数组非单值 |
| 旋转卡顿 | 减少数据点或启用 automargin 优化布局计算 |
| 轴比例失真 | 设置 scene.aspectmode: 'cube' 或手动指定 aspectratio |
Ln 1, Col 1MarkdownSpaces: 2
No errors