← 返回Book 2目录
第12章

Patches:几何图形

Geometric Shapes · 用图形补丁创造艺术

从基础形状到生成艺术,掌握13种几何可视化技法

🎨 章节概览

Patches(图形补丁)是Matplotlib中用于绘制几何图形的核心工具,可以创建圆形、椭圆、矩形、多边形等各种形状。 本章系统讲解使用patches绘制基础几何形状、创建生成艺术、实现填充效果、添加阴影、 以及通过仿射变换实现旋转、缩放、平移等13种技法。 Patches不仅用于数据可视化标注,更是创作数学艺术和几何图案的强大工具。

⭕
基础图形
Circle、Ellipse、Rectangle
✨
生成艺术
几何图案创作
🎨
填充与阴影
横向、纵向填充
🔄
仿射变换
旋转、缩放、平移
12.1

使用patches绘制平面几何形状

Circle、Ellipse、Rectangle、Polygon等基础形状

🎨 matplotlib.patches 中常见的几何图形

  • • 图1:9种基础形状(Circle、Rectangle、Wedge、RegularPolygon、Ellipse、Arrow、PathPatch、FancyBboxPatch、Line2D)
  • • 图2:利用patches绘制正圆,以及外切、内接多边形(4、5、6、8边形)
  • • 图3:画形内接和外接多边形的几何关系

🎨 Patches实验室(Patches Lab)

探索matplotlib patches的几何图形绘制

中心圆形 (Circle)

🔍 图形洞察

⭕ 圆形:所有点到中心距离相等
📏 半径: 80px
旋转对圆形无影响(旋转对称)

🧪 探索建议

  • • 切换图形类型,观察不同形状特征
  • • 调整旋转角度,理解旋转对称性
  • • 改变透明度,观察图层叠加效果
  • • 多边形:尝试不同边数(3-12)

🎭 图形类型

80px
0.70

🎨 颜色

📚 Patches理论

什么是Patches?
Patches是matplotlib中的2D图形对象,每个patch代表一个几何形状。 通过ax.add_patch()添加到坐标轴。
from matplotlib.patches import Circle
circle = Circle((0, 0), radius=1)
ax.add_patch(circle)
常用参数
• xy:中心坐标或左下角坐标
• facecolor:填充颜色
• edgecolor:边框颜色
• alpha:透明度 (0-1)
• linewidth:边框宽度
旋转对称性
• 圆形:无限旋转对称
• 正n边形:n重旋转对称
• 矩形:2重旋转对称(180°)
• 椭圆:2重旋转对称
应用场景
✓ 数据可视化标注
✓ 误差带、置信区间
✓ 几何艺术创作
✓ 算法可视化(如最小二乘)
🎯 学习目标:通过动手调整参数,理解patches的核心属性。 观察不同图形的特征,建立几何形状的直觉。
📚 Python绘图代码(基于Ch12原文)
# ===== 示例1:使用patches绘制基本几何形状 =====
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines

# 创建画布
fig, axs = plt.subplots(3, 3, figsize=(6, 6))

# 定义各种形状
artists = [
    mpatches.Circle((0, 0), 0.1, ec="none"),  # 圆形
    mpatches.Rectangle((-0.025, -0.05), 0.05, 0.1, ec="none"),  # 矩形
    mpatches.Wedge((0, 0), 0.1, 30, 270, ec="none"),  # 楔形
    mpatches.RegularPolygon((0, 0), 5, radius=0.1),  # 正五边形
    mpatches.Ellipse((0, 0), 0.2, 0.1),  # 椭圆
    mpatches.Arrow(-0.05, -0.05, 0.1, 0.1, width=0.1),  # 箭头
    mpatches.FancyBboxPatch((-0.025, -0.05), 0.05, 0.1, 
                           boxstyle="Round", pad=0.02),  # 圆角矩形
    mlines.Line2D([-0.06, 0.0, 0.1], [0.05, -0.05, 0.05], lw=5),  # 折线
]

# 绘制每个形状
for i, (ax, artist) in enumerate(zip(axs.flat, artists)):
    artist.set(color=plt.cm.hsv(i / len(artists)))
    ax.add_artist(artist)
    ax.set(title=type(artist).__name__,
          aspect=1, xlim=(-.2, .2), ylim=(-.2, .2))
    ax.set_axis_off()

plt.show()


# ===== 示例2:正圆及外切、内接正多边形 =====
from matplotlib.patches import RegularPolygon, Circle
import numpy as np

fig, axs = plt.subplots(nrows=1, ncols=4, figsize=(12, 3))

for num_vertices, ax in zip([4, 5, 6, 8], axs.ravel()):
    # 内接多边形(半径为1)
    polygon_inner = RegularPolygon((0, 0), numVertices=num_vertices,
                                  radius=1, alpha=0.2, edgecolor='k')
    ax.add_patch(polygon_inner)
    
    # 外切多边形(半径调整)
    polygon_outer = RegularPolygon((0, 0), numVertices=num_vertices,
                                  radius=1/np.cos(np.pi/num_vertices),
                                  alpha=0.2, edgecolor='k')
    ax.add_patch(polygon_outer)
    
    # 正圆
    circle = Circle((0, 0), radius=1, facecolor='none', edgecolor='k')
    ax.add_patch(circle)
    
    ax.set_xlim(-1.5, 1.5)
    ax.set_ylim(-1.5, 1.5)
    ax.set_aspect('equal')
    ax.axis('off')
    ax.set_title(f'{num_vertices}边形')

