使用seaborn kdeplot绘制多子图时如何创建适配所有子图的统一颜色条
2x2核密度子图共享统一公共色条实现方案
原代码需要先修正的问题
plt.subplots(2,2)返回的是shape为(2,2)的二维轴数组,你原代码中的解包写法fig, ((ax1, ax2 ,ax3,ax4)) = plt.subplots(2,2,sharex='col', sharey='row')会导致轴与绘图位置错位,正确的解包逻辑为:
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row')
核心实现逻辑
要消除每个子图独立生成的冗余色条、同时保证公共色条的数值对应关系准确,必须遵循两个原则:
- 所有子图的核密度绘图强制使用完全一致的颜色映射数值范围,否则不同子图同一块颜色对应的密度值没有可比性,公共色条会完全失去参考意义
- 全程保持每个子图的自动色条开关为关闭状态,手动在画布的独立空间创建专门承载公共色条的轴,不占用原有子图的布局位置
完整可运行代码
import matplotlib.pyplot as plt import seaborn as sns from matplotlib.cm import ScalarMappable from matplotlib.colors import Normalize sns.set_style("white") # 正确解包2行2列的子图结构 fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row') # 统一所有子图的颜色映射范围 # 可根据实际数据的密度极值调整vmin/vmax,保证所有子图颜色规则一致 global_vmin = 0 global_vmax = 0.5 # 初始化归一化规则与PuBuGn色卡关联 norm = Normalize(vmin=global_vmin, vmax=global_vmax) cmap = sns.color_palette("PuBuGn", as_cmap=True) # 逐个子图绘制填充核密度图,保持cbar=False,传入统一的范围参数 sns.kdeplot( hour_listm[1], dfm[1].K, ax=ax1, cmap=cmap, shade=True, cbar=False, shade_lowest=False, vmin=global_vmin, vmax=global_vmax ) sns.kdeplot( hour_listm[2], dfm[2].K, ax=ax2, cmap=cmap, shade=True, cbar=False, shade_lowest=False, vmin=global_vmin, vmax=global_vmax ) sns.kdeplot( hour_listm[3], dfm[3].K, ax=ax3, cmap=cmap, shade=True, cbar=False, shade_lowest=False, vmin=global_vmin, vmax=global_vmax ) sns.kdeplot( hour_listm[4], dfm[4].K, ax=ax4, cmap=cmap, shade=True, cbar=False, shade_lowest=False, vmin=global_vmin, vmax=global_vmax ) # 保持原有轴范围与外轴标签隐藏逻辑 for ax in fig.get_axes(): ax.set_ylim(0, 0.5) ax.set_xlim(0, 23) ax.label_outer() # 手动指定公共色条的位置,参数为[左边界, 下边界, 宽度, 高度],基于画布0-1相对坐标 cbar_ax = fig.add_axes([0.92, 0.15, 0.02, 0.7]) # 生成与绘图规则完全一致的映射对象 sm = ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) # 仅用于色条渲染,无需绑定具体绘图数据 # 在指定轴上生成公共色条 cbar = fig.colorbar(sm, cax=cbar_ax) cbar.set_label("核密度值") # 可按需修改色条标签文本 # 调整整体布局,为右侧色条预留画布空间,避免子图被挤压 plt.tight_layout(rect=[0, 0, 0.9, 1])
关键注意事项
- 每一个
kdeplot必须传入相同的vmin和vmax参数,否则每个子图会自动适配自身数据的密度极值做颜色缩放,公共色条的数值对应关系会完全错乱 - 所有
kdeplot的cbar参数必须保持为False,不能开启任何一个子图的自动色条,否则会在对应轴旁生成冗余的小型色条 - 色条的位置可以通过修改
fig.add_axes()的四个参数灵活调整:想把色条放在顶部、底部或者任意侧,都可以通过调整左/下边界的坐标实现,修改宽高参数可以调整色条的粗细/长度 global_vmin和global_vmax无需硬编码,可在完成所有kde图绘制后,遍历收集所有绘图对象的密度极值动态计算,保证色条范围完全覆盖所有子图的数值区间
内容的提问来源于stack exchange,提问作者avi
相关产品推荐
相关产品推荐

