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

如何为matplotlib多个子图添加统一侧边单列4项散点图例

matplotlib 5行2列散点子图统一侧边图例实现方案

修正后完整代码

import matplotlib.pyplot as plt

# 提前创建图例手柄(空散点仅用于定义图例样式,不会实际渲染到图中)
legend_handles = [
    plt.scatter([], [], c='#738A3E', alpha=0.3, marker='^', label='X[12] >75 & X[10] >7000'),
    plt.scatter([], [], c='#738A3E', alpha=0.3, marker='v', label='X[12] >75 & X[10] ≤7000'),
    plt.scatter([], [], c='#007CAE', alpha=0.3, marker='^', label='X[12] ≤75 & X[10] >7000'),
    plt.scatter([], [], c='#007CAE', alpha=0.3, marker='v', label='X[12] ≤75 & X[10] ≤7000')
]

# 创建5行2列子图,提前预留图例空间
fig, axes = plt.subplots(nrows=5, ncols=2, figsize=(7, 12))
axes = axes.flatten() # 把子图二维数组转为一维,方便循环遍历

# 逐个绘制子图
for i in range(10):
    ax = axes[i]
    ax.set_title(f'Range {i+1}')
    # 绘制当前子图所有散点
    for j in range(X.shape[1]):
        if X[12,j] > 75 and X[10,j] > 7000:
            ax.scatter(X[i,j], y[i,j], c='#738A3E', alpha=0.3, marker='^')
        elif X[12,j] > 75 and X[10,j] <= 7000:
            ax.scatter(X[i,j], y[i,j], c='#738A3E', alpha=0.3, marker='v')
        elif X[12,j] <= 75 and X[10,j] > 7000:
            ax.scatter(X[i,j], y[i,j], c='#007CAE', alpha=0.3, marker='^')
        else:
            ax.scatter(X[i,j], y[i,j], c='#007CAE', alpha=0.3, marker='v')
    # 设置当前子图x轴范围
    ax.set_xlim(X[i,:].min(), X[i,:].max())

# 调整子图布局,右侧预留15%宽度放图例
fig.tight_layout(rect=[0, 0, 0.85, 1])
# 添加全局统一图例
fig.legend(handles=legend_handles, loc='upper right', bbox_to_anchor=(1.02, 0.9))

plt.show()

关键实现说明

  • 提前生成空散点作为图例手柄:不需要从每个子图提取图例元素,空散点不会在画布上渲染,仅用来定义图例的颜色、标记、透明度样式,顺序和要求的4种样式完全一致。
  • 用subplots批量生成子图对象,避免循环调用subplot导致的子图管理混乱,所有绘图操作直接对应当前子图对象ax。
  • tight_layout的rect参数限定子图绘制区域为画布左侧85%,剩余空间用来放置侧边图例,不会出现图例被截断的问题。
  • fig.legend是画布级别的全局图例,不属于任何子图,通过bbox_to_anchor调整位置固定在画布右侧,实现所有子图共用一个图例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:45:02