Python使用matplotlib绘制了一个具有特殊形状的图形和曲线周围绘制误差带图详解

本文介绍了如何使用matplotlib.pyplot库在Python中绘制具有特殊形状的参数化曲线,并展示了如何添加误差带以表示不确定性。通过numpy进行数值计算和路径操作,演示了创建和配置误差带的详细步骤。
摘要由CSDN通过智能技术生成

使用 matplotlib.pyplot 绘制了一个具有特殊形状的图形。

一、直接绘制参数化曲线

在这里插入图片描述

  1. 导入库:

    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.patches import PathPatch
    from matplotlib.path import Path
    

    这里导入了 matplotlib.pyplot 用于绘图,numpy 用于数值计算,以及与路径相关的类和函数。

  2. 生成参数:

    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 转换为直角坐标系中的 xy

  3. 创建画布和轴:

    fig, ax = plt.subplots()
    

    使用 plt.subplots() 创建一个包含一个轴的画布。

  4. 绘制特殊形状的图形:

    ax.plot(x, y, "k")
    

    使用 ax.plot() 绘制了一个特殊形状的图形,其中 xy 是上一步生成的坐标,“k” 表示黑色。

  5. 设置图形的纵横比:

    ax.set(aspect=1)
    

    使用 ax.set() 方法设置图形的纵横比为 1,以保持图形的比例。

  6. 显示图形:

    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方法。
在这里插入图片描述

  1. draw_error_band 函数:

    def draw_error_band(ax, x, y, err, **kwargs):
    

    这个函数接受一个坐标系 ax、x坐标、y坐标和误差值,然后绘制一个带有误差带的曲线。

  2. 计算法向量:

    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
    

    使用中心差分计算法向量,其中 dxdy 分别为x和y坐标的差值,l 是法向量的长度,nxny 是法向量的x和y分量。

  3. 计算误差带的端点:

    xp = x + nx * err
    yp = y + ny * err
    xn = x - nx * err
    yn = y - ny * err
    

    根据法向量和给定的误差值,计算误差带的两端点。

  4. 构建误差带的路径:

    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 表示移动到新的起始点)。

  5. 添加误差带到坐标系:

    ax.add_patch(PathPatch(path, **kwargs))
    

    将误差带添加到给定的坐标系,通过 PathPatch 类来创建并配置路径。

  6. 创建画布和子图:

    _, axs = plt.subplots(1, 2, layout='constrained', sharex=True, sharey=True)
    

    创建一个包含两个子图的画布,子图共享x和y轴。

  7. 定义两个不同的误差并绘制:

    errs = [
        (axs[0], "constant error", 0.05),
        (axs[1], "variable error", 0.05 * np.sin(2 * t) ** 2 + 0.04),
    ]
    

    定义两个不同的误差,然后在每个子图中绘制原始曲线和带有误差带的曲线。

  8. 显示图形:

    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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pandas120

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值