← 返回Book 2目录
第15章

三维曲面进阶

Advanced 3D Surface · 网格曲面、填充与动画

从网格曲面到薄膜振荡,掌握7种高级三维可视化技法

🎨 章节概览

三维曲面进阶技术是Ch14的延续和深化,系统讲解网格曲面、高维数据映射、Dirichlet分布可视化、 填充平面、剖面线、曲线下填充、物理振荡模拟等7种高级技法。 本章重点在于将复杂的数学概念和物理现象通过三维曲面直观展示, 特别是第四维数据映射到三维空间、剖面线分析、以及圆形薄膜振荡等高级应用。

🕸️
网格曲面
plot_surface技法
🌈
高维映射
第四维到颜色
✂️
剖面分析
切片可视化
〰️
振荡模拟
物理现象
15.1

绘制网格曲面

plot_surface 绘制精细的网格曲面

Python代码:BK_2_Ch15_1.ipynb

🕸️ 网格密度对比器

调整网格密度观察曲面精细程度 · 理解meshgrid的作用

网格点数: 21 × 21 = 441 个点

📊 显示模式

网格密度21
粗糙精细
仰角30°
方位角-135°

📐 网格原理

• meshgrid生成XY坐标网格
• 密度越高,曲面越平滑
• 但计算量也随之增加
• 需要权衡精度和性能

💡 观察要点

  • • 11×11:网格粗糙,看到棱角
  • • 21×21:中等精度,常用配置
  • • 51×51:较精细,曲面平滑
  • • 101×101:极精细,计算量大
📚 Python实现参考
# 网格生成
num = 21  # 网格密度
x_array = np.linspace(-3, 3, num)
y_array = np.linspace(-3, 3, num)
xx, yy = np.meshgrid(x_array, y_array)

# MATLAB peaks函数
f_xy = 3*(1-x)**2*exp(-(x**2) - (y+1)**2) \
    - 10*(x/5 - x**3 - y**5)*exp(-x**2-y**2) \
    - 1/3*exp(-(x+1)**2 - y**2)

# 计算Z值
zz = f_xy(xx, yy)

# 绘制网格曲面
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_wireframe(xx, yy, zz, color=[0.5, 0.5, 0.5], linewidth=0.25)
ax.set_proj_type('ortho')
ax.view_init(azim=-135, elev=30)
plt.show()

# 💡 网格密度影响:
# - 太稀疏:曲面不平滑,有明显棱角
# - 适中:平滑且计算快速(通常用21-51)
# - 太密集:计算慢,内存占用大
15.2

将第四维数据映射到三维网格曲面

用颜色编码第四维度信息

Python代码:BK_2_Ch15_2.ipynb

🕸️ 曲面映射实验室(Surface Mapping Lab)

探索网格曲面和高维数据映射

z = exp(-(x²+y²)/2)

🔍 曲面洞察

🔔 高斯曲面:钟形对称
中心最高,径向对称衰减

🧪 探索建议

  • • 切换曲面类型,观察不同形态
  • • 改变映射模式,理解第四维编码
  • • 调整视角,从多角度观察
  • • 开启横截面,分析剖面特征

🌊 曲面类型

🌈 颜色映射

仰角30°
方位角45°
网格密度15

📚 高维映射理论

🌈
第四维映射
三维空间已被(x,y,z)占据,第四维数据通过颜色编码展示。 实现4D数据的3D可视化。
✂️
剖面分析
横截面切片揭示曲面内部结构, 橙色线标示切面轮廓。
🎨
Dirichlet分布
单纯形上的分布,α参数控制集中度。 α>1聚集,α<1稀疏。
🎯 学习目标:理解高维数据如何通过颜色映射到三维空间。 掌握剖面分析技术,从不同角度观察复杂结构。
Python实现
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


# 生成网格
x = np.linspace(-2, 2, 15)
y = np.linspace(-2, 2, 15)
X, Y = np.meshgrid(x, y)

# 计算Z值
Z = np.exp(-(X**2 + Y**2) / 2)
Fourth = X**2 + Y**2  # 第四维数据

# 创建3D图
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# 高度映射到颜色
surf = ax.plot_surface(X, Y, Z, cmap='viridis')

# 设置视角
ax.view_init(elev=30, azim=45)
plt.show()
15.3

可视化 Dirichlet 分布

在单纯形上展示Dirichlet概率密度

Python代码:Bk_2_Ch15_3.ipynb

🔺 Dirichlet分布可视化器

在单纯形上展示Dirichlet概率密度 · 调整α参数观察分布变化

θ₃θ₁θ₂
约束条件: θ₁ + θ₂ + θ₃ = 1, θᵢ ≥ 0

🎛️ Alpha参数

α₁2
α₂2
α₃2

🎯 预设配置

仰角30°
方位角30°

📐 Dirichlet公式

f(θ₁,θ₂,θ₃) =
[Γ(Σαᵢ) / ∏Γ(αᵢ)]
× ∏θᵢ^(αᵢ-1)
约束: Σθᵢ = 1, θᵢ ≥ 0

