news 2026/10/14 1:27:39

Matplotlib快速上手2:中文字体、布局与保存的完整出图指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Matplotlib快速上手2:中文字体、布局与保存的完整出图指南

1. 为什么第二篇才是真正开始上手的分水岭

很多人学Matplotlib的路径都差不多:找一篇入门教程,照着敲一遍折线图、柱状图、散点图的代码,跑出来觉得“哦,我会了”。然后第二天打开自己的数据,想画一个稍微像样点的图,瞬间卡住——中文显示成方块、图例挡住数据、子图挤成一团、保存出来模糊得没法看。这不是你笨,而是第一篇教程只教了“怎么让代码跑起来”,没教“怎么让图能用”。

“Matplotlib-快速上手-2”这个标题里的“2”,恰恰是整个学习路径中最关键的一步。第一篇解决的是“从零到一”,让你知道plt.plot()能画线、plt.show()能弹窗。第二篇要解决的是“从一到能用”,也就是把默认出图变成可交付的图表。这个阶段涉及的东西看起来零碎,但每一样都是实际工作中绕不开的:中文字体配置、画布与分辨率控制、子图布局、样式系统、坐标轴精细调整、图例与标注、保存输出。这些东西不掌握,你画出来的图永远停留在“草稿”级别。

我见过太多人卡在这个阶段。他们能跑通代码,但一到要给别人展示、要放进报告、要发到论文里,就发现图完全拿不出手。于是开始到处搜“Matplotlib中文乱码怎么解决”“Matplotlib子图间距怎么调”“Matplotlib保存图片模糊怎么办”,搜到的答案东一榔头西一棒子,拼凑起来勉强能用,但下次换个场景又不会了。根本原因是没有建立起一套完整的“出图工作流”认知。

这篇内容就是冲着这个痛点来的。我会把第二阶段的每一个关键环节拆开讲清楚:为什么要这么设置、参数背后的逻辑是什么、不同场景下该怎么选、有哪些坑是文档里不会写的。适合已经能跑通基础代码、但画出来的图总觉得“差点意思”的人。如果你连plt.plot()都还没敲过,建议先去看第一篇,否则这里的内容会让你觉得跳跃。但只要你跑通过哪怕一个最简单的图,这篇就能帮你把出图质量拉上一个台阶。

2. 中文字体配置:从方块到正常显示的完整方案

2.1 为什么默认显示不了中文

Matplotlib的默认字体是DejaVu Sans,这是一个开源字体,覆盖了拉丁字母、希腊字母、部分符号,但不包含中文字符。当你用默认配置画一个带中文标题的图时,Matplotlib找不到对应的字形,就会用一个方框(俗称“豆腐块”)来替代。这不是bug,是字体覆盖范围的问题。

解决思路很直接:告诉Matplotlib用一款包含中文字形的字体。但这里有几个层次的问题需要搞清楚。第一,你的系统里有哪些中文字体可用?第二,怎么让Matplotlib知道用哪个?第三,为什么有时候设置了还是不行?第四,负号显示异常是怎么回事?这四个问题层层递进,很多人只解决了第二个就以为完事了,结果遇到负号变方块又懵了。

先看系统字体。Windows系统自带黑体(SimHei)、微软雅黑(Microsoft YaHei)、宋体(SimSun)等;macOS自带苹方(PingFang SC)、华文黑体(STHeiti)等;Linux发行版差异较大,常见的有文泉驿系列、Noto Sans CJK等。你可以通过matplotlib.font_manager模块来查询系统里Matplotlib能识别到的字体。

from matplotlib import font_manager # 列出所有可用字体名称 font_names = [f.name for f in font_manager.fontManager.ttflist] # 去重后打印 for name in sorted(set(font_names)): print(name)

运行这段代码,你会看到一个长长的字体列表。在里面找找有没有你认识的中文字体。如果列表里完全没有中文字体,说明你的环境需要先安装字体文件,或者Matplotlib的字体缓存没更新。

2.2 三种配置方式与适用场景

配置中文字体有三种常见方式,各有适用场景,不是随便选一个就行。

第一种:全局配置。通过rcParams修改全局参数,一次设置,之后所有图都生效。适合在脚本开头统一设置,或者写在Jupyter Notebook的第一个单元格里。

import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体 plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题

