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

如何在Matplotlib中绘制尺寸精确无额外填充的圆角矩形?

如何在Matplotlib中绘制尺寸精确的圆角矩形

要实现类似CSS中裁剪边缘生成圆角(不改变原矩形尺寸)的效果,你可以通过两种方式解决:手动构建路径或者调整FancyBboxPatch的参数,避免使用导致尺寸扩展的pad属性。

方法一:手动构建Path路径(完全精确控制)

直接用matplotlib.path.Path绘制圆角矩形,所有顶点基于原矩形边界,从边角裁剪出圆角,完全不会改变原矩形的整体尺寸。

from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.path import Path
import matplotlib.patches as patches

fig = plt.figure()
ax = fig.add_subplot(111)

# 定义时间范围与坐标转换
startTime = datetime(1,1,1,10,0)
endTime = startTime + timedelta(hours=2)
start = mdates.date2num(startTime)
end = mdates.date2num(endTime)
width = end - start
height = 1

# 设置圆角半径(这里对应15分钟的时间宽度,转换为Matplotlib日期数值)
r = mdates.date2num(startTime + timedelta(minutes=15)) - start

x0, y0 = start, 0
x1, y1 = end, height

# 构建圆角矩形的顶点列表(按顺时针顺序)
vertices = [
    (x0 + r, y0),          # 左下边缘起点(跳过圆角左端点)
    (x1 - r, y0),          # 右下圆角左端点
    (x1, y0), (x1, y0 + r),# 右下圆弧的控制点与终点
    (x1, y1 - r),          # 右上边缘起点
    (x1, y1), (x1 - r, y1),# 右上圆弧的控制点与终点
    (x0 + r, y1),          # 左上边缘起点
    (x0, y1), (x0, y1 - r),# 左上圆弧的控制点与终点
    (x0, y0 + r),          # 左下边缘终点
    (x0, y0), (x0 + r, y0),# 左下圆弧的控制点与终点(闭合路径)
]

# 路径指令:MOVETO(起始)、LINETO(直线)、CURVE3(二次贝塞尔)、CLOSEPOLY(闭合)
codes = [
    Path.MOVETO,
    Path.LINETO,
    Path.CURVE3, Path.CURVE3,
    Path.LINETO,
    Path.CURVE3, Path.CURVE3,
    Path.LINETO,
    Path.CURVE3, Path.CURVE3,
    Path.LINETO,
    Path.CURVE3, Path.CURVE3,
    Path.CLOSEPOLY,
]

# 创建路径补丁并添加到轴上
rounded_path = Path(vertices, codes)
rounded_patch = patches.PathPatch(rounded_path, color='yellow', alpha=0.3)
rect = patches.Rectangle((start, 0), width, height, color='red', alpha=0.5)
ax.add_patch(rect)
ax.add_patch(rounded_patch)

# 设置轴格式与范围
ax.xaxis.set_major_formatter(mdates.DateFormatter("%I:%M %p"))
plt.xlim([start - width, end + width])
plt.ylim([-.5, 1.5])
plt.show()

方法二:调整FancyBboxPatch参数(更简洁)

FancyBboxPatch的pad参数是导致尺寸扩展的原因,设置pad=0关闭向外填充,同时用rounding_size指定圆角半径(需匹配当前轴的坐标单位)。

from datetime import datetime, timedelta
from matplotlib.patches import Rectangle, FancyBboxPatch
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

fig = plt.figure()
ax = fig.add_subplot(111)

# 时间范围与坐标转换
startTime = datetime(1,1,1,10,0)
endTime = startTime + timedelta(hours=2)
start = mdates.date2num(startTime)
end = mdates.date2num(endTime)
width = end - start
height = 1

# 圆角半径(转换为Matplotlib日期数值,对应15分钟)
r = mdates.date2num(startTime + timedelta(minutes=15)) - start

# 创建圆角矩形补丁:pad=0关闭扩展,rounding_size指定圆角大小
rounded_rect = FancyBboxPatch(
    (start, 0), width, height,
    boxstyle=f'Round, pad=0, rounding_size={r}',
    color='yellow', alpha=0.3
)
rect = Rectangle((start, 0), width, height, color='red', alpha=0.5)

ax.add_patch(rect)
ax.add_patch(rounded_rect)

# 轴格式与范围设置
ax.xaxis.set_major_formatter(mdates.DateFormatter("%I:%M %p"))
plt.xlim([start - width, end + width])
plt.ylim([-.5, 1.5])
plt.show()

关键说明

  • 日期轴下,圆角半径r需要转换为Matplotlib的日期数值(通过mdates.date2num计算时间差得到),确保圆角大小在视觉上符合预期。
  • 方法一适合需要完全自定义路径的场景,方法二更简洁,适合快速实现需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:35:13