4.3Path 和 Patch 对象


文档摘要

4.3Path 和 Patch 对象 Matplotlib 高级主题:深入 Path 和 Patch 对象 4.3.1 理解 Path 对象:图形的骨架 在 Matplotlib 中, 对象定义了构成各种图形元素(如线条、多边形、曲线等)的 路径。你可以将其视为图形的 "骨架",它描述了如何从一个点移动到另一个点,以及如何绘制连接这些点的线段或曲线。 一个 对象由两个关键部分组成: 顶点 (Vertices): 一组坐标点,定义了路径的形状。这些顶点可以是二维或更高维度的。 代码 (Codes): 一组指令代码,指示如何在顶点之间进行绘制。例如,代码可以指定在两个顶点之间画一条直线,还是画一条曲线,或者闭合一个多边形。 Matplotlib 提供了 类来创建和操作 Path 对象。 4.3.

4.3Path 和 Patch 对象

Matplotlib 高级主题:深入 Path 和 Patch 对象

4.3.1 理解 Path 对象:图形的骨架

在 Matplotlib 中,Path 对象定义了构成各种图形元素(如线条、多边形、曲线等)的 路径。你可以将其视为图形的 "骨架",它描述了如何从一个点移动到另一个点,以及如何绘制连接这些点的线段或曲线。

一个 Path 对象由两个关键部分组成:

  • 顶点 (Vertices): 一组坐标点,定义了路径的形状。这些顶点可以是二维或更高维度的。

  • 代码 (Codes): 一组指令代码,指示如何在顶点之间进行绘制。例如,代码可以指定在两个顶点之间画一条直线,还是画一条曲线,或者闭合一个多边形。

Matplotlib 提供了 matplotlib.path.Path 类来创建和操作 Path 对象。

4.3.1.1 Path 代码详解

Path 对象的核心在于其代码,它定义了路径的绘制方式。以下是一些常用的 Path 代码及其含义:

代码名称 代码值 含义
Path.MOVETO 1 移动到指定的顶点,不绘制任何线条。
Path.LINETO 2 从当前位置绘制一条直线到指定的顶点。
Path.CURVE3 3 使用二次贝塞尔曲线从当前位置绘制到指定的顶点。需要一个控制点。
Path.CURVE4 4 使用三次贝塞尔曲线从当前位置绘制到指定的顶点。需要两个控制点。
Path.CLOSEPOLY 79 闭合当前子路径,从当前顶点绘制一条直线回到子路径的起始顶点。

Mermaid 图示:Path 对象结构

这个 Mermaid 图展示了 Path 对象由顶点和代码组成,它们共同定义了路径的线段和曲线段。代码示例部分列举了一些常用的 Path 代码及其作用。

4.3.1.2 Path 对象代码实践

让我们通过代码来实践如何创建和使用 Path 对象。

示例 1: 创建一个简单的折线路径

import matplotlib.pyplot as plt import matplotlib.path as mpath import matplotlib.patches as mpatches # 定义顶点坐标 vertices = [ (0, 0), # P1 (0, 1), # P2 (1, 1), # P3 (1, 0), # P4 (0, 0), # P1 (再次回到起点) ] # 定义代码 codes = [ mpath.Path.MOVETO, # 移动到 P1 mpath.Path.LINETO, # 从 P1 绘制直线到 P2 mpath.Path.LINETO, # 从 P2 绘制直线到 P3 mpath.Path.LINETO, # 从 P3 绘制直线到 P4 mpath.Path.CLOSEPOLY, # 从 P4 绘制直线回到 P1,并闭合路径 ] # 创建 Path 对象 path = mpath.Path(vertices, codes) # 创建 Patch 对象 (稍后详细介绍 Patch) patch = mpatches.PathPatch(path, facecolor='orange', lw=2) # 创建 Figure 和 Axes 对象 fig, ax = plt.subplots() ax.add_patch(patch) # 将 Patch 添加到 Axes ax.set_xlim(-0.5, 1.5) ax.set_ylim(-0.5, 1.5) ax.set_aspect('equal') # 保持 x 和 y 轴比例一致 plt.title("Simple Path Example") plt.grid(True) plt.show()

代码详解:

  1. 导入必要的模块: matplotlib.pyplot, matplotlib.path, matplotlib.patches

  2. 定义顶点坐标 vertices: 我们定义了一个包含 5 个顶点的列表,构成一个正方形。

  3. 定义代码 codes:

    • mpath.Path.MOVETO: 指示从原点 (0, 0) 开始路径。

    • mpath.Path.LINETO: 指示绘制直线到后续顶点。

    • mpath.Path.CLOSEPOLY: 指示闭合路径,连接最后一个顶点到第一个顶点,形成一个闭合多边形。

  4. 创建 Path 对象: 使用 mpath.Path(vertices, codes) 将顶点和代码组合成一个 Path 对象。

  5. 创建 Patch 对象: mpatches.PathPatch(path, ...)Path 对象转换为一个 Patch 对象,用于在 Axes 上绘制。我们设置了 facecolorlw (linewidth) 属性。

  6. 创建 Figure 和 Axes 并添加 Patch: 标准 Matplotlib 绘图流程,将 Patch 添加到 Axes 上,并设置坐标轴范围和比例。