这里font.sans-serif是一个字体列表,Matplotlib会按顺序查找,用第一个找到的。所以你可以写成['Microsoft YaHei', 'SimHei', 'PingFang SC'],这样在不同系统上都能尽量找到可用的字体。axes.unicode_minus设为False是因为很多中文字体里的减号字形和Matplotlib默认的Unicode减号不一致,导致负号显示为方块,关掉Unicode减号就用ASCII的连字符替代,虽然短一点但至少能正常显示。

第二种:局部指定。在具体的文本元素上通过fontproperties参数指定字体。适合一张图里需要混用不同字体的场景,比如标题用黑体、正文用宋体。

from matplotlib.font_manager import FontProperties font_title = FontProperties(fname='C:/Windows/Fonts/simhei.ttf', size=16) font_label = FontProperties(fname='C:/Windows/Fonts/simsun.ttc', size=12) fig, ax = plt.subplots() ax.set_title('销售趋势分析', fontproperties=font_title) ax.set_xlabel('月份', fontproperties=font_label) ax.set_ylabel('金额(万元)', fontproperties=font_label)

这种方式的好处是精确控制,不依赖全局设置。缺点是每次都要写字体路径,代码冗长。而且路径在不同系统上不一样,移植性差。所以一般只在有特殊排版需求时才用。

第三种:通过字体文件直接加载。用font_manager.fontManager.addfont()把字体文件注册到Matplotlib的字体管理器中,然后用字体名称引用。适合系统字体列表里没有但你手头有字体文件的场景。

from matplotlib import font_manager # 注册字体文件 font_manager.fontManager.addfont('/path/to/your/font.ttf') # 获取字体名称 prop = font_manager.FontProperties(fname='/path/to/your/font.ttf') print(prop.get_name()) # 打印出字体名称 # 然后用这个名称去设置rcParams plt.rcParams['font.sans-serif'] = [prop.get_name()]

这种方式在服务器环境或容器里特别有用,因为那些环境往往没有预装中文字体,你可以把字体文件打包进去。

2.3 实操心得与常见坑

说几个我踩过的坑。第一个坑是设置了字体但没生效。原因通常是Matplotlib的字体缓存没更新。你可以删除缓存目录(Windows在~/.matplotlib,Linux/macOS在~/.cache/matplotlib),然后重启Python内核。或者直接在代码里调用font_manager._rebuild()强制重建缓存。

第二个坑是Jupyter Notebook里设置了但图表还是方块。这通常是因为你在设置字体之前已经创建了图形对象,或者设置语句和绘图语句不在同一个单元格执行。解决办法是把字体设置放在最前面,并且确保执行顺序正确。

第三个坑是负号问题。即使你设置了中文字体,如果忘了axes.unicode_minus = False,坐标轴上的负数刻度还是会显示异常。这个参数一定要和字体设置一起写。

第四个坑是字体名称写错。比如把“SimHei”写成“simhei”在某些系统上可能找不到,因为字体名称是大小写敏感的。最稳妥的方式是用前面说的字体列表查询代码,把名称复制出来用。

提示:如果你在团队协作或跨平台部署,建议把字体设置封装成一个函数,在项目入口处调用。这样换环境时只需要改一处。

3. 画布、分辨率与保存:让出图质量可控

3.1 figsize与dpi的配合逻辑

figsize控制画布的物理尺寸,单位是英寸;dpi控制每英寸的像素数。两者相乘就是最终图像的像素尺寸。比如figsize=(10, 6)配合dpi=100,得到的图像是1000×600像素。如果dpi=300,就是3000×1800像素。

很多人不重视这两个参数,用默认值出图,结果要么太小看不清,要么保存出来模糊。默认的figsize是(6.4, 4.8),dpi是100,对于屏幕预览够用,但放到文档里就偏小。我的经验是:屏幕展示用figsize=(10, 6)、dpi=100;文档插入用figsize=(8, 5)、dpi=200;印刷出版用figsize=(6, 4)、dpi=300以上。

这里有个容易混淆的点:dpi在plt.figure()里设置和在plt.savefig()里设置是两回事。前者影响交互显示和默认保存,后者只影响保存时的输出。如果你在savefig时指定了更高的dpi,保存出来的图会更清晰,但屏幕上看到的还是原来的分辨率。所以建议在创建图形时就设定好dpi,保持所见即所得。

fig, ax = plt.subplots(figsize=(10, 6), dpi=150) ax.plot([1, 2, 3, 4], [10, 20, 25, 30]) ax.set_title('季度营收趋势') fig.savefig('revenue_trend.png', dpi=300, bbox_inches='tight')

