You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Matplotlib的fig.transFigure在ylabel旁及画布任意位置绘制Patch图形

我创建了一组点序列,希望将其转换为Patch对象,目标是把该Patch绘制在y轴标签左侧(如下图红色部分所示),或是画布的任意其他位置。

虽然使用Gridspec也可以实现该需求,但我更希望通过Patch来完成。

import matplotlib.pyplot as plt
import numpy as np

plt.figure()
npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)
plt.plot(xd,yd)

示例图

编辑1

目前我已经可以成功创建Patch对象,仅需将其移动到坐标轴外侧即可,可通过平移或缩放操作实现。我确认实现该需求的核心参考为Matplotlib官方的变换系统教程,更具体来说,解决方案需要用到fig.transFigure。对应代码如下:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches

npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)

fig, ax = plt.subplots()
ax.axis([-2, 0, -1, 1])
verts=np.c_[xd,yd]
codes = np.ones(len(xd))*2 # 除第一个点外所有点都为Path.LINETO类型
codes[0] = 1 # 仅第一个点为Path.MOVETO类型
path1 = mpath.Path(verts, codes)
patch = mpatches.PathPatch(path1, facecolor='none')
ax.add_patch(patch)

运行结果:
编辑1运行结果图

编辑2:接近完成!

为使用取值范围在[0,1]之间的Figure坐标,我对定义路径的点做了归一化处理。我没有使用向坐标轴添加Patch的ax.add_patch()方法,而是使用fig.add_artist()将Patch添加到画布上,覆盖在坐标轴上方。对应代码如下:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches

# 归一化数据
def normalize(x):
    return (x - min(x)) / (max(x) - min(x))

npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)

xd = normalize(xd)
yd = normalize(yd)

fig, ax = plt.subplots()
ax.axis([-2, 2, -1, 1])
verts=np.c_[xd,yd]
codes = np.ones(len(xd))*2 # 除第一个点外所有点都为Path.LINETO类型
codes[0] = 1 # 仅第一个点为Path.MOVETO类型
path1 = mpath.Path(verts, codes)
patch1 = mpatches.PathPatch(path1, facecolor='none')
ax.add_patch(patch1)

patch2 = mpatches.PathPatch(path1, fc='none', ec='red', transform=fig.transFigure)
fig.add_artist(patch2)

目前的运行结果如下:
编辑2运行结果图
接下来只需要使用Affine2D对Patch进行缩放和平移即可。

编辑3:完成!

最终我成功实现了需求,由于我暂时没搞清楚scale()和translate()参数使用的坐标系,所以通过试错法确定了参数值,目前还希望能获取到精确的y轴中心(画布坐标中的0.5位置)来优化实现。完整代码如下:

import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches

# 归一化数据
def normalize(x):
    return (x - min(x)) / (max(x) - min(x))

npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)

xd = normalize(xd)
yd = normalize(yd)

fig, ax = plt.subplots()
ax.axis([-2, 2, -1, 1])
verts=np.c_[xd,yd]
codes = np.ones(len(xd))*2 # 除第一个点外所有点都为Path.LINETO类型
codes[0] = 1 # 仅第一个点为Path.MOVETO类型
path1 = mpath.Path(verts, codes)
patch1 = mpatches.PathPatch(path1, fc='none', ec='green')
ax.add_patch(patch1) # 在坐标轴内部绘制

patch2 = mpatches.PathPatch(path1, fc='none', ec='C0', transform=fig.transFigure)
fig.add_artist(patch2) # 在画布层级绘制,该方法可行

import matplotlib.transforms as mtransforms
tt = fig.transFigure + mtransforms.Affine2D().scale(0.02, 0.8).translate(10,45)
patch3 = mpatches.PathPatch(path1, fc='none', ec='red', transform=tt)
fig.add_artist(patch3)

最终运行结果如下:
最终运行结果图


内容的提问来源于stack exchange,提问作者Pedro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:45:01