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

如何在Matplotlib图例中将两个散点标记合并为单个暂停符号条目?

解决Matplotlib中暂停符号图例重复的问题

你的问题出在两次调用scatter时都设置了相同的label,导致图例生成了重复条目。以下是几种可行的解决方案:

方案一:使用自定义标记路径(最简洁)

直接定义一个包含两条竖线的自定义标记,这样只需一次scatter调用即可完成绘制,自然避免图例重复:

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

# 定义双竖线标记的路径
def double_vertical_marker():
    shift = 0.1  # 两条线的间距比例
    # 标记坐标以中心点(0,0)为基准
    vertices = [
        (-shift, -0.5), (-shift, 0.5),  # 左侧竖线
        (shift, -0.5), (shift, 0.5)     # 右侧竖线
    ]
    # 路径指令:MOVETO表示移动到起点,LINETO表示画线到下一点
    codes = [
        Path.MOVETO, Path.LINETO,
        Path.MOVETO, Path.LINETO
    ]
    return Path(vertices, codes)

# 绘制汽车行驶路径
x = np.linspace(0, 20, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, y)

# 标记停车位置
x_stop = np.array([1, 5, 10])
y_stop = np.sin(x_stop)
ax.scatter(x_stop, y_stop, marker=double_vertical_marker(), color='r', s=225, label='停车点')

ax.legend(loc='best')
plt.show()

方案二:手动创建复合图例条目

保持原有的两次scatter绘制方式,但去掉其中一个的label,然后手动创建包含两条竖线的图例条目:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.lines as mlines

# 绘制汽车行驶路径
x = np.linspace(0, 20, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, y)

# 标记停车位置
x_stop = np.array([1, 5, 10])
y_stop = np.sin(x_stop)
shift = 0.1
# 仅在第二次scatter时设置label(或第一次,任选其一)
ax.scatter(x_stop - shift, y_stop, marker='|', color='r', s=225)
ax.scatter(x_stop + shift, y_stop, marker='|', color='r', s=225)

# 创建两个单竖线的标记对象
line_left = mlines.Line2D([], [], color='r', marker='|', markersize=15)
line_right = mlines.Line2D([], [], color='r', marker='|', markersize=15)
# 将两个标记组合成一个图例条目
ax.legend([(line_left, line_right)], ['停车点'], loc='best')

plt.show()

方案三:自定义图例处理器

通过编写自定义的图例处理器,修改单个scatter条目的显示样式,使其展示两条竖线:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerBase
import matplotlib.lines as mlines

# 自定义图例处理器:绘制两条竖线
class DoubleLineHandler(HandlerBase):
    def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
        # 在图例框内绘制左右两条竖线
        line1 = mlines.Line2D([width/4, width/4], [ydescent, height - ydescent], color='r', linewidth=2)
        line2 = mlines.Line2D([3*width/4, 3*width/4], [ydescent, height - ydescent], color='r', linewidth=2)
        return [line1, line2]

# 绘制汽车行驶路径
x = np.linspace(0, 20, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, y)

# 标记停车位置
x_stop = np.array([1, 5, 10])
y_stop = np.sin(x_stop)
shift = 0.1
ax.scatter(x_stop - shift, y_stop, marker='|', color='r', s=225)
# 仅给其中一个scatter设置label
scatter_right = ax.scatter(x_stop + shift, y_stop, marker='|', color='r', s=225, label='停车点')

# 使用自定义处理器生成图例
ax.legend(handles=[scatter_right], handler_map={type(scatter_right): DoubleLineHandler()}, loc='best')

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:45:36