注意savefig里的bbox_inches='tight',这个参数会自动裁剪掉图形周围的空白边距,让保存出来的图更紧凑。不加这个参数,默认会保留一圈白边,插入文档时显得松散。

3.2 保存格式的选择与参数

Matplotlib支持多种输出格式,常用的有PNG、JPG、SVG、PDF。选择哪种取决于用途。

格式适用场景特点
PNG网页、文档、演示无损压缩,支持透明背景,文件适中
JPG照片类图像、邮件有损压缩,文件小,但不适合线条图
SVG网页、矢量编辑矢量格式,无限缩放不失真,文件小
PDF论文、印刷矢量格式,排版友好,支持字体嵌入

对于数据图表,我强烈推荐优先用SVG或PDF。因为图表本质上是线条和文字,矢量格式能保证在任何缩放下都清晰锐利。PNG虽然方便,但放大后会模糊。如果必须用位图,那就把dpi设高一点。

保存时还有几个参数值得注意。transparent=True可以输出透明背景,适合把图叠加到其他背景上。facecolor可以指定背景色,默认是白色。pad_inches控制bbox_inches='tight'时的留白大小,默认是0.1英寸。

# 保存为矢量PDF,适合论文 fig.savefig('chart.pdf', format='pdf', bbox_inches='tight') # 保存为透明背景PNG,适合做PPT fig.savefig('chart.png', transparent=True, dpi=200, bbox_inches='tight')

3.3 实操心得:分辨率与文件大小的平衡

这里有个实际问题:dpi设太高,文件会很大。一张A4大小的图,dpi=600的PNG可能超过10MB,插入文档后打开很卡。我的做法是:先确定最终使用场景,再倒推参数。如果是网页展示,dpi=72到100足够;如果是Word文档,dpi=150到200;如果是印刷,dpi=300起步。不要盲目追求高分辨率,够用就行。

另一个技巧是先用低dpi调试,确定最终效果后再用高dpi保存。因为高dpi渲染慢,调试阶段没必要浪费时间。你可以把dpi设成一个变量,调试时用100,出图时改成300。

注意:Jupyter Notebook里用%matplotlib inline时,图形显示的分辨率由rcParams['figure.dpi']控制,和savefig的dpi是独立的。如果发现Notebook里显示的图模糊,调figure.dpi;如果保存出来的图模糊,调savefig的dpi。

4. 子图布局:从挤成一团到整齐排列

4.1 subplots与subplot_mosaic的选择

画多个子图,最基础的方式是plt.subplots(nrows, ncols),返回一个figure对象和一个axes数组。这种方式适合规整的网格布局,比如2×2、3×1。但如果你的布局不规则,比如上面一张大图、下面两张小图,用subplots就需要手动调整位置,很麻烦。

Matplotlib 3.4之后引入了subplot_mosaic,用字符串来描述布局,非常直观。比如:

fig, axes = plt.subplot_mosaic([ ['top', 'top'], ['left', 'right'] ], figsize=(10, 8))

这段代码创建了一个布局:上面一行是横跨两列的top,下面一行是left和right。然后你可以通过axes['top']、axes['left']、axes['right']来访问各个子图。这种方式比subplots灵活得多,代码也更易读。

我现在的习惯是:规整网格用subplots,不规则布局用subplot_mosaic。subplot_mosaic几乎能表达所有常见的布局需求,而且不用去算坐标位置。

4.2 间距调整与共享坐标轴

子图挤在一起是新手最常见的问题。默认的间距往往不够,标题和x轴标签会重叠。解决办法是fig.tight_layout()或者fig.subplots_adjust()。

tight_layout()会自动计算合适的间距,简单省事。但它有时候会忽略一些元素,比如suptitle(总标题)。这时候可以用constrained_layout,在创建figure时指定layout='constrained',效果通常比tight_layout更好。

# 方式一:tight_layout fig, axes = plt.subplots(2, 2, figsize=(10, 8)) # ... 绘图代码 ... fig.tight_layout() # 方式二:constrained_layout fig, axes = plt.subplots(2, 2, figsize=(10, 8), layout='constrained') # ... 绘图代码 ...

subplots_adjust()则是手动指定各个方向的间距,参数包括left、right、top、bottom、wspace(水平间距)、hspace(垂直间距)。适合需要精确控制的场景。

fig.subplots_adjust(left=0.1, right=0.95, top=0.9, bottom=0.1, wspace=0.3, hspace=0.4)