示例 2: 创建一个带有曲线的路径

import matplotlib.pyplot as plt import matplotlib.path as mpath import matplotlib.patches as mpatches import numpy as np # 定义顶点坐标 vertices = np.array([ (0, 0), # P1 (1, 1), # P2 (控制点 1 for CURVE4) (2, 1), # P3 (控制点 2 for CURVE4) (3, 0), # P4 (终点 for CURVE4) (3, -1), # P5 (2, -2), # P6 (控制点 for CURVE3) (1, -1), # P7 (终点 for CURVE3) (0, 0), # P1 (再次回到起点) ]) # 定义代码 codes = [ mpath.Path.MOVETO, # 移动到 P1 mpath.Path.CURVE4, # 从 P1 到 P4 的三次贝塞尔曲线 (使用 P2, P3 作为控制点) mpath.Path.LINETO, # 从 P4 绘制直线到 P5 mpath.Path.CURVE3, # 从 P5 到 P7 的二次贝塞尔曲线 (使用 P6 作为控制点) mpath.Path.CLOSEPOLY, # 闭合路径 ] # 创建 Path 对象 path = mpath.Path(vertices, codes) # 创建 Patch 对象 patch = mpatches.PathPatch(path, facecolor='lightblue', edgecolor='black', lw=1) # 创建 Figure 和 Axes 对象 fig, ax = plt.subplots() ax.add_patch(patch) ax.set_xlim(-0.5, 3.5) ax.set_ylim(-2.5, 1.5) ax.set_aspect('equal') plt.title("Path with Curves Example") plt.grid(True) plt.show()

代码详解:

  1. 使用 CURVE4CURVE3 代码:

    • mpath.Path.CURVE4: 绘制三次贝塞尔曲线,需要四个顶点:起点 (P1),两个控制点 (P2, P3),终点 (P4)。顶点坐标列表 vertices 中需要按照这个顺序排列。

    • mpath.Path.CURVE3: 绘制二次贝塞尔曲线,需要三个顶点:起点 (P5),一个控制点 (P6),终点 (P7)。

  2. 顶点坐标顺序: 注意 CURVE4CURVE3 代码需要按照特定的顶点顺序来定义曲线。

  3. 其他代码和绘图流程与示例 1 类似。

这两个示例展示了如何使用 Path 对象定义简单的折线和更复杂的曲线路径。通过组合不同的顶点和代码,你可以创建各种各样的形状。

4.3.2 理解 Patch 对象:图形的可视化呈现

Patch 对象是 Matplotlib 中用于在 Axes 上绘制 填充形状 的对象。它基于 Path 对象,并添加了填充颜色、边框样式等属性,使其成为我们实际看到的图形元素。

简单来说,Patch 对象是对 Path 对象的可视化封装。你可以将 Path 视为图形的形状描述,而 Patch 则是在这个形状描述的基础上,赋予其颜色、边框等视觉属性,最终在图表上呈现出来。

Matplotlib 提供了多种预定义的 Patch 类,用于绘制常见的形状,例如:

  • Rectangle: 矩形

  • Circle: 圆形

  • Polygon: 多边形

  • Ellipse: 椭圆

  • Arc: 弧形

  • Wedge: 扇形

以及更通用的 PathPatch 类,它可以基于任意 Path 对象创建 Patch。

Mermaid 图示:Path 和 Patch 的关系

这个 Mermaid 图清晰地展示了 PathPatch 之间的关系:

  • Patch 对象 基于 Path 对象来定义形状。

  • Patch 对象在 Path 的基础上,添加了各种 视觉属性,例如填充颜色、透明度、边框颜色、线宽、线型等。

  • 最终,Patch 对象被添加到 Axes 上进行绘制。

4.3.2.1 常用 Patch 对象及其代码实践

让我们看看一些常用的预定义 Patch 对象,并通过代码示例来演示如何使用它们。

示例 3: 绘制 Rectangle, Circle, Polygon Patch

import matplotlib.pyplot as plt import matplotlib.patches as mpatches fig, ax = plt.subplots() # Rectangle Patch rect = mpatches.Rectangle((0.1, 0.1), 0.4, 0.3, facecolor='lightgreen', edgecolor='black', linewidth=1) ax.add_patch(rect) # Circle Patch circle = mpatches.Circle((0.7, 0.5), 0.2, facecolor='lightcoral', edgecolor='blue', linestyle='--', linewidth=2) ax.add_patch(circle) # Polygon Patch polygon_vertices = [[0.6, 0.8], [0.8, 0.9], [0.9, 0.7], [0.7, 0.6]] polygon = mpatches.Polygon(polygon_vertices, facecolor='lightyellow', edgecolor='purple', closed=True) ax.add_patch(polygon) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_aspect('equal') plt.title("Common Patch Examples") plt.grid(True) plt.show()

