- 数据可视化
- 数据分析
【免费下载链接】plotly.py
The interactive graphing library for Python :sparkles:
本指南基于 plotly.py 仓库中的 3D 参数化绘图文档(doc/unconverted/python/3d-parametric-plots.md)展开,系统讲解如何利用go.Surface轨迹将数学参数方程(如球坐标、柱坐标描述的曲面)渲染为可交互的 3D 曲面图,并深入剖析 colorscale、scene 三维坐标系等核心配置。读完本文,你将能够独立完成从"参数方程离散化"到"带配色与三维场景样式的交互式曲面图"的完整实战闭环。
什么是 3D 参数曲面图
3D 参数曲面图是把由两个参数(通常记作s、t或phi、theta)定义的曲面:
x = f(s, t) y = g(s, t) z = h(s, t)离散化为网格点,再以网格点构成的多边形面片渲染出来的三维图形。与笛卡尔直角坐标系下的显式曲面z = f(x, y)相比,参数化描述能力更强——球面、环面、超环面(torus knot 类曲面)、莫比乌斯带等无法写成单值函数的曲面,都可以用参数方程优雅表达。在 plotly.py 中,这类图形由plotly.graph_objects.Surface(即go.Surface)轨迹负责渲染,其数据组织方式是三个二维数组x、y、z,维度一致且一一对应。
基本参数曲面图:以扰动球面为例
文档给出的第一个例子是一个"扰动球面":以标准球坐标为基础,把半径r替换为随参数波动的函数r = 2 + sin(7s + 5t),从而在球面上形成起伏的褶皱。
参数网格的构建
先用numpy.linspace生成参数采样点,再用numpy.meshgrid张成二维网格:
import numpy as np s = np.linspace(0, 2 * np.pi, 240) # 经度方向参数,采样 240 个点 t = np.linspace(0, np.pi, 240) # 纬度方向参数,采样 240 个点 tGrid, sGrid = np.meshgrid(s, t) # 生成二维参数网格采样密度(240 × 240)直接决定曲面网格的细腻程度:采样点越多,曲面越光滑,但前端渲染开销也越大;对探索性可视化,80 × 80到200 × 200通常是精度与性能的合理区间。
代入参数方程计算坐标
将球坐标公式应用到网格上:
r = 2 + np.sin(7 * sGrid + 5 * tGrid) # r = 2 + sin(7s + 5t) x = r * np.cos(sGrid) * np.sin(tGrid) # x = r*cos(s)*sin(t) y = r * np.sin(sGrid) * np.sin(tGrid) # y = r*sin(s)*sin(t) z = r * np.cos(tGrid) # z = r*cos(t)创建 Surface 轨迹与三维场景
将三个坐标数组交给go.Surface,再通过layout.scene配置三维场景中 x/y/z 三条轴的外观。文档示例中对三条轴统一设置了白网格线、浅灰背景,并开启了坐标轴背景面板(showbackground):
import plotly.graph_objects as go surface = go.Surface(x=x, y=y, z=z) layout = go.Layout( title='Parametric Plot', scene=dict( xaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230, 230)' ), yaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230, 230)' ), zaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230, 230)' ) ) ) fig = go.Figure(data=[surface], layout=layout) fig.show()关于文档中的旧版 API:原始文档示例使用
import plotly.plotly as py与py.iplot(fig, filename='Parametric_plot')上传到 Plotly 在线服务展示,这是早期的在线绘图工作流。当前仓库的plotly.py已采用plotly.graph_objects命名空间,绘图统一通过fig.show()完成(BaseFigure.show()实现),默认走离线渲染器,无需联网账号。本文所有示例均已按新 API 改写,可直接运行。
带 Colorscale 的参数曲面:超环面公式与 Viridis 配色
文档的第二个示例展示了如何为参数曲面添加颜色映射。它使用numpy.mgrid在球坐标两个方向上密集采样,并把半径定义为一个由三角幂函数组合的"超环面"方程:
import numpy as np import plotly.graph_objects as go dphi, dtheta = np.pi / 250.0, np.pi / 250.0 [phi, theta] = np.mgrid[0:np.pi + dphi * 1.5:dphi, 0:2 * np.pi + dtheta * 1.5:dtheta] m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4 # 应用参数方程 r = (np.sin(m0 * phi) ** m1 + np.cos(m2 * phi) ** m3 + np.sin(m4 * theta) ** m5 + np.cos(m6 * theta) ** m7) x = r * np.sin(phi) * np.cos(theta) y = r * np.cos(phi) z = r * np.sin(phi) * np.sin(theta) surface = go.Surface(x=x, y=y, z=z, colorscale='Viridis') data = [surface] layout = go.Layout( title='Another Parametric Plot', scene=dict( xaxis=dict(gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230, 230)'), yaxis=dict(gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230, 230)'), zaxis=dict(gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230, 230)') ) ) fig = go.Figure(data=data, layout=layout) fig.show()colorscale 的取值规则
colorscale是Surface轨迹的核心外观属性。从 Surface 轨迹源码 的 docstring 可以确认它支持三种写法:
- 命名调色板字符串:如
'Viridis'、'Plasma'、'Jet'、'Rainbow'、'Hot'、'Electric'等。源码中列出的完整命名列表包括aggrnyl、agsunset、algae、amp、armyrose、balance、blackbody、bluered、blues、brbg、cividis、curl、deep、dense、earth、electric、greens、greys、hot、inferno、jet、magma、plasma、plotly3、portland、rainbow、rdbu、reds、spectral、sunset、turbo、twilight、viridis、ylgnbu、ylorrd等几十种,且在命名后追加_r后缀即可反转色序(如'Viridis_r')。 - 列表形式:
[[0, 'green'], [0.5, 'red'], [1.0, 'rgb(0, 0, 255)']]这种"归一化色阶值 + 颜色字符串"的成对列表,色阶值从 0 到 1,至少需要 0 和 1 两个端点。 - plotly.colors 包中的调色板对象:
sequential、diverging、cyclical等模块(见 _plotly_utils/colors 与 plotly/colors/init.py)导出的列表可直接传入。
颜色域控制:cmin / cmax / cauto / reversescale
colorscale决定"颜色怎么映射",而颜色数值域则由一组配套属性控制(同样定义于 Surface 轨迹源码):
cmin/cmax:手动指定颜色域的下界与上界,单位与z(或surfacecolor)一致,二者需成对设置;cauto:是否根据数据自动计算颜色域;一旦用户显式给出cmin/cmax,默认即视为关闭自动计算;cmid:设定颜色域中点,让cmin/cmax围绕该值等距缩放;reversescale:布尔值,是否反转颜色映射方向;autocolorscale:布尔值,决定是否使用默认调色板而非colorscale指定的调色板;showscale:布尔值,控制是否显示右侧的颜色条(colorbar),默认开启;colorbar:颜色条本身的详细配置对象(go.surface.ColorBar),支持title、len、thickness、tickformat等子属性,对应实现位于 plotly/graph_objs/surface/_colorbar.py。
例如,若要强制曲面颜色从 0 到 10 映射、并隐藏颜色条:
go.Surface(x=x, y=y, z=z, colorscale='Plasma', cmin=0, cmax=10, showscale=False)用 surfacecolor 独立驱动颜色
Surface还提供surfacecolor属性:它可以是一个与x/y/z同维的二维数组,用于独立于几何高度之外的另一组标量来控制曲面着色。典型应用场景是"几何是参数曲面、颜色表达物理量(温度、压力、误差等)"。此时颜色域(cmin/cmax/cauto)依据的是surfacecolor而非z(见源码 docstring 中对cauto的说明)。
三维场景(scene)的进阶配置
所有 3D 轨迹(包括Surface)都在layout.scene这个三维场景子图中绘制。从 layout.scene 源码 可以看到场景支持的主要配置项:
xaxis/yaxis/zaxis:三条轴各自的独立配置(网格颜色gridcolor、零线颜色zerolinecolor、背景面板showbackground/backgroundcolor、范围range、刻度tickformat等);aspectmode/aspectratio:控制三维场景的宽高比模式(如'data'按数据范围等比、'cube'强制立方体)与手动比例;camera:相机视角(eye、up、center等),用于预设初始观察角度;bgcolor:场景背景色;annotations:三维空间中的文字标注;domain:场景在画布中的布局区域。
文档示例中反复使用的"白网格线 + 浅灰背景面板"三轴统一配置,正是为了让曲面在三维空间中层次清晰、便于旋转观察。相机视角可这样预设(以 45° 俯视角度为例):
layout = go.Layout( scene=dict( xaxis=dict(...), yaxis=dict(...), zaxis=dict(...), camera=dict(eye=dict(x=1.5, y=1.5, z=1.2)), aspectmode='data' ) )Surface 轨迹的常用属性速查
结合 Surface 轨迹的完整属性清单,参数曲面绘图中常用的属性归纳如下:
| 属性 | 类型 | 作用 |
|---|---|---|
x/y/z | 二维数组 | 曲面的三个坐标网格,必须同维 |
surfacecolor | 二维数组 | 独立驱动着色的标量场,可与高度不同 |
colorscale | 字符串/列表 | 配色方案(命名调色板或色阶列表) |
cmin/cmax/cmid | 数值 | 颜色域边界与中点 |
cauto/autocolorscale | 布尔 | 颜色域 / 调色板是否自动确定 |
reversescale | 布尔 | 反转颜色映射 |
showscale/colorbar | 布尔 / 对象 | 颜色条显隐与外观 |
opacity | 0~1 数值 | 曲面透明度,便于透视内部结构 |
connectgaps | 布尔 | 是否连接z中的 NaN 空洞 |
contours | 对象 | 曲面上叠加等高线(x/y/z方向) |
hidesurface | 布尔 | 隐藏曲面本身,配合contours可绘制线框效果 |
lighting/lightposition | 对象 | 光照与光源位置,增强立体感 |
hovertemplate | 字符串 | 悬停信息模板(如"x: %{x}<br>y: %{y}<br>z: %{z}") |
其中contours与hidesurface的组合特别适合参数曲面的"线框模式":将hidesurface设为True、同时开启contours.x.show/contours.y.show,即可只绘制三维线框;lighting则控制环境光、漫反射、镜面反射等参数,能让曲面褶皱的立体感显著增强(实现见 plotly/graph_objs/surface/_lighting.py)。
从参数方程到完整图形的完整流程
把两个示例提炼成可复用的通用流程:
- 离散化参数域:用
np.linspace(均匀采样)或np.mgrid(网格切片语法)生成两个方向上的参数采样; - 网格化:用
np.meshgrid将一维参数张成二维网格sGrid、tGrid; - 代入参数方程:基于网格计算
x、y、z三个同维二维数组; - 构造轨迹:
go.Surface(x=x, y=y, z=z, colorscale=...); - 配置场景:在
layout.scene中设置三轴样式、相机视角与宽高比; - 组装与展示:
go.Figure(data=[surface], layout=layout)后调用fig.show()。
参考与延伸
- 本文主题文档:doc/unconverted/python/3d-parametric-plots.md
- Surface 轨迹完整属性与 colorscale 规则:plotly/graph_objs/_surface.py
- 三维场景 scene 配置:plotly/graph_objs/layout/_scene.py
- 颜色条与光照子组件:plotly/graph_objs/surface/_colorbar.py、plotly/graph_objs/surface/_lighting.py
- 内置调色板定义:plotly/colors/init.py 与 _plotly_utils/colors
若需绘制球坐标与极坐标风格的更多案例,可参考仓库中的其他 3D 曲面文档,如 3d-surface-plots.md 与 3d-mesh.md。
- 数据可视化
- 数据分析
【免费下载链接】plotly.py
The interactive graphing library for Python :sparkles:
相关推荐
OpenMontage 中 ManimGL 三维曲面可视化实战:参数化曲面、相机运镜与场景编排参考
OpenMontage 中 ManimGL 三维曲面可视化实战:参数化曲面、相机运镜与场景编排参考 导读 本篇文章解读 OpenMontage 仓库中数学动画技
人工智能AI Agent音视频媒体生成工作流自动化Matplot++ 3D绘图指南:从曲面到立体数据的可视化
Matplot++ 3D绘图指南:从曲面到立体数据的可视化 Matplot++是一个强大的C++图形库,专为数据可视化设计。它为现代C++应用程序提供了丰富的3
数据可视化图表库three.js ParametricGeometry 全面指南:用数学函数生成参数化曲面网格
three.js ParametricGeometry 全面指南:用数学函数生成参数化曲面网格 本文是 three.js 官方文档中 ParametricGeo
前端3D渲染图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考