💡 参数影响

  • • α = (1,1,1):均匀分布
  • • α > 1:集中在中心
  • • α < 1:集中在边角
  • • 某个α大:偏向对应θ
📚 Python实现参考
from scipy.stats import dirichlet
import numpy as np
import matplotlib.pyplot as plt

# Alpha参数
alpha_array = [2, 2, 2]

# 生成单纯形网格
theta_1_array = np.linspace(0, 1, 401)
theta_2_array = np.linspace(0, 1, 401)
tt1, tt2 = np.meshgrid(theta_1_array, theta_2_array)
tt3 = 1 - tt1 - tt2  # 约束条件

# 计算PDF
PDF_array = []
for t_1_idx, t_2_idx in zip(tt1.ravel(), tt2.ravel()):
    t_3_idx = 1 - t_1_idx - t_2_idx
    if t_3_idx < 0.005:
        PDF_idx = np.nan
    else:
        PDF_idx = dirichlet.pdf([t_1_idx, t_2_idx, t_3_idx], alpha_array)
    PDF_array.append(PDF_idx)

PDF_FF = np.reshape(PDF_array, tt1.shape)

# 绘制三维单纯形
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
norm_plt = plt.Normalize(np.nanmin(PDF_FF), np.nanmax(PDF_FF))
colors = cm.RdYlBu_r(norm_plt(PDF_FF))

surf = ax.plot_surface(tt1, tt2, tt3,
                       facecolors=colors,
                       cstride=10, rstride=10)

# 显示概率密度颜色

ax.view_init(azim=30, elev=30)
ax.set_proj_type('ortho')
plt.show()

# 💡 应用:
# - LDA主题模型中的先验分布
# - 贝叶斯统计中的共轭先验
# - 多分类问题的概率建模
15.4

绘制填充平面

用平面分割三维空间

Python代码:BK_2_Ch15_4.ipynb
15.5

可视化剖面线

展示曲面的横截面和纵切面

Python代码:BK_2_Ch15_5.ipynb

✂️ 剖面线可视化器

沿不同方向切割曲面 · 观察横截面和纵切面特征

剖切方向: 平行于XY平面 (固定Z)

📐 剖切方向

Z位置0.0
调整剖切面的位置
仰角30°
方位角-120°

📊 剖面类型

横截面:平行于XY平面
固定Z值,观察XY平面上的等高线
纵切面:平行于XZ或YZ
固定X或Y值,观察曲面剖面

💡 学习要点

  • • 剖面揭示曲面内部结构
  • • 等高线:同高度点的连线
  • • 切面曲线:局部形态分析
  • • 辅助理解复杂三维形状
📚 Python实现参考
# 生成曲面数据
xx, yy = np.meshgrid(np.linspace(-3, 3, 121), np.linspace(-3, 3, 121))
ff = peaks_function(xx, yy)

fig, ax = plt.subplots(subplot_kw={'projection': '3d'})

# 绘制网格曲面
ax.plot_wireframe(xx, yy, ff, color=[0.6, 0.6, 0.6], 
                 rstride=5, cstride=5, linewidth=0.25)

# 平行于XY平面的剖面(横截面)
z_level = 0
xx_, yy_ = np.meshgrid(np.linspace(-3, 3, 2), np.linspace(-3, 3, 2))
zz_ = np.zeros_like(xx_) + z_level

# 绘制剖切平面
ax.plot_surface(xx_, yy_, zz_, color='b', alpha=0.1)

# 绘制等高线
ax.contour(xx, yy, ff, levels=[z_level], colors='r', linewidths=1)

ax.view_init(azim=-120, elev=30)
ax.set_proj_type('ortho')
plt.show()

# 💡 应用场景:
# - 分析复杂曲面的局部特征
# - CT/MRI医学成像的切片分析
# - 地质勘探的剖面图
# - 工程设计的截面分析
15.6

填充曲线下方剖面

剖面区域的填充可视化

Python代码:BK_2_Ch15_6.ipynb
15.7

圆形薄膜振荡模式

模拟薄膜振动的物理现象

Python代码:BK_2_Ch15_7.ipynb

〰️ 薄膜振荡动画器(Membrane Oscillation Animator)

观察圆形薄膜的振荡模式演化

基础模态m=0, n=1
0/100
速度1x

👀 观察要点

  • • 薄膜上下振荡(颜色深浅变化)
  • • 节点线:振幅为零的位置
  • • (m,n)模态决定振荡模式
  • • 周期性往复运动

🎵 振动模态

角向模数 m0
径向模数 n1
振幅1.0

📊 当前模态

基础模态
最低频率振动
m: 角向节点线数量
n: 径向节点圆数量

⚛️ 物理原理

• 波动方程:∂²u/∂t² = c²∇²u
• 贝塞尔函数:径向解
• 驻波:周期性振荡
• 节点:振幅为零的点

🎓 薄膜振荡理论

〰️
波动方程
二维波动方程描述薄膜振动。 解包含贝塞尔函数和三角函数。
🎵
振动模态
(m,n)表示不同的振动模式。 每个模态有特定的频率。
🎯
节点
节点线/圆是振幅恒为零的位置。 m条径向线,n-1个同心圆。
🎯 学习目标:通过动画观察薄膜振荡的物理过程。 理解不同模态的振动形态,感受波动方程解的几何意义。
Python实现
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import jv  # 贝塞尔函数
from mpl_toolkits.mplot3d import Axes3D