共享坐标轴是另一个实用功能。当多个子图的x轴或y轴范围相同时,可以用sharex=True或sharey=True来共享,这样只会在边缘显示刻度标签,图面更干净。

fig, axes = plt.subplots(2, 1, figsize=(8, 6), sharex=True)

4.3 实操心得:布局调试的笨办法

布局调试没有捷径,就是反复预览、反复调整。我的做法是先把所有子图画出来,用tight_layout()跑一遍看效果,哪里重叠了就手动调subplots_adjust的参数。调的时候不要一次改太多,每次改一个参数,看变化。

还有一个技巧是给子图加标题时用ax.set_title()而不是plt.title()。后者只对当前活跃的axes生效,在多个子图场景下容易搞错对象。用ax.set_title()明确指定是哪个子图,代码更清晰。

如果子图数量很多,比如超过6个,建议考虑拆成多张图,而不是硬塞在一张图里。图太密了读者根本看不清,不如分成两张,每张信息量适中。

5. 样式系统:一行代码改变整体观感

5.1 style sheet的用法与内置样式

Matplotlib内置了一套样式系统,通过plt.style.use()可以一键切换整体风格。内置样式有几十种,常用的有ggplot、seaborn-v0_8、fivethirtyeight、bmh、dark_background等。

plt.style.use('ggplot') # 之后画的图都会用ggplot风格

你可以用plt.style.available查看所有可用样式。不同样式主要改变的是背景色、网格线、字体、颜色循环等。比如ggplot风格有灰色背景和白色网格线,fivethirtyeight风格有粗线条和简洁的坐标轴。

样式的作用范围是全局的,设置之后所有图都生效。如果只想对某一张图用特定样式,可以用上下文管理器:

with plt.style.context('dark_background'): fig, ax = plt.subplots() ax.plot([1, 2, 3], [4, 5, 6])

这样只在with块内生效,出了块就恢复原来的样式。

5.2 自定义rcParams:精细控制

样式表本质上是一组rcParams的预设。如果你想精细控制,可以直接修改rcParams。常用的参数包括:

  • figure.figsize:默认画布尺寸
  • figure.dpi:默认分辨率
  • font.size:全局字体大小
  • axes.titlesize:标题字号
  • axes.labelsize:轴标签字号
  • lines.linewidth:线宽
  • lines.markersize:标记大小
  • axes.grid:是否显示网格
  • axes.spines.top/right:是否显示上/右边框
plt.rcParams.update({ 'font.size': 12, 'axes.titlesize': 16, 'axes.labelsize': 14, 'lines.linewidth': 2, 'axes.grid': True, 'grid.alpha': 0.3, 'axes.spines.top': False, 'axes.spines.right': False })

这套配置是我常用的“简洁风”:去掉上右边框、加淡网格、字号适中。你可以根据自己的审美调整,关键是形成一套固定的配置,每次项目开头就设置好,这样出图风格统一,不用每次重新调。

5.3 实操心得:样式配置的复用策略

我建议把常用的样式配置写成一个.mplstyle文件,放在项目目录里,然后用plt.style.use('path/to/your.mplstyle')加载。.mplstyle文件就是纯文本,每行一个参数: 值,写起来很简单。

font.size: 12 axes.titlesize: 16 axes.labelsize: 14 lines.linewidth: 2 axes.grid: True grid.alpha: 0.3 axes.spines.top: False axes.spines.right: False

这样做的好处是配置和代码分离,换项目时只需要改样式文件,不用动代码。团队协作时也可以共享同一个样式文件,保证所有人出图风格一致。

提示:rcParams的修改是全局的,会影响到之后创建的所有图形。如果你在Notebook里先设了一套参数,后面又设了另一套,后面的会覆盖前面的。所以建议在Notebook开头统一设置,中途不要随意改。

6. 坐标轴、图例与标注的精细调整

6.1 坐标轴范围、刻度与标签

默认的坐标轴范围是Matplotlib根据数据自动计算的,但很多时候你需要手动指定。ax.set_xlim()和ax.set_ylim()可以设置范围,ax.set_xticks()和ax.set_yticks()可以设置刻度位置,ax.set_xticklabels()可以设置刻度标签。

