解决Matplotlib子图变形:通过调整画布大小自适应子图布局
本文介绍在Matplotlib中绘制多个子图时,因子图数量少导致图像拉伸变形的常见问题。核心解决方案是保持子图不变,通过增大整体画布(figure)尺寸,使子图根据新画布大小自适应显示,从而避免图像变形。
此前曾遇到此问题,一直未及整理,现于夜间进行总结。
问题
阅读此文者应已掌握Matplotlib中pyplot的基本绘图功能。
例如生成如下单图。

同时,你也应熟悉如何控制单个图形(figure)的尺寸,例如设定为8x6。
fig3 = plt.figure(figsize=(8,6))随着学习深入,常需将多张图置于同一画布以进行对比,即在一个画布上绘制多个子图,效果如上图所示。

这通常通过subplot实现。
#展示一下数据
fig = plt.figure(figsize=(15,7))
fig1 = plt.subplot(231)
plt.scatter(data.loc[:,'Avg. Area Income'],data.loc[:,'Price'])
plt.title('Income VS Price')
fig2 = plt.subplot(232)
plt.scatter(data.loc[:,'Avg. Area House Age'],data.loc[:,'Price'])
plt.title('Age VS Price')
fig3 = plt.subplot(233)
plt.scatter(data.loc[:,'Avg. Area Number of Rooms'],data.loc[:,'Price'])
plt.title('Number VS Price')
fig4 = plt.subplot(234)
plt.scatter(data.loc[:,'Area Population'],data.loc[:,'Price'])
plt.title('Population VS Price')
fig5 = plt.subplot(235)
plt.scatter(data.loc[:,'size'],data.loc[:,'Price'])
plt.title('size VS Price')
plt.show()目前看来图形似乎无异常,但问题在于当子图数量较少时,整个图形可能发生变形,出现如下情况。

这并非预期效果,我们期望图形保持比例不被拉长。然而,直接通过subplot生成的子图似乎难以直接修改大小,且网上提供的部分解决方案较为繁琐。
简便的解决方法
将两个子图置于同一画布中,即使子图本身无法直接调整大小,通过改变外部画布的尺寸,子图即可根据新画布大小自适应显示。
针对该图。

其原始代码为。
fig6 = plt.subplot(121)
label0 = plt.scatter(X.loc[:,'V1'][y_corrected==0],X.loc[:,'V2'][y_corrected==0])
label1 = plt.scatter(X.loc[:,'V1'][y_corrected==1],X.loc[:,'V2'][y_corrected==1])
label2 = plt.scatter(X.loc[:,'V1'][y_corrected==2],X.loc[:,'V2'][y_corrected==2])
plt.title("corrected data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
fig7 = plt.subplot(122)
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])
plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
plt.show()可见,fig6和fig7均直接使用subplot生成,因此导致变形。
修改后的代码应如下所示。

对应代码:
fig = plt.figure(figsize=(11,4))
fig6 = plt.subplot(121)
label0 = plt.scatter(X.loc[:,'V1'][y_corrected==0],X.loc[:,'V2'][y_corrected==0])
label1 = plt.scatter(X.loc[:,'V1'][y_corrected==1],X.loc[:,'V2'][y_corrected==1])
label2 = plt.scatter(X.loc[:,'V1'][y_corrected==2],X.loc[:,'V2'][y_corrected==2])
plt.title("corrected data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
fig7 = plt.subplot(122)
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])
plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
plt.show()相较于原代码,仅增加了第一行的操作,设定合适的画布大小即可方便地动态调整子图。
麻烦点的方法
网上存在自定义子图大小的方法,但相比本文提出的方案显得更为繁琐。该方法可解决此类问题,若后续遇到需不同大小子图的情况,将另行记录。
总结
至此,关于调整Matplotlib子图大小的介绍结束。如需了解更多相关调整内容,请搜索本站历史文章或浏览相关文章,感谢支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









