如何让Matplotlib中色条尺寸与等高线图匹配?
解决Matplotlib中等高线图色条与主图尺寸不匹配的问题
你在使用Matplotlib绘制等高线彩色图时,遇到了色条(colorbar)与主图尺寸不匹配的问题,原代码如下:
import numpy as np from matplotlib.ticker import (MultipleLocator, AutoMinorLocator) import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1 import make_axes_locatable import scipy.interpolate from matplotlib.backends.backend_pdf import PdfPages from functools import reduce pp = PdfPages('plot.pdf') N = 2000 x, y, z = np.genfromtxt(r'100_t_eV_inten.data', unpack=True,autostrip=True,skip_header=1) xp= (x-150)*0.6581 yp= y+543 xll = xp.min(); xul = xp.max(); yll = yp.min(); yul = yp.max() xi = np.linspace(xll, xul, N) yi = np.linspace(yll, yul, N) zi = scipy.interpolate.griddata((xp,yp), z/max(z), (xi[None,:], yi[:,None]), method='cubic') fig, ax =plt.subplots(dpi=800) colormap=plt.contourf(xi,yi,zi,100) fig.suptitle('Input Data Contour Map') plt.xlabel('$\phi$ (deg)') plt.ylabel('$\psi$ (deg)') plt.ylim(515, 540) plt.xlim(-85, 85) cax = fig.add_axes([ax.get_position().x1+0.04, ax.get_position().y0, 0.2, ax.get_position().height]) plt.clim(0, 0.2) im=plt.imshow(zi, extent=[xll, xul, yll, yul], cmap='hot') plt.colorbar(im, cax=cax) plt.show()
问题原因
你的代码存在两个核心问题:
- 同时调用了
contourf和imshow,属于重复绘图,且色条关联的是imshow的对象,和contourf的显示逻辑冲突 - 手动计算色条轴位置的方式,在设置
xlim和ylim后,主图的实际显示区域位置会发生变化,手动设置的轴参数无法自动适配,导致尺寸不匹配;且色条宽度设为0.2(相对画布比例)过宽,进一步加剧了视觉上的不匹配
解决方案
使用mpl_toolkits.axes_grid1中的make_axes_locatable工具,它能自动根据主图的实际显示区域创建尺寸完全匹配的色条轴,修改后的完整代码如下:
import numpy as np from matplotlib.ticker import (MultipleLocator, AutoMinorLocator) import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1 import make_axes_locatable import scipy.interpolate from matplotlib.backends.backend_pdf import PdfPages from functools import reduce pp = PdfPages('plot.pdf') N = 2000 x, y, z = np.genfromtxt(r'100_t_eV_inten.data', unpack=True,autostrip=True,skip_header=1) xp= (x-150)*0.6581 yp= y+543 xll = xp.min(); xul = xp.max(); yll = yp.min(); yul = yp.max() xi = np.linspace(xll, xul, N) yi = np.linspace(yll, yul, N) zi = scipy.interpolate.griddata((xp,yp), z/max(z), (xi[None,:], yi[:,None]), method='cubic') fig, ax =plt.subplots(dpi=800) # 仅保留contourf绘图,避免重复 colormap=plt.contourf(xi,yi,zi,100, cmap='hot') fig.suptitle('Input Data Contour Map') plt.xlabel('$\phi$ (deg)') plt.ylabel('$\psi$ (deg)') plt.ylim(515, 540) plt.xlim(-85, 85) # 使用make_axes_locatable自动创建匹配的色条轴 divider = make_axes_locatable(ax) # 右侧添加色条轴,宽度为主图的5%,间距0.1 cax = divider.append_axes("right", size="5%", pad=0.1) plt.clim(0, 0.2) # 基于contourf的结果创建色条 plt.colorbar(colormap, cax=cax) plt.show() pp.close() # 记得关闭PDF文件,避免损坏
关键修改说明
- 移除了多余的
imshow调用,确保绘图逻辑统一,避免数据混淆 - 用
make_axes_locatable拆分主图轴,自动生成的色条轴会完全匹配主图的高度和位置,无需手动计算 - 将色条关联到
contourf返回的colormap对象,确保色条的色彩范围和绘图数据完全对应 - 调整色条宽度为
5%(相对主图宽度),并设置pad=0.1保证合理间距,视觉效果更协调 - 添加了
pp.close()确保PDF文件正常写入关闭
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