plt.show()


# 💡 关键学习点:
# 1. mpatches模块提供丰富的几何形状
# 2. Circle, Rectangle, Polygon等基本形状
# 3. RegularPolygon的radius参数控制外接圆半径
# 4. 内接多边形半径 = r,外切多边形半径 = r/cos(π/n)
# 5. set_aspect('equal')保持纵横比
12.2

填充

fill_between 和 fill_betweenx 的多种用法

🎯 沿横轴辅助填充

  • • 图4-5:曲线和水平线之间填充区域,where条件控制,不同颜色
  • • 图6:两条曲线之间沿横轴填充
  • • 图7:沿纵轴填充(fill_betweenx)
  • • 图8:参考填充色块(axhspan和axvspan)
12.3

更多应用

fill、旋转、仿射变换等高级应用

✨ 用fill填充

  • • 图9:用fill旋转连续移位示例
  • • 图10:落和几何示意
  • • 图11:两组旋转正圆
  • • 图12:两组旋转椭圆
  • • 图13-14:两组旋转正方形,平面仿射变换

✨ 几何艺术动画器(Geometric Art Animator)

观察几何图形逐步生成艺术图案的过程

同心圆艺术
0/20
速度1x
图形数量20

👀 观察要点

  • • 图形逐个出现,形成完整图案
  • • 注意颜色渐变和位置规律
  • • 观察旋转、缩放如何创造美感
  • • 数学公式驱动的艺术创作

🎨 艺术模式

🌈 颜色模式

⚙️ 生成原理

同心圆模式
• x = 200 + cos(θ) × r
• y = 200 + sin(θ) × r
• 半径r随索引递增

📐 数学美学

  • • 对称性:旋转对称、镜像对称
  • • 重复性:周期性模式
  • • 渐变性:大小、颜色渐变
  • • 规律性:数学公式驱动

🎨 生成艺术理论

🔢
算法驱动
通过数学公式和循环生成图案,每个参数控制不同的视觉效果
🎭
参数化设计
调整参数即可生成无限变化的图案,探索参数空间的艺术可能
✨
规律与随机
规律性创造秩序美,适当随机性增加生动感和自然感
🎓 关键要素
位置控制:
• 圆周分布:极坐标
• 网格分布:笛卡尔坐标
• 螺旋分布:阿基米德螺线
视觉编码:
• 颜色:色相、饱和度、明度
• 大小:线性或非线性缩放
• 旋转:角度递增或函数映射
📚 Python绘图代码(基于Ch12原文)
# ===== 示例1:正圆旋转生成艺术 =====
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D

fig, ax = plt.subplots(figsize=(8, 8))
ax.set_aspect('equal')
ax.plot(0, 0, color='r', marker='o', markersize=10)

range_array = np.arange(200)
delta_angle = 5  # 每次旋转5度

colors = plt.cm.RdYlBu(np.linspace(0, 1, len(range_array)))

for i in range_array:
    deg = delta_angle * i
    width = 0.05 + i * 0.05  # 半径逐渐增大
    point_of_rotation = np.array([-width/2, -width/2])
    
    circle = plt.Circle(point_of_rotation, radius=width,
                       fill=False, edgecolor=colors[i],
                       transform=Affine2D().rotate_deg_around(0, 0, deg) + ax.transData)
    ax.add_patch(circle)

plt.axis('off')
plt.show()


# ===== 示例2:固定半径旋转(花瓣形) =====
fig, ax = plt.subplots(figsize=(8, 8))
ax.set_aspect('equal')
ax.plot(0, 0, color='r', marker='o', markersize=10)

range_array = np.arange(100)
delta_angle = 3.6  # 每次旋转3.6度(100次旋转360度)

colors = plt.cm.hsv(np.linspace(0, 1, len(range_array)))

for i in range_array:
    deg = delta_angle * i
    width = 2  # 固定半径
    point_of_rotation = np.array([0, -width])
    
    circle = plt.Circle(point_of_rotation, radius=width,
                       fill=False, edgecolor=colors[i],
                       transform=Affine2D().rotate_deg_around(0, 0, deg) + ax.transData)
    ax.add_patch(circle)

plt.axis('off')
plt.show()


# ===== 示例3:填充透明圆(曼陀罗效果) =====
fig, ax = plt.subplots(figsize=(8, 8))
ax.set_aspect('equal')
ax.plot(0, 0, color='b', marker='o', markersize=10)

range_array = np.arange(36)
delta_angle = 10  # 每次旋转10度

colors = plt.cm.hsv(np.linspace(0, 1, len(range_array)))

