使用 matplotlib.pyplot
绘制了一个具有特殊形状的图形。
一、直接绘制参数化曲线
-
导入库:
import matplotlib.pyplot as plt import numpy as np from matplotlib.patches import PathPatch from matplotlib.path import Path
这里导入了
matplotlib.pyplot
用于绘图,numpy
用于数值计算,以及与路径相关的类和函数。 -
生成参数:
N = 400 t = np.linspace(0, 2 * np.pi, N) r = 0.5 + np.cos(t) x, y = r * np.cos(t), r * np.sin(t)
在这一步中,生成了参数
t
,该参数从 0 到 2π 产生了 400 个均匀分布的点,然后通过余弦函数计算了r
。最后,使用极坐标转换将r
转换为直角坐标系中的x
和y
。 -
创建画布和轴:
fig, ax = plt.subplots()
使用
plt.subplots()
创建一个包含一个轴的画布。 -
绘制特殊形状的图形:
ax.plot(x, y, "k")
使用
ax.plot()
绘制了一个特殊形状的图形,其中x
和y
是上一步生成的坐标,“k” 表示黑色。 -
设置图形的纵横比:
ax.set(aspect=1)
使用
ax.set()
方法设置图形的纵横比为 1,以保持图形的比例。 -
显示图形:
plt.show()
- 完整代码
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import PathPatch
from matplotlib.path import Path
# 生成参数
N = 400
t = np.linspace(0, 2 * np.pi, N)
r = 0.5 + np.cos(t)
x, y = r * np.cos(t), r * np.sin(t)
# 创建画布和轴
fig, ax = plt.subplots()
# 绘制特殊形状的图形
ax.plot(x, y, "k")
# 设置图形的纵横比
ax.set(aspect=1)
# 显示图形
plt.show()
二、曲线周围绘制误差带
误差带可用于指示曲线的不确定性。在这个例子中,我们假设误差可以用标量err给出 ,它描述垂直于曲线上每个点的不确定性。
我们使用 将该错误可视化为路径周围的彩色带 PathPatch。该补丁是由两个路径段(xp, yp)和 (xn, yn)创建的,这两个路径段垂直于曲线(x, y)移动 +/- err。
注意:这种使用 a 的方法PathPatch适用于二维中的任意曲线。如果您只有标准 y-vs.-x 图,则可以使用更简单的 fill_between方法。
-
draw_error_band
函数:def draw_error_band(ax, x, y, err, **kwargs):
这个函数接受一个坐标系
ax
、x坐标、y坐标和误差值,然后绘制一个带有误差带的曲线。 -
计算法向量:
dx = np.concatenate([[x[1] - x[0]], x[2:] - x[:-2], [x[-1] - x[-2]]]) dy = np.concatenate([[y[1] - y[0]], y[2:] - y[:-2], [y[-1] - y[-2]]]) l = np.hypot(dx, dy) nx = dy / l ny = -dx / l
使用中心差分计算法向量,其中
dx
和dy
分别为x和y坐标的差值,l
是法向量的长度,nx
和ny
是法向量的x和y分量。 -
计算误差带的端点:
xp = x + nx * err yp = y + ny * err xn = x - nx * err yn = y - ny * err
根据法向量和给定的误差值,计算误差带的两端点。
-
构建误差带的路径:
vertices = np.block([[xp, xn[::-1]], [yp, yn[::-1]]]).T codes = np.full(len(vertices), Path.LINETO) codes[0] = codes[len(xp)] = Path.MOVETO path = Path(vertices, codes)
构建误差带的路径,其中
vertices
是路径的顶点,codes
表示路径的类型(LINETO
表示直线段,MOVETO
表示移动到新的起始点)。 -
添加误差带到坐标系:
ax.add_patch(PathPatch(path, **kwargs))
将误差带添加到给定的坐标系,通过
PathPatch
类来创建并配置路径。 -
创建画布和子图:
_, axs = plt.subplots(1, 2, layout='constrained', sharex=True, sharey=True)
创建一个包含两个子图的画布,子图共享x和y轴。
-
定义两个不同的误差并绘制:
errs = [ (axs[0], "constant error", 0.05), (axs[1], "variable error", 0.05 * np.sin(2 * t) ** 2 + 0.04), ]
定义两个不同的误差,然后在每个子图中绘制原始曲线和带有误差带的曲线。
-
显示图形:
plt.show()
- 完整代码
from matplotlib.patches import PathPatch
from matplotlib.path import Path
import matplotlib.pyplot as plt
import numpy as np
def draw_error_band(ax, x, y, err, **kwargs):
# 计算法向量,通过中心差分计算(第一个点使用前向差分,最后一个点使用后向差分)
dx = np.concatenate([[x[1] - x[0]], x[2:] - x[:-2], [x[-1] - x[-2]]])
dy = np.concatenate([[y[1] - y[0]], y[2:] - y[:-2], [y[-1] - y[-2]]])
l = np.hypot(dx, dy)
nx = dy / l
ny = -dx / l
# 误差带的端点
xp = x + nx * err
yp = y + ny * err
xn = x - nx * err
yn = y - ny * err
# 构建误差带的路径
vertices = np.block([[xp, xn[::-1]],
[yp, yn[::-1]]]).T
codes = np.full(len(vertices), Path.LINETO)
codes[0] = codes[len(xp)] = Path.MOVETO
path = Path(vertices, codes)
ax.add_patch(PathPatch(path, **kwargs))
N = 400
t = np.linspace(0, 2 * np.pi, N)
r = 0.5 + np.cos(t)
x, y = r * np.cos(t), r * np.sin(t)
# 创建一个包含两个子图的画布
_, axs = plt.subplots(1, 2, layout='constrained', sharex=True, sharey=True)
# 定义两个不同的误差
errs = [
(axs[0], "constant error", 0.05),
(axs[1], "variable error", 0.05 * np.sin(2 * t) ** 2 + 0.04),
]
# 在每个子图中绘制曲线和误差带
for i, (ax, title, err) in enumerate(errs):
ax.set(title=title, aspect=1, xticks=[], yticks=[])
ax.plot(x, y, "k")
draw_error_band(ax, x, y, err=err,
facecolor=f"C{i}", edgecolor="none", alpha=.3)
# 显示图形
plt.show()