代码详解:

  1. 创建不同的 Patch 对象:

    • mpatches.Rectangle((x, y), width, height, ...): 创建矩形 Patch,(x, y) 是左下角坐标,widthheight 是宽度和高度。

    • mpatches.Circle((x, y), radius, ...): 创建圆形 Patch,(x, y) 是圆心坐标,radius 是半径。

    • mpatches.Polygon(vertices, ...): 创建多边形 Patch,vertices 是顶点坐标列表。 closed=True 表示闭合多边形。

  2. 设置 Patch 属性: 每个 Patch 对象都接受各种属性来定制其外观,例如:

    • facecolor: 填充颜色

    • edgecolor: 边框颜色

    • linewidth: 边框线宽

    • linestyle: 边框线型

    • alpha: 透明度

  3. ax.add_patch(patch): 将创建的 Patch 对象添加到 Axes 上进行绘制。

示例 4: 绘制 Arc 和 Wedge Patch

import matplotlib.pyplot as plt import matplotlib.patches as mpatches fig, ax = plt.subplots() # Arc Patch arc = mpatches.Arc((0.5, 0.5), width=0.6, height=0.4, angle=30, theta1=30, theta2=270, facecolor='none', edgecolor='green', linewidth=2) ax.add_patch(arc) # Wedge Patch (扇形) wedge = mpatches.Wedge((0.5, 0.5), r=0.4, theta1=0, theta2=270, facecolor='orange', edgecolor='black', linewidth=1) ax.add_patch(wedge) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_aspect('equal') plt.title("Arc and Wedge Patch Examples") plt.grid(True) plt.show()

代码详解:

  1. mpatches.Arc((x, y), width, height, angle, theta1, theta2, ...): 创建弧形 Patch。

    • (x, y): 椭圆中心坐标。

    • width, height: 椭圆的宽度和高度。

    • angle: 椭圆整体旋转角度 (逆时针,度数)。

    • theta1, theta2: 弧形的起始和结束角度 (度数,从正 x 轴逆时针方向计算)。

    • facecolor='none': 设置填充颜色为 none,只绘制边框。

  2. mpatches.Wedge((x, y), r, theta1, theta2, ...): 创建扇形 Patch。

    • (x, y): 圆心坐标。

    • r: 半径。

    • theta1, theta2: 扇形的起始和结束角度 (度数,从正 x 轴逆时针方向计算)。

这些示例展示了如何使用 Matplotlib 提供的各种预定义 Patch 对象来绘制常见的几何形状。你可以根据需要选择合适的 Patch 类型,并自定义其属性来创建丰富的图形效果。

4.3.3 PathPatch:将 Path 对象转化为 Patch

PathPatch 是一个特殊的 Patch 类,它允许你直接使用 Path 对象来创建 Patch。这为你提供了最大的灵活性,因为你可以自定义任意复杂的路径形状,然后将其转化为可绘制的 Patch 对象。

在前面的示例中,我们已经使用过 PathPatch,例如:

path = mpath.Path(vertices, codes) patch = mpatches.PathPatch(path, facecolor='orange', lw=2)

PathPatch 的构造函数接受一个 Path 对象作为参数,并可以像其他 Patch 对象一样设置各种属性(facecolor, edgecolor, linewidth 等)。

示例 5: 使用 PathPatch 创建自定义星形 Patch

import matplotlib.pyplot as plt import matplotlib.path as mpath import matplotlib.patches as mpatches import numpy as np star_path = mpath.Path.unit_star() # 创建预定义的单位星形 Path circle_path = mpath.Path.unit_circle() # 创建预定义的单位圆形 Path # 将星形 Path 缩放和平移 star_patch = mpatches.PathPatch(star_path, facecolor='gold', edgecolor='black', lw=1, transform=plt.gca().transData + plt.Affine2D().scale(2).translate(2, 2)) # 将圆形 Path 缩放和平移 circle_patch = mpatches.PathPatch(circle_path, facecolor='lightblue', edgecolor='blue', lw=1, transform=plt.gca().transData + plt.Affine2D().scale(1.5).translate(5, 2)) fig, ax = plt.subplots() ax.add_patch(star_patch) ax.add_patch(circle_patch) ax.set_xlim(0, 7) ax.set_ylim(0, 5) ax.set_aspect('equal') plt.title("PathPatch Example - Star and Circle") plt.grid(True) plt.show()

