如何为N*2网格子图添加底部跨列的水平色条
解决N×2子图网格+底部横跨水平色条的问题
我来帮你搞定这个需求!你想要的是N行2列的等尺寸子图网格,给折线/散点图绑定对应颜色,并且在底部加一个横跨整个底部的水平色条对吧?咱们先梳理下原代码的小问题,再给出调整后的完整方案:
原代码的小问题
- 随机选择子图会导致同一个子图被多次覆盖,没法保证每个子图都有内容
- 色条默认布局没法完美对齐底部两个子图的宽度
xrange在Python3中已更新为range,需要做兼容调整
改进后的完整代码
import numpy as np import matplotlib.pyplot as plt import matplotlib.colors as colors # 1. 定义核心参数:子图行数N,数据维度 N = 2 # 可修改为任意正整数,比如3、4 lines = np.random.rand(100, N*2) # 每个子图对应一条数据,共N*2条 ranks = np.linspace(0, len(lines[0,:]), len(lines[0,:])) # 2. 创建N×2的子图网格,共享x轴保证尺寸一致 fig, axs = plt.subplots(nrows=N, ncols=2, sharex=True, figsize=(10, 6*N/2)) # 把二维子图数组扁平化,方便遍历操作 axs = axs.flatten() # 3. 设置颜色映射:将ranks值映射到指定色阶 norm = colors.Normalize(vmin=np.min(ranks), vmax=np.max(ranks)) c_m = plt.cm.cool # 可替换为你需要的色板,比如viridis、plasma s_m = plt.cm.ScalarMappable(cmap=c_m, norm=norm) s_m.set_array([]) # 仅需颜色映射逻辑,无需绑定具体数据 # 4. 遍历数据,给每个子图绘制折线图(散点图适配见下文) for idx, (line, rank) in enumerate(zip(lines.T, ranks)): # 给当前子图绘制折线,颜色从映射中获取 axs[idx].plot(line, c=s_m.to_rgba(rank)) # 给子图添加标题,方便区分 axs[idx].set_title(f"Subplot {idx+1}") # 5. 调整布局并添加横跨底部的水平色条 fig.subplots_adjust(bottom=0.15) # 预留底部色条空间,可根据N的大小微调 # 关键:ax=axs让色条自动对齐所有子图的底部宽度,fraction控制色条高度,pad控制间距 fig.colorbar(s_m, orientation='horizontal', ax=axs, fraction=0.06, pad=0.1) plt.tight_layout() plt.show()
关键细节说明
- 子图尺寸一致:通过
sharex=True(按需可加sharey=True)保证所有子图轴刻度统一,自然尺寸相等;figsize可根据N的大小调整,比如N=3时设为(10, 9) - 散点图适配:如果要绘制散点图,只需把折线代码替换为:
axs[idx].scatter(np.arange(len(line)), line, c=s_m.to_rgba(rank)),颜色映射逻辑完全通用 - 色条横跨底部:
ax=axs参数告诉Matplotlib将色条放在所有子图下方,自动对齐整体宽度;fraction和pad可微调色条高度和与子图的距离,优化布局美观度 - 避免子图覆盖:用
enumerate按顺序分配数据,不会出现随机覆盖问题;若需要随机分配,可先打乱lines.T的顺序再遍历
这样就能完美实现你需要的N×2子图网格+底部横跨水平色条的效果啦!
内容的提问来源于stack exchange,提问作者kch197
相关产品推荐
相关产品推荐

