如何设置plotnine导出PNG文件的固定整体物理尺寸
plotnine 底层基于matplotlib实现,save() 方法默认传入的 height、width 参数,控制的是**绘图轴域(即实际绘制几何图形的axes区域)**的尺寸,而非包含标题、坐标轴标签、图例、边距在内的整个画布(figure)尺寸。
标题、轴标签、图例这类元素都属于画布范围内、轴域之外的内容,默认排版逻辑下会自动占用额外空间,再配合matplotlib默认的边缘紧凑裁剪规则,最终导出的文件实际尺寸就会和你传入的参数值有偏差。你示例中3张图尺寸不一致,就是因为三张图的外围元素多少不同:fig1保留了轴标签和图例,fig2去掉了轴标签,fig3连图例也隐藏了,自动裁剪后的最终画布大小自然不统一,不是尺寸参数本身是近似值。
两种方法都可以实现不管外围元素怎么调整,最终导出的PNG物理尺寸完全精准匹配设定值:
方法1:通过主题参数全局锁定画布尺寸
在绘图流程中通过theme指定figure_size参数,直接锁定整个画布的尺寸,注意plotnine该参数的默认单位是英寸,需要把你需要的厘米值做单位转换(1英寸=2.54厘米):
import pandas as pd from plotnine import * from plotnine.data import mpg path = 'C:\\Users\\BRB\\' # 设定目标尺寸:12cm宽,10cm高,转换为英寸 target_width_cm = 12 target_height_cm = 10 target_width_in = target_width_cm / 2.54 target_height_in = target_height_cm / 2.54 # fig1 带轴标签和图例 p1 = (ggplot(mpg, aes(x='displ', y='hwy', colour='factor(cyl)')) + geom_point() # 核心:锁定画布尺寸 + theme(figure_size=(target_width_in, target_height_in)) ) p1.save(filename=path+'fig1_fixed.png', dpi=300) # fig2 隐藏轴标签 p2 = (ggplot(mpg, aes(x='displ', y='hwy', colour='factor(cyl)')) + geom_point() + labs(x=None,y=None) + theme(figure_size=(target_width_in, target_height_in)) ) p2.save(filename=path+'fig2_fixed.png', dpi=300) # fig3 隐藏轴标签和图例 p3 = (ggplot(mpg, aes( x='displ', y='hwy', colour='factor(cyl)')) + geom_point() + labs(x=None,y=None) + scale_color_discrete(guide=False) + theme(figure_size=(target_width_in, target_height_in)) ) p3.save(filename=path+'fig3_fixed.png', dpi=300)
该方式下所有外围元素都会被限制在固定尺寸的画布内排版,不会改动画布本身大小,导出的文件插入Word后尺寸会完全匹配你设定的12cm×10cm。如果出现标签、图例被截断的问题,调整plot_margin参数预留足够边距即可,不要改动画布尺寸,例如+ theme(plot_margin=0.4),该参数单位为厘米。
方法2:保存时通过参数强制锁定输出尺寸
如果不想修改绘图主题,可以在调用save()方法时传入参数,指定整个画布的尺寸,同时配置裁剪规则让所有元素都被纳入固定尺寸范围内:
p.save( filename=path+'fig_fixed.png', dpi=300, width=target_width_in, height=target_height_in, units='in', bbox_inches='tight', pad_inches=0 )
该配置会先计算所有图表元素(含标题、标签、图例)的占用空间,再将全部内容等比缩放到你指定的宽高尺寸,最终导出的文件尺寸同样精准。
- 不要同时在
theme(figure_size=...)和save()方法中传入不同的宽高值,会出现参数覆盖导致尺寸不符合预期,优先选择其中一种方式设置即可。 - 单位转换不要出错:直接传厘米值给默认以英寸为单位的参数,会导致最终尺寸偏差2.54倍。
- 固定尺寸后如果元素排版拥挤,优先调整字号、边距、图例位置,不要改动画布尺寸,才能保证系列图表插入文档时尺寸完全统一,不需要额外缩放。
内容的提问来源于stack exchange,提问作者brb