# 参数
m, n = 0, 1  # 模态数
amplitude = 1
frames = 100

# 生成网格
theta = np.linspace(0, 2*np.pi, 25)
r = np.linspace(0, 1, 25)
R, Theta = np.meshgrid(r, theta)

# 贝塞尔函数的第n个零点(简化)
k = 2.4 + n

# 时间循环
for t_step in range(frames):
    t = (t_step / frames) * 2 * np.pi
    
    # 薄膜振荡方程解
    Z = amplitude * jv(m, k*R) * np.cos(m*Theta) * np.cos(k*t)
    
    # 转换为笛卡尔坐标
    X = R * np.cos(Theta)
    Y = R * np.sin(Theta)
    
    # 绘制
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_surface(X, Y, Z, cmap='viridis')
    plt.pause(0.05)
    plt.clf()

plt.show()

📚 章节总结

网格与映射

  • ✓ plot_surface:精细网格曲面
  • ✓ 颜色映射:第四维数据编码
  • ✓ cmap:colormap选择
  • ✓ Dirichlet:单纯形分布

填充与剖面

  • ✓ 填充平面:空间分割
  • ✓ 剖面线:横截面、纵切面
  • ✓ 区域填充:曲线下方区域
  • ✓ 多层叠加:复杂结构

物理模拟

  • ✓ 薄膜振荡:波动方程
  • ✓ 模态分析:振动模式
  • ✓ 时间演化:动态过程
  • ✓ 贝塞尔函数:解析解

💡 核心洞察: 三维曲面进阶技术突破了基础曲面的限制,实现了高维数据的降维展示。 第四维数据通过颜色映射到三维曲面,让我们能够同时观察四个维度的信息。 剖面线技术将复杂的三维结构切片展示,帮助理解内部结构。 物理模拟(如薄膜振荡)展示了数学可视化在科学研究中的强大应用。

🎓核心概念解析

网格曲面

• 使用meshgrid生成X, Y网格
• Z = f(X, Y)计算高度
• plot_surface绘制连续曲面
• 网格密度影响平滑度

第四维映射

• 空间位置:(x, y, z)
• 第四维:用颜色编码
• facecolors参数控制
• 实现4D数据可视化

Dirichlet分布

• 定义在单纯形上
• 约束:Σxᵢ = 1, xᵢ ≥ 0
• 三元Dirichlet:三角形
• LDA主题模型基础

填充平面

• plot_surface绘制平面
• 可以是水平或倾斜平面
• 用于空间分割和参考
• alpha控制透明度

剖面线

• 横截面:固定x或y
• 纵切面:固定z
• 展示曲面的局部特征
• 帮助理解复杂结构

薄膜振荡

• 波动方程的可视化
• 贝塞尔函数解
• 振动模态:(m, n)模式
• 时间演化动画

💻关键函数速查表

曲面绘制

ax.plot_surface(X, Y, Z)
facecolors=colors
cmap='viridis'

填充与剖面

ax.plot_surface(平面)
ax.plot(x, y, z) # 剖面线
alpha=0.5 # 透明度

特殊函数

scipy.special.jv # 贝塞尔
scipy.stats.dirichlet

📐 核心数学公式

Dirichlet分布
f(x₁,...,xₖ) = Γ(Σαᵢ) / ∏Γ(αᵢ) × ∏xᵢ^(αᵢ-1)
约束: Σxᵢ = 1, xᵢ ≥ 0
波动方程
∂²u/∂t² = c²∇²u
圆膜解: u(r,θ,t) = J_m(k·r)cos(mθ)cos(ωt)
贝塞尔函数
J_m(x) = Σ(-1)^k/(k!Γ(m+k+1)) (x/2)^(m+2k)
单纯形
Δₖ = {x ∈ ℝᵏ⁺¹: Σxᵢ=1, xᵢ≥0}

📂Python代码文件

本章内容对应以下Jupyter Notebook代码文件:

BK_2_Ch15_01.ipynb小节 15.1
BK_2_Ch15_02.ipynb小节 15.2
BK_2_Ch15_03.ipynb小节 15.3
BK_2_Ch15_04.ipynb小节 15.4
BK_2_Ch15_05.ipynb小节 15.5
BK_2_Ch15_06.ipynb小节 15.6
BK_2_Ch15_07.ipynb小节 15.7
📁 代码位置:books/Book2_Beauty-of-Data-Visualization/Book2_Ch15_Python_Codes/

📖 延伸阅读

数学基础

  • • 贝塞尔函数:柱坐标系中的特殊函数
  • • 波动方程:偏微分方程理论
  • • 单纯形几何:凸几何与优化
  • • 贝叶斯统计:Dirichlet先验

实际应用

  • • 物理模拟:振动、波动、热传导
  • • 主题模型:LDA中的Dirichlet分布
  • • 科学可视化:高维数据展示
  • • 工程分析:结构振动分析