for i in range_array:
    deg = delta_angle * i
    width = 2
    point_of_rotation = np.array([0, -width])
    
    circle = plt.Circle(point_of_rotation, radius=width,
                       fill=True, edgecolor='b',
                       facecolor=colors[i],
                       alpha=0.1,  # 半透明
                       transform=Affine2D().rotate_deg_around(0, 0, deg) + ax.transData)
    ax.add_patch(circle)

plt.axis('off')
plt.show()


# 💡 关键学习点:
# 1. Affine2D().rotate_deg_around(x, y, deg):绕指定点旋转
# 2. fill=False:只绘制边框,fill=True:填充内部
# 3. alpha参数控制透明度,多层叠加产生艺术效果
# 4. plt.cm色谱:RdYlBu(红黄蓝)、hsv(色相环)
# 5. 通过控制旋转角度、半径变化创造不同艺术图案

📚 章节总结

基础图形

  • ✓ Circle:绘制圆形
  • ✓ Ellipse:绘制椭圆
  • ✓ Rectangle:绘制矩形
  • ✓ Polygon:绘制多边形

生成艺术与填充

  • ✓ 几何图案:圆、椭圆、正方形组合
  • ✓ fill_between:横向填充
  • ✓ fill_betweenx:纵向填充
  • ✓ 阴影:3D视觉效果

仿射变换

  • ✓ 旋转:rotation_deg参数
  • ✓ 平移:改变xy坐标
  • ✓ 缩放:调整width/height
  • ✓ 变换矩阵:仿射变换数学

💡 核心洞察: Patches是Matplotlib的面向对象绘图核心,每个图形都是一个独立的对象,拥有位置、大小、颜色、透明度等属性。 通过组合多个patches,可以创作复杂的几何艺术。仿射变换使图形能够旋转、缩放、平移, 为数据可视化和艺术创作提供了无限可能。在科学可视化中,patches用于标注特定区域、 绘制误差带、创建自定义图例等。

🎓核心概念解析

Patches对象

• matplotlib.patches模块提供各种形状
• 每个patch是独立的图形对象
• 通过ax.add_patch()添加到坐标轴
• 可设置facecolor、edgecolor、alpha等

常用图形

Circle(xy, radius)
Ellipse(xy, width, height)
Rectangle(xy, width, height)
Polygon(xy)
Wedge(center, r, theta1, theta2)

填充函数

• fill_between:填充两条曲线之间区域
• fill_betweenx:纵向填充
• where参数:条件填充
• 用于误差带、置信区间可视化

仿射变换

• 旋转:rotation_deg或angle参数
• 平移:修改中心坐标xy
• 缩放:调整width、height、radius
• 变换矩阵:[x', y'] = A · [x, y] + b

生成艺术

• 通过循环批量生成图形
• 参数化控制位置、大小、颜色
• 创造对称、重复、渐变图案
• 结合数学函数(sin、cos)产生规律美

应用场景

• 标注图表特定区域
• 绘制误差带、置信区间
• 创作几何艺术作品
• 可视化最小二乘等算法

💻关键函数速查表

基础图形

Circle((x, y), radius)
Ellipse((x, y), width, height)
Rectangle((x, y), width, height)
Polygon([(x1,y1), (x2,y2), ...])

填充与阴影

fill_between(x, y1, y2)
fill_betweenx(y, x1, x2)
patch.set_shadow(True)

添加与样式

ax.add_patch(patch)
patch.set_facecolor('color')
patch.set_edgecolor('color')
patch.set_alpha(0.5)

📐 仿射变换数学

🔄
旋转变换
x' = x·cos(θ) - y·sin(θ)
y' = x·sin(θ) + y·cos(θ)
↔️
缩放变换
x' = sx · x
y' = sy · y
➡️
平移变换
x' = x + tx
y' = y + ty
矩阵表示:仿射变换可用矩阵表示 [x', y']ᵀ = A·[x, y]ᵀ + b, 其中A是2×2线性变换矩阵,b是平移向量。

📂Python代码文件

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

BK_2_Ch12_01.ipynb小节 12.1
BK_2_Ch12_02.ipynb小节 12.2
BK_2_Ch12_03.ipynb小节 12.3
BK_2_Ch12_04.ipynb小节 12.4
BK_2_Ch12_05.ipynb小节 12.5
BK_2_Ch12_06.ipynb小节 12.6
BK_2_Ch12_07.ipynb小节 12.7
BK_2_Ch12_08.ipynb小节 12.8
BK_2_Ch12_09.ipynb小节 12.9
BK_2_Ch12_10.ipynb小节 12.10
BK_2_Ch12_11.ipynb小节 12.11
BK_2_Ch12_12.ipynb小节 12.12
BK_2_Ch12_13.ipynb小节 12.13
📁 代码位置:books/Book2_Beauty-of-Data-Visualization/Book2_Ch12_Python_Codes/

📖 延伸阅读

数学基础

  • • 平面几何:圆、椭圆、多边形性质
  • • 线性代数:仿射变换、变换矩阵
  • • 三角函数:旋转角度计算
  • • 参数方程:椭圆、圆的参数化表示

实际应用

  • • 数据可视化:标注、误差带、置信区间
  • • 计算机图形学:2D图形渲染
  • • 生成艺术:算法艺术创作
  • • 科学可视化:标记特定区域