代码详解:

  1. mpath.Path.unit_star()mpath.Path.unit_circle(): Matplotlib 提供了预定义的 Path 对象,例如单位星形和单位圆形。

  2. mpatches.PathPatch(path, ...): 使用 PathPatchstar_pathcircle_path 转换为 Patch 对象。

  3. transform=plt.gca().transData + plt.Affine2D().scale(2).translate(2, 2): 使用 transform 属性对 Patch 进行变换 (缩放和平移)。

    • plt.gca().transData: 获取当前 Axes 的数据坐标变换。

    • plt.Affine2D().scale(2).translate(2, 2): 创建一个仿射变换对象,先缩放 2 倍,然后平移 (2, 2)。

    • +: 将数据坐标变换和仿射变换组合起来,先进行数据坐标到屏幕坐标的变换,再进行缩放和平移。

这个例子展示了如何使用 PathPatch 和预定义的 Path 对象,以及如何使用 transform 属性对 Patch 进行变换,创建更复杂的图形效果。

4.3.4 高级应用:Path Effects 和 自定义 Patch

除了基本的 Path 和 Patch 用法,Matplotlib 还提供了一些高级特性,可以进一步增强图形的视觉效果和定制性。

4.3.4.1 Path Effects (路径效果)

Path Effects 允许你为 Path 和 Patch 对象添加各种视觉效果,例如阴影、描边、发光等。这可以使你的图形更具吸引力和表现力。

Matplotlib 提供了 matplotlib.patheffects 模块,其中包含多种预定义的 Path Effect 类。

示例 6: 使用 Path Effects 添加阴影效果

import matplotlib.pyplot as plt import matplotlib.patches as mpatches import matplotlib.patheffects as path_effects fig, ax = plt.subplots() rect = mpatches.Rectangle((0.2, 0.2), 0.6, 0.4, facecolor='skyblue', edgecolor='black', linewidth=2) rect.set_path_effects([path_effects.SimpleShadow(), # 添加简单阴影效果 path_effects.Stroke(linewidth=3, foreground='darkblue')]) # 添加蓝色描边效果 ax.add_patch(rect) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_aspect('equal') plt.title("Path Effects Example - Shadow and Stroke") plt.grid(True) plt.show()

代码详解:

  1. 导入 matplotlib.patheffects 模块。

  2. rect.set_path_effects([effect1, effect2, ...]): 使用 set_path_effects() 方法为 Patch 对象设置路径效果列表。

    • path_effects.SimpleShadow(): 添加一个简单的阴影效果。

    • path_effects.Stroke(linewidth=3, foreground='darkblue'): 添加一个蓝色描边效果,线宽为 3。

这个例子展示了如何使用 Path Effects 为 Patch 对象添加阴影和描边效果,增强图形的视觉层次感。

4.3.4.2 自定义 Patch 类

如果你需要创建非常特殊的形状,或者需要封装一些常用的 Patch 组合,可以考虑自定义 Patch 类。这需要继承 matplotlib.patches.Patch 类,并重写一些方法,例如 __init__, draw_path 等。

自定义 Patch 类是一个更高级的主题,这里不再深入展开,但了解这个概念可以帮助你扩展 Matplotlib 的功能,满足更复杂的需求。

4.3.5 总结

PathPatch 对象是 Matplotlib 中构建各种图形的基础。理解它们的工作原理和使用方法,可以让你:

  • 创建自定义形状: 使用 Path 对象定义任意复杂的路径,并通过 PathPatch 将其转化为可绘制的 Patch。

  • 灵活控制图形外观: 通过 Patch 对象的各种属性 (填充、边框、透明度等) 和 Path Effects,精细控制图形的视觉效果。

  • 构建更复杂的图表: 将 Path 和 Patch 组合使用,可以构建更复杂的图表元素,例如自定义标记、注释、流程图等。

掌握 Path 和 Patch 对象是提升 Matplotlib 技能的关键一步,它们为你打开了更广阔的图形定制化世界。希望本文的详细讲解和代码实践能够帮助你深入理解这两个重要的概念,并在你的 Matplotlib 图表创作中发挥更大的作用。

总结 Mermaid 图:Path 和 Patch 对象在 Matplotlib 中的地位

这个 Mermaid 图总结了 Path 和 Patch 对象在 Matplotlib 整体架构中的地位:

  • Path 是图形的形状描述。

  • Patch 是基于 Path 的可视化对象,是 Artist 的一种。

  • Artist 是 Matplotlib 中所有可绘制元素的基类,包括 Patch, Line2D, Text 等。

  • Artist 被添加到 Axes 上进行绘制。

  • Axes 属于 Figure (画布)。

理解这个层级关系有助于你更好地理解 Matplotlib 的工作原理,并更有效地使用 Path 和 Patch 对象来创建强大的可视化作品。


发布者: 作者: 转发
评论区 (0)
U