如何去除单张图表中多个colorbar之间的空白区域
解决Matplotlib中水平Colorbar间距过大的问题
问题描述
我尝试在Matplotlib中水平绘制三个colorbar,希望消除它们之间的空白区域,请问是否有实现该需求或逐步调整间距的方法?
复现代码
import matplotlib as mpl import matplotlib.pyplot as plt fig, axes = plt.subplots(figsize=(8, 2), nrows=3, ncols=1, sharex=True, sharey=True) fig.suptitle('Bar comparison') # upper colorbar bar1 = [['a', 0, 0.6], ['b', 0.6, 1.2], ['a', 1.2, 1.8], ['b', 1.8, 4]] colors1 = ['yellow', 'blue', 'yellow', 'blue'] cmap1 = mpl.colors.ListedColormap(colors1) bounds1 = [0] + [i[2] for i in bar1] norm1 = mpl.colors.BoundaryNorm(bounds1, len(colors1)) plt.colorbar(mpl.cm.ScalarMappable(cmap=cmap1, norm=norm1), cax=axes[0], ticks=[[0], [bar1[-1][2]]], spacing='proportional', orientation='horizontal') # middle colorbar bar2 = [['a', 0, 0.5], ['b', 0.5, 1], ['a', 1, 2], ['b', 2, 3.8], ['a', 3.8, 4]] colors2 = ['yellow', 'blue', 'yellow', 'blue', 'yellow'] cmap2 = mpl.colors.ListedColormap(colors2) bounds2 = [0] + [i[2] for i in bar2] norm2 = mpl.colors.BoundaryNorm(bounds2, len(colors2)) plt.colorbar(mpl.cm.ScalarMappable(cmap=cmap2, norm=norm2), cax=axes[1], ticks=[[0], [bar2[-1][2]]], spacing='proportional', orientation='horizontal') # lower colorbar bar3 = [['a', 0, 0.5], ['b', 0.5, 1], ['a', 1, 2], ['b', 2, 3.8], ['a', 3.8, 4]] colors3 = ['green', 'green', 'green', 'green', 'red'] cmap3 = mpl.colors.ListedColormap(colors3) bounds3 = [0] + [i[2] for i in bar3] norm3 = mpl.colors.BoundaryNorm(bounds3, len(colors3)) plt.colorbar(mpl.cm.ScalarMappable(cmap=cmap3, norm=norm3), cax=axes[2], ticks=[[0], [bar3[-1][2]]], spacing='proportional', orientation='horizontal') # Figure settings # Hide x labels and tick labels for all but bottom plot. for ax in axes: ax.label_outer() plt.show()
解决方案
方法一:直接消除子图间距(推荐)
通过设置子图垂直间距为0,并清理轴上冗余元素,让三个colorbar紧密贴合。修改后的代码如下:
import matplotlib as mpl import matplotlib.pyplot as plt # 关键:设置hspace=0消除子图间垂直空白 fig, axes = plt.subplots(figsize=(8, 2), nrows=3, ncols=1, sharex=True, sharey=True, gridspec_kw={'hspace': 0}) fig.suptitle('Bar comparison') # upper colorbar bar1 = [['a', 0, 0.6], ['b', 0.6, 1.2], ['a', 1.2, 1.8], ['b', 1.8, 4]] colors1 = ['yellow', 'blue', 'yellow', 'blue'] cmap1 = mpl.colors.ListedColormap(colors1) bounds1 = [0] + [i[2] for i in bar1] norm1 = mpl.colors.BoundaryNorm(bounds1, len(colors1)) plt.colorbar(mpl.cm.ScalarMappable(cmap=cmap1, norm=norm1), cax=axes[0], ticks=[0, bar1[-1][2]], # 修复嵌套列表导致的刻度异常 spacing='proportional', orientation='horizontal') # middle colorbar bar2 = [['a', 0, 0.5], ['b', 0.5, 1], ['a', 1, 2], ['b', 2, 3.8], ['a', 3.8, 4]] colors2 = ['yellow', 'blue', 'yellow', 'blue', 'yellow'] cmap2 = mpl.colors.ListedColormap(colors2) bounds2 = [0] + [i[2] for i in bar2] norm2 = mpl.colors.BoundaryNorm(bounds2, len(colors2)) plt.colorbar(mpl.cm.ScalarMappable(cmap=cmap2, norm=norm2), cax=axes[1], ticks=[0, bar2[-1][2]], spacing='proportional', orientation='horizontal') # lower colorbar bar3 = [['a', 0, 0.5], ['b', 0.5, 1], ['a', 1, 2], ['b', 2, 3.8], ['a', 3.8, 4]] colors3 = ['green', 'green', 'green', 'green', 'red'] cmap3 = mpl.colors.ListedColormap(colors3) bounds3 = [0] + [i[2] for i in bar3] norm3 = mpl.colors.BoundaryNorm(bounds3, len(colors3)) plt.colorbar(mpl.cm.ScalarMappable(cmap=cmap3, norm=norm3), cax=axes[2], ticks=[0, bar3[-1][2]], spacing='proportional', orientation='horizontal') # 清理轴元素,避免额外空白 for ax in axes: ax.label_outer() ax.margins(y=0) # 移除y方向的边距 # 隐藏不需要的边框和刻度 ax.set_yticks([]) for spine in ax.spines.values(): spine.set_visible(False) plt.show()
方法二:精细调整间距
如果不需要完全消除空白,而是自定义间距大小,可以在plt.show()前添加以下代码,数值越小间距越小:
fig.subplots_adjust(hspace=0.05) # 设置0.05的小间距,可根据需求修改
关键说明
gridspec_kw={'hspace': 0}:直接让子图间垂直间距为0,是消除空白的核心设置。- 清理轴元素:colorbar的容器轴不需要y轴刻度、边框,隐藏这些元素并设置y边距为0,避免轴本身带来额外空白。
- 修复刻度设置:原代码中
ticks用嵌套列表会导致显示异常,改为普通列表[0, bar[-1][2]]更合理。
内容的提问来源于stack exchange,提问作者lonyen11
相关产品推荐
相关产品推荐

