plt.savefig()保存图像时裁剪色标下标字符的问题求助
解决Matplotlib保存水平色标时下标被裁剪的问题
嘿,这个问题我太熟悉了!Matplotlib的bbox_inches="tight"有时候对LaTeX格式的下标这类特殊字符的边界识别不太到位,尤其是水平色标这种情况——手动保存窗口没问题是因为窗口会实时调整布局,但savefig的自动裁剪会漏掉下标部分。你试过的换行和labelpad只是调整了标签内部或标签与色标的距离,没从根本上让绘图引擎把下标纳入整体边界计算。
下面给你几个靠谱的解决办法:
方法1:用bbox_extra_artists指定色标元素
bbox_inches="tight"默认可能没把色标(ColorbarBase对象)完全纳入边界计算,我们可以手动把色标加入bbox_extra_artists参数,确保保存时包含它的完整标签:
修改你的保存代码部分:
# 在创建色标后,先让tight_layout调整布局 fig.tight_layout() # 保存时指定bbox_extra_artists包含色标对象 plt.savefig("C:/Users/Christopher/Desktop/test.png", dpi=1200, bbox_inches="tight", bbox_extra_artists=[cb])
方法2:手动调整底部边距
如果方法1效果不够,你可以直接给整个图表调整底部留白,给下标留出足够空间:
# 在创建色标后,调整子图布局的底部边距 plt.subplots_adjust(bottom=0.2) # 数值可以根据实际情况调整,0.2是示例 plt.savefig("C:/Users/Christopher/Desktop/test.png", dpi=1200, bbox_inches="tight")
方法3:使用constrained_layout(推荐)
Matplotlib 3.0+的constrained_layout比旧的tight_layout更智能,能自动处理元素的边界,包括LaTeX格式的文本。你可以在创建子图时就开启它:
# 创建子图时开启constrained_layout fig, ax = plt.subplots(constrained_layout=True)
然后直接保存即可,不需要额外设置bbox_inches="tight"(当然加上也没问题):
plt.savefig("C:/Users/Christopher/Desktop/test.png", dpi=1200)
完整修改后的示例代码(用方法3)
import numpy import random import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.patches as patches import matplotlib.colors as mcolors import matplotlib.colorbar as cbar from matplotlib import cm ########################################################## # Centre colourmap so 0=white class MidpointNormalize(mpl.colors.Normalize): def __init__(self,vmin=None,vmax=None,midpoint=None,clip=False): self.midpoint=midpoint mpl.colors.Normalize.__init__(self,vmin,vmax,clip) def __call__(self,value,clip=None): x,y=[self.vmin,self.midpoint,self.vmax],[0,0.5,1] return numpy.ma.masked_array(numpy.interp(value,x,y),numpy.isnan(value)) ########################################################## # Set min and max values xymin=0 xymax=10 valmin=-5 valmax=5 val=numpy.zeros((xymax,xymax),dtype=float) # Configure plot - 开启constrained_layout fig,ax=plt.subplots(constrained_layout=True) ax.set_xlim([xymin,xymax]) ax.set_ylim([xymin,xymax]) # Configure colour bar colours=plt.cm.RdBu(numpy.linspace(0,1,256)) colourmap=mcolors.LinearSegmentedColormap.from_list('colourmap',colours) normalisecolors=mpl.colors.Normalize(vmin=valmin,vmax=valmax) scalecolors=cm.ScalarMappable(norm=normalisecolors,cmap=colourmap) label="$U/U_{"+(u"\u221e")+"}$" for ix in range(xymin,xymax): for iy in range(xymin,xymax): xlow=ix*+1 # Calculate vertices of patch xhigh=(ix*1)+1 ylow=iy*1 yhigh=(iy*1)+1 val[ix][iy]=random.randint(valmin,valmax) # Patch value rgbacolor=scalecolors.to_rgba(val[ix][iy]) # Calculate RGBA colour for value ax.add_patch(patches.Polygon([(xlow,ylow),(xlow,yhigh),(xhigh,yhigh),(xhigh,ylow)],fill=True,facecolor=rgbacolor)) # Add value as polygon patch cax,_=cbar.make_axes(ax,orientation="horizontal") cb=cbar.ColorbarBase(cax,cmap=colourmap,norm=MidpointNormalize(midpoint=0,vmin=valmin,vmax=valmax),orientation="horizontal",label=label) plt.savefig("C:/Users/Christopher/Desktop/test.png",dpi=1200) plt.clf() plt.close()
这个修改后的代码用了constrained_layout=True,它会自动识别色标标签的下标并预留足够空间,保存的图片下标就不会被裁剪了。
内容的提问来源于stack exchange,提问作者chrisprt
相关产品推荐
相关产品推荐

