Python使用matplotlib绘制热图时x轴标签被截断问题求解决方案
问题描述
我希望有人能帮我指出操作中的错误:我正在绘制尺寸为182×794的热图,但最终生成的图像x轴标签被截断,图中的点值看起来显示了部分甚至全部,很难明确判断。
生成的图像如下:
我的代码
from scipy.cluster.hierarchy import dendrogram, linkage import matplotlib.pyplot as plt from matplotlib import gridspec linked = linkage(hmapNP,'single') figure= plt.figure(figsize=(50,50)) gs1 = gridspec.GridSpec(2,7) gs1.update(wspace=0.01) ax1 = plt.subplot(gs1[0:-1, :2]) dendrogram(linked, orientation='left', distance_sort='descending',show_leaf_counts=True,no_labels=True) ax1.spines['left'].set_visible(False) ax1.spines['top'].set_visible(False) ax1.spines['right'].set_visible(False) ax2 = plt.subplot(gs1[0:-1,2:6]) f = ax2.imshow(hmapNP, cmap='PRGn_r', interpolation='nearest') ax2.set_title('Fingerprint Similarity',fontsize=20,weight='bold') ax2.set_xticks(range(len(meaNameTrueList))) ax2.set_yticks(range(len(drugNameTrueFinalList))) ax2.set_xticklabels(meaNameTrueList,rotation=90,size=6) ax2.set_yticklabels(drugNameTrueFinalList,rotation=45,size=6) ax3 = plt.subplot(gs1[0:-1,6:7]) m=plt.colorbar(f,cax=ax3,shrink=0.75,orientation='vertical',spacing='uniform',pad=0.01) m.set_label('Fingerprint Similarity') plt.tick_params('both',width=2) plt.plot()
变量hmapNP的形状为(182, 794),示例值如下:
array([[0.05633803, 0.0610687 , 0.06289308, ..., 0.06024096, 0.04411765, 0.06134969], [0.03947368, 0.07936508, 0.08888889, ..., 0.06060606, 0.05970149, 0.0625 ], [0.2 , 0.18055556, 0.08490566, ..., 0.17307692, 0.17333333, 0.10185185], ..., [0.0625 , 0.05970149, 0.075 , ..., 0.0591716 , 0.04316547, 0.06024096], [0.08333333, 0.12048193, 0.07894737, ..., 0.09243697, 0.07865169, 0.13392857], [0.07070707, 0.07954545, 0.06837607, ..., 0.06451613, 0.08888889, 0.08403361]])
解决方案
导致x轴标签被截断的核心原因有三点:
- 你使用的2行7列GridSpec布局第二行处于空置状态,没有给底部x轴标签预留足够的显示空间,且画布宽高比和热图本身的宽高比不匹配,挤压了标签的显示区域
- 没有调整子图底部边距,旋转90度的x轴标签延伸到了画布可视区域之外
- x轴标签没有设置对齐参数,和刻度的匹配存在偏移,进一步加剧了截断问题
修改后的代码如下:
from scipy.cluster.hierarchy import dendrogram, linkage import matplotlib.pyplot as plt from matplotlib import gridspec linked = linkage(hmapNP,'single') # 调整画布宽高比适配热图的宽高比(794:182≈4.36:1),避免拉伸挤压 figure = plt.figure(figsize=(70, 25)) # 改用1行7列的网格,不需要空置的第二行 gs1 = gridspec.GridSpec(1,7) gs1.update(wspace=0.01) ax1 = plt.subplot(gs1[:, :2]) dendrogram(linked, orientation='left', distance_sort='descending',show_leaf_counts=True,no_labels=True) ax1.spines[['left','top','right']].set_visible(False) ax2 = plt.subplot(gs1[:,2:6]) # 加aspect='auto'避免热图强制等比例拉伸 f = ax2.imshow(hmapNP, cmap='PRGn_r', interpolation='nearest', aspect='auto') ax2.set_title('Fingerprint Similarity',fontsize=20,weight='bold') ax2.set_xticks(range(len(meaNameTrueList))) ax2.set_yticks(range(len(drugNameTrueFinalList))) # 加ha='right'让旋转后的标签和刻度对齐更准确 ax2.set_xticklabels(meaNameTrueList, rotation=90, size=6, ha='right') ax2.set_yticklabels(drugNameTrueFinalList, rotation=45, size=6, va='center') ax3 = plt.subplot(gs1[:,6:7]) m=plt.colorbar(f,cax=ax3,shrink=0.75,orientation='vertical',spacing='uniform',pad=0.01) m.set_label('Fingerprint Similarity') plt.tick_params('both',width=2) # 调整底部边距给x轴标签留空间,可根据实际标签长度调整bottom的数值 figure.subplots_adjust(bottom=0.2) plt.show()
如果你的x轴标签本身长度差异很大,可以适当调大bottom的数值,或者进一步缩小xticklabels的字号,就能完全避免截断问题。
内容的提问来源于stack exchange,提问作者Anthony Nash
相关产品推荐
相关产品推荐

