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

如何让Matplotlib Pyplot图例中的Hatches填充图案显示美观

解决Matplotlib图例中Hatch图案偏移问题

问题原因

Matplotlib的hatch填充图案基于全局坐标空间绘制,而非图例中Patch的局部边界框,导致小尺寸Patch的hatch无法居中,出现对齐偏移。

解决方案

方法一:自定义居中Hatch的Patch类

重写Patch的get_hatch_transform方法,让hatch图案相对于Patch自身边界框居中:

import matplotlib.patches as mpatches
from matplotlib.transforms import TransformedBbox, Bbox
import matplotlib.pyplot as plt

# 自定义居中hatch的Patch类
class CenteredHatchPatch(mpatches.Patch):
    def __init__(self, hatch, **kwargs):
        super().__init__(**kwargs)
        self.hatch = hatch

    def get_hatch_transform(self):
        # 获取Patch的局部边界框
        bbox = TransformedBbox(Bbox.from_bounds(0, 0, self.get_width(), self.get_height()),
                               self.get_transform())
        # 调整变换矩阵,让hatch以Patch中心为原点
        hatch_trans = self.get_transform().inverted()
        hatch_trans = hatch_trans.translate(bbox.width/2, bbox.height/2)
        hatch_trans = hatch_trans.scale(1/bbox.width, 1/bbox.height)
        return hatch_trans

# 替换原图例元素中的Patch为自定义类
legend_elements=[
    CenteredHatchPatch(hatch="\\\\", facecolor='none', label='not unitary', edgecolor="#8D8896", lw=1),
    CenteredHatchPatch(hatch="//", facecolor='none', label='not bfb', edgecolor="#752692", lw=1),
    CenteredHatchPatch(hatch="---", facecolor='none', label='STU obs.', edgecolor="#124C8A", lw=1),
    CenteredHatchPatch(hatch="xx", facecolor='none', label='Vacuum stab.', edgecolor="#B9314F", lw=1),
    CenteredHatchPatch(hatch="||", facecolor='none', label='HB excl.', edgecolor="#F57200", lw=1),
    CenteredHatchPatch(hatch="++", facecolor='none', label='HS excl.', edgecolor="tab:green", lw=1),
    CenteredHatchPatch(hatch="//", facecolor='none', label='$h_{95}$ excl.', edgecolor="#4EA5D9", lw=1),
    mpatches.Patch(facecolor="darkgreen", label='stable')
]

fig, ax = plt.subplots()
ax.legend(handles=legend_elements, ncols=2, loc="lower center", bbox_to_anchor=(0.5, 1.05))
plt.show()

方法二:调整图例Patch尺寸

通过增大图例中Patch的显示尺寸,弱化hatch偏移的视觉效果,操作简单:

# 在legend调用中添加handlelength和handleheight参数
ax.legend(handles=legend_elements, ncols=2, loc="lower center", bbox_to_anchor=(0.5, 1.05),
          handlelength=2, handleheight=1.5)

方法三:用Line2D模拟Hatch图案

对于简单图案,直接用Line2D的marker或线条模拟,完全控制图案位置:

from matplotlib.lines import Line2D

# 重新定义图例元素,用Line2D替代部分Patch
legend_elements=[
    mpatches.Patch(facecolor='none', hatch="\\\\", label='not unitary', edgecolor="#8D8896", lw=1),
    # 用"+" marker模拟"++" hatch
    Line2D([], [], color='tab:green', lw=1, marker='+', linestyle='', markersize=8, label='HS excl.'),
    # 用水平线模拟"---" hatch
    Line2D([], [], color="#124C8A", lw=1, linestyle='-', label='STU obs.'),
    # 用叉号marker模拟"xx" hatch
    Line2D([], [], color="#B9314F", lw=1, marker='x', linestyle='', markersize=8, label='Vacuum stab.'),
    # 其他元素按需替换
    mpatches.Patch(facecolor="darkgreen", label='stable')
]

方法对比

  • 自定义Patch:彻底解决居中问题,适配所有hatch类型,代码稍复杂。
  • 调整尺寸:快速改善视觉效果,无需修改元素定义,但无法完全消除偏移。
  • Line2D模拟:灵活性高,适合简单图案,需逐个调整元素样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 06:22:50