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

Matplotlib中为多色图例添加填充图案(hatch)的问题

解决Matplotlib多色图例条目添加填充图案的问题

问题描述

基于现有代码实现Matplotlib多色图例条目时,尝试为图例添加//、xx这类填充图案但未成功,需求是让其中一个图例矩形带填充图案,另一个不带。尝试代码如下:

import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection

# define an object that will be used by the legend
class MulticolorPatch(object):
    def __init__(self, colors):
        self.colors = colors
        
# define a handler for the MulticolorPatch object
class MulticolorPatchHandler(object):
    def legend_artist(self, legend, orig_handle, fontsize, handlebox):
        width, height = handlebox.width, handlebox.height
        patches = []
        for i, c in enumerate(orig_handle.colors):
          patches.append(
              plt.Rectangle(
                  [
                      width/len(orig_handle.colors) * i - handlebox.xdescent, 
                      -handlebox.ydescent
                  ],
                  width / len(orig_handle.colors),
                  height, 
                  facecolor=c, 
                  edgecolor="black",
                  linewidth=0.5,
                  hatch='//'
              )
          )

        patch = PatchCollection(patches, match_original=True)
        handlebox.add_artist(patch)

        return patch


# ------ choose some colors
colors1 = ['r', 'g']
colors2 = ['b', 'y']

# ------ create a dummy-plot (just to show that it works)
f, ax = plt.subplots()
ax.plot([1,2,3,4,5], [1,4.5,2,5.5,3], c='g', lw=0.5, ls='--',
        label='... just a line')
ax.scatter(range(len(colors1)), range(len(colors1)), c=colors1)
ax.scatter([range(len(colors2))], [.5]*len(colors2), c=colors2, s=50)

# ------ get the legend-entries that are already attached to the axis
h, l = ax.get_legend_handles_labels()

# ------ append the multicolor legend patches
h.append(MulticolorPatch(colors1))
l.append("a nice multicolor legend patch")

h.append(MulticolorPatch(colors2))
l.append("and another one")

# ------ create the legend
f.legend(h, l, loc='upper left', 
         handler_map={MulticolorPatch: MulticolorPatchHandler()}, 
         bbox_to_anchor=(.125,.875))

解决方案

问题出在两个核心点:原MulticolorPatch类没有存储填充图案的差异化参数,且PatchCollection的match_original=True会覆盖单个patch的hatch设置。修改步骤如下:

  1. 扩展MulticolorPatch类:新增hatch参数,支持为每个补丁单独指定填充图案(默认None表示无图案)
  2. 调整Handler逻辑:在创建矩形patch时读取对象的hatch参数,同时移除PatchCollection的match_original参数,避免覆盖自定义设置

修改后的完整代码:

import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection

# 定义图例使用的多色补丁对象,新增hatch参数支持填充图案设置
class MulticolorPatch(object):
    def __init__(self, colors, hatch=None):
        self.colors = colors
        self.hatch = hatch
        
# 定义多色补丁的图例处理器
class MulticolorPatchHandler(object):
    def legend_artist(self, legend, orig_handle, fontsize, handlebox):
        width, height = handlebox.width, handlebox.height
        patches = []
        for i, c in enumerate(orig_handle.colors):
            patches.append(
                plt.Rectangle(
                    [
                        width/len(orig_handle.colors) * i - handlebox.xdescent, 
                        -handlebox.ydescent
                    ],
                    width / len(orig_handle.colors),
                    height, 
                    facecolor=c, 
                    edgecolor="black",
                    linewidth=0.5,
                    hatch=orig_handle.hatch  # 使用当前补丁的hatch参数
                )
            )

        # 移除match_original=True,避免覆盖自定义hatch设置
        patch = PatchCollection(patches)
        handlebox.add_artist(patch)

        return patch


# 选择颜色,为不同补丁指定是否带填充图案
colors1 = ['r', 'g']
colors2 = ['b', 'y']

# 创建示例图
f, ax = plt.subplots()
ax.plot([1,2,3,4,5], [1,4.5,2,5.5,3], c='g', lw=0.5, ls='--',
        label='... just a line')
ax.scatter(range(len(colors1)), range(len(colors1)), c=colors1)
ax.scatter([range(len(colors2))], [.5]*len(colors2), c=colors2, s=50)

# 获取已有图例条目
h, l = ax.get_legend_handles_labels()

# 添加多色图例补丁:第一个带//填充,第二个无填充
h.append(MulticolorPatch(colors1, hatch='//'))
l.append("带填充图案的多色图例")

h.append(MulticolorPatch(colors2))
l.append("无填充图案的多色图例")

# 创建图例
f.legend(h, l, loc='upper left', 
         handler_map={MulticolorPatch: MulticolorPatchHandler()}, 
         bbox_to_anchor=(.125,.875))

plt.show()

关键修改说明

  • 给MulticolorPatch添加hatch参数,实现不同图例条目填充图案的差异化配置
  • 矩形patch的hatch属性从orig_handle.hatch读取,而非固定写死,支持灵活设置
  • 移除PatchCollection的match_original=True,该参数会强制同步集合内所有patch的属性,导致自定义hatch被覆盖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:17:46