ax.set_xlim(0, 12) ax.set_ylim(0, 100) ax.set_xticks(range(1, 13)) ax.set_xticklabels(['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], rotation=45, ha='right')

这里rotation=45让标签旋转45度,避免重叠;ha='right'让标签右对齐,旋转后看起来更整齐。这是处理长标签的常用组合。

刻度还有主刻度和次刻度之分。ax.minorticks_on()可以开启次刻度,ax.tick_params()可以分别设置主次刻度的样式。

ax.minorticks_on() ax.tick_params(axis='both', which='major', length=6, width=1.5) ax.tick_params(axis='both', which='minor', length=3, width=1)

6.2 图例的位置、样式与多图例

图例用ax.legend()添加。位置通过loc参数控制,常用的有'upper right'、'upper left'、'lower right'、'lower left'、'center'、'best'。'best'会让Matplotlib自动选择遮挡最少的位置,但计算需要时间,数据量大时可能慢。

ax.legend(loc='upper right', frameon=True, framealpha=0.9, edgecolor='gray', fontsize=10, title='图例标题')

frameon控制是否显示图例边框,framealpha控制边框透明度,edgecolor控制边框颜色。如果图例挡住了数据,可以设framealpha=0.8让它半透明,或者用bbox_to_anchor把图例放到图外。

ax.legend(loc='upper left', bbox_to_anchor=(1.02, 1), borderaxespad=0)

这段代码把图例放到坐标轴右侧外面,配合fig.tight_layout()可以自动调整边距,避免图例被裁掉。

一张图里如果有多个图例(比如不同来源的数据),可以多次调用legend(),但需要手动把第一个图例加回去,因为第二次调用会覆盖第一个。

legend1 = ax.legend(handles=[line1], labels=['数据集A'], loc='upper left') ax.add_artist(legend1) # 手动加回第一个图例 ax.legend(handles=[line2], labels=['数据集B'], loc='lower right')

6.3 标注:让关键数据点说话

标注用ax.annotate(),可以在图上加箭头和文字,指向特定的数据点。参数比较多,但核心就几个:text是标注文字,xy是箭头指向的坐标,xytext是文字位置,arrowprops控制箭头样式。

ax.annotate('峰值', xy=(6, 95), xytext=(7, 80), arrowprops=dict(arrowstyle='->', color='red', lw=1.5), fontsize=12, color='red')

arrowstyle有多种样式,常用的有'->'(简单箭头)、'fancy'(带边框的箭头)、'-|>'(实心三角箭头)。connectionstyle可以控制箭头的弯曲程度,比如'arc3,rad=0.2'会让箭头带一点弧度。

如果只是想在某个位置加文字,不需要箭头,可以用ax.text():

ax.text(6, 95, '峰值', fontsize=12, ha='center', va='bottom', color='red')

ha是水平对齐('left'、'center'、'right'),va是垂直对齐('top'、'center'、'bottom')。这两个参数决定了文字相对于指定坐标的位置。

6.4 实操心得:标注不要过度

标注是个双刃剑。用得好,读者一眼就能看到重点;用得不好,图面杂乱,反而干扰阅读。我的原则是:一张图上的标注不超过3个,只标最关键的转折点、峰值、异常值。其他数据点让读者自己看。

另外,标注文字要简短,能用两个字说清楚就不用一句话。颜色要和背景有足够对比,但不要用太刺眼的颜色。箭头不要太粗,lw=1到1.5就够了。

注意:annotate的xy坐标是数据坐标,不是像素坐标。如果你缩放或平移了坐标轴,标注会跟着数据点走,这是正确的行为。但如果你想让标注固定在某个屏幕位置,需要用xycoords='axes fraction',坐标范围变成0到1。

7. 常见问题与排查技巧实录

7.1 中文显示问题速查表

现象可能原因解决方法
中文显示为方块未设置中文字体设置rcParams['font.sans-serif']
设置了字体仍显示方块字体缓存未更新删除缓存目录或调用_rebuild()
负号显示为方块Unicode减号与字体不兼容设置rcParams['axes.unicode_minus'] = False
部分中文正常部分方块字体覆盖不全换一款覆盖更全的字体
Jupyter中设置无效执行顺序问题把字体设置放在绘图代码之前

7.2 布局问题排查

子图重叠、标签被裁、图例遮挡,这些问题几乎每个人都会遇到。排查思路是:先看是哪个元素出了问题,再针对性调整。

如果是标题和上方子图重叠,用fig.suptitle()加总标题时指定y参数调整位置,或者用constrained_layout。如果是x轴标签被裁掉,用bbox_inches='tight'保存,或者调subplots_adjust(bottom=0.15)。如果是图例遮挡数据,把图例移到图外,或者调framealpha让它半透明。

# 总标题位置调整 fig.suptitle('总标题', y=0.98, fontsize=16) # 底部留白增加 fig.subplots_adjust(bottom=0.15)

7.3 保存问题排查

保存出来是空白、保存的图和显示的不一样、保存后字体变了,这些问题的根源通常是保存时的参数和创建图形时的参数不一致。

保存空白通常是因为在savefig之前调用了plt.show(),show()会清空当前图形。解决办法是先保存再显示,或者用fig.savefig()而不是plt.savefig()。

保存的图和显示的不一样,通常是因为savefig的dpi和figure.dpi不同。建议在创建图形时就设定好dpi,保存时不额外指定,保持一致性。

保存后字体变了,通常是因为保存为PDF时字体没有嵌入。可以在savefig时指定pdf.fonttype=42,让字体以TrueType格式嵌入。

plt.rcParams['pdf.fonttype'] = 42 plt.rcParams['ps.fonttype'] = 42

7.4 实操心得:建立自己的排查清单

踩坑多了之后,我总结了一个排查顺序:先看字体,再看布局,最后看保存。因为字体问题最明显,布局问题次之,保存问题往往在最后一步才发现。每次出图前按这个顺序检查一遍,能省不少时间。

另外,建议养成保存中间版本的习惯。调布局的时候,每改一次就保存一张图,文件名带上版本号。这样如果改坏了,可以回退到上一个版本,不用从头再来。

8. 从能跑到能看:一个完整的出图模板

把前面讲的东西串起来,形成一个可以直接复用的模板。这个模板涵盖了字体设置、画布配置、样式调整、子图布局、保存输出,适合大多数日常出图场景。

import matplotlib.pyplot as plt import matplotlib as mpl # 1. 全局配置 mpl.rcParams.update({ 'font.sans-serif': ['Microsoft YaHei', 'SimHei', 'PingFang SC'], 'axes.unicode_minus': False, 'font.size': 12, 'axes.titlesize': 16, 'axes.labelsize': 14, 'lines.linewidth': 2, 'axes.grid': True, 'grid.alpha': 0.3, 'axes.spines.top': False, 'axes.spines.right': False, 'figure.dpi': 100, 'savefig.dpi': 300, 'pdf.fonttype': 42 }) # 2. 创建图形 fig, axes = plt.subplots(2, 2, figsize=(12, 8), layout='constrained') # 3. 绘图(示例) x = [1, 2, 3, 4, 5] y1 = [10, 20, 25, 30, 28] y2 = [15, 18, 22, 27, 35] axes[0, 0].plot(x, y1, marker='o', label='产品A') axes[0, 0].set_title('产品A趋势') axes[0, 0].legend() axes[0, 1].plot(x, y2, marker='s', color='orange', label='产品B') axes[0, 1].set_title('产品B趋势') axes[0, 1].legend() axes[1, 0].bar(x, y1, color='steelblue') axes[1, 0].set_title('产品A季度对比') axes[1, 1].scatter(y1, y2, s=80, alpha=0.7) axes[1, 1].set_title('A与B相关性') # 4. 总标题 fig.suptitle('产品数据分析看板', fontsize=18, y=1.02) # 5. 保存 fig.savefig('dashboard.png', bbox_inches='tight') fig.savefig('dashboard.pdf', bbox_inches='tight') plt.show()

这个模板可以直接拿去改数据和标题,适合做周报、月报、分析报告。关键点是配置在前、绘图在中、保存在后,顺序不要乱。另外layout='constrained'省去了手动调间距的麻烦,bbox_inches='tight'保证保存时不裁掉元素。

我个人在实际操作中的体会是,Matplotlib的第二阶段学习,核心不是记住多少参数,而是建立起一套可复用的出图流程。字体、画布、布局、样式、保存,这五个环节每个都有坑,但每个坑踩过一次之后,把它固化到模板里,下次就不用再想了。真正花时间的不是画图本身,而是调格式。把格式调好了,数据分析和展示的效率会高很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 1:27:06

陌生代码库先啃数据预处理:second项目数据管道拆解与调试实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 1:27:05

Linux x86_64汇编实现字符串比较:从CMPSB到REPE详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 1:26:34

三路电流采样零点校准与电流换算的工程实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 1:26:30

Linux内核slub_debug内存调试原理与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 1:26:25

基于STM32的多参数环境检测终端:从传感器选型到云平台对接

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 1:26:17

RT-Thread自动初始化机制:链接段与函数指针的启动解耦实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华