Jupyter Notebook 里如何正确绘制并显示 Matplotlib 图表

Leo
Leo
发布时间:2026-08-25| 58人浏览过
原创

前言

很多人以为在 Jupyter Notebook 里画不出 Matplotlib 图,是函数没写对;其实更常见的原因,是显示后端、中文字体和子图对象的配置顺序出了问题。本文按实际使用场景梳理几个最容易踩坑的环节,帮你快速判断图表不显示、中文乱码和多子图混乱分别该从哪里排查。

很多人在 Jupyter Notebook 里第一次画 Matplotlib 图时,代码看起来没问题,结果却遇到图不显示、中文标题变方框,或者子图标签挤在一起的情况。真正影响结果的,通常不是绘图函数本身,而是显示模式有没有先启用、全局配置有没有在正确时机设置,以及你到底是在操作当前图还是明确的 axes 对象;下面就按这几个最容易踩坑的点逐一拆开。

%matplotlib inline 为什么要先执行

在 Jupyter Notebook 里,%matplotlib inline 不是装饰性写法,而是让图表直接渲染到单元格输出区的前提。少了这一步,plt.show() 可能弹出新窗口,也可能什么都不显示,尤其是在远程服务器、Docker 或 JupyterLab 里更常见。

用便签和箭头说明 Jupyter Notebook 里 Matplotlib 图表显示的前置顺序
图表显示先看后端顺序先启用 inline,再进入绘图,是 Notebook 中图表正常显示的基础顺序。
  • %matplotlib inline 要放在第一个绘图单元格的最上方,而且必须单独成行,不能和 import 写在同一行。
  • 执行后,当前内核的绘图后端状态会改变,之后像 plt.plot()、plt.scatter() 这类调用都会自动渲染到当前单元格。
  • 如果你已经运行过绘图代码但没看到图,不要只补跑 plt.show(),而是先确认这行是否漏写,再重新运行整个绘图单元格。
  • %matplotlib notebook 并不适合作为通用替代,它依赖浏览器端 JavaScript 支持,在 GitHub Codespaces、Kaggle 这类云环境里经常报错或白屏。

也就是说,Notebook 里的显示问题,第一步不是检查 plot 参数,而是先看后端有没有在绘图前进入 inline 模式。

inline 模式下还要不要写 plt.show()

启用 %matplotlib inline 后,Matplotlib 通常会在单元格末尾自动完成渲染。这种情况下,很多示例里继续写 plt.show() 并非必需,反而可能带来重复输出或空白图的问题。

%matplotlib inline
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 2])
  • 上面这段代码已经足够在 Notebook 中显示图表,不需要再补一行 plt.show()。
  • 如果你在 inline 模式下强行调用 plt.show(),有时会让同一张图被触发两次渲染,表现成重复输出,或者多出一个空图框。
  • 只有在非 inline 后端,比如 QtAgg,或者你需要手动控制显示时机时,plt.show() 才更有必要。
  • 如果目标是保存图像,直接用 fig.savefig("xxx.png") 即可,不依赖 plt.show()。

判断标准可以很简单:如果图表是为了在 Notebook 单元格里直接看结果,通常依赖自动渲染就够了;如果是桌面窗口交互或特殊显示流程,再考虑显式调用 plt.show()。

中文显示异常,关键在 rcParams 的设置时机

标题、坐标轴标签一写中文就出现方框、空白或者负号显示异常,这基本都不是文本内容的问题,而是 Matplotlib 默认字体配置不支持中文,或者配置写得太晚。

更稳妥的做法,是在导入 pyplot 之后、任何绘图命令之前就把字体和负号规则设好:

import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei", "KaiTi", "DejaVu Sans"]
plt.rcParams["axes.unicode_minus"] = False
  • plt.rcParams 属于全局配置,设一次即可影响后续绘图。
  • 但如果你先画图、后改配置,已经生成的 Axes 通常不会自动按新字体重绘,所以“第二次才正常”这类现象很常见。
  • 如果你还会调用 plt.style.use("seaborn-whitegrid"),也要注意它可能覆盖部分 rcParams,因此风格设置最好同样提前完成。
  • 即使用的是 plt.subplots() 来创建 figure 和 axes,中文配置也仍然应该在前面完成,否则 axes 初始化时拿到的还是默认字体环境。

很多人以为中文乱码是“缺一个字体包”,其实更常见的原因是配置顺序错了。字体有没有装是一层,什么时候生效是另一层,两者都要对上。

多子图场景里,为什么推荐 plt.subplots()

只画一张简单折线图时,直接写 plt.plot() 问题不大;但一旦涉及多子图、局部标签设置、间距调整或复杂布局,继续依赖隐式状态就容易把代码写乱。这个时候,显式拿到 fig 和 axes 会更稳定。

用卡片对比 rcParams 与 axes 写法,说明中文显示与子图控制的关键区别
中文配置与子图控制两条主线中文配置要早,子图控制要明确对象,才能减少 Notebook 中最常见的绘图混乱。
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(x, y)
ax.set_xlabel("时间")
ax.set_ylabel("数值")
  • plt.plot() 属于隐式绘图,操作默认作用在当前 active axes 上;而 ax.plot() 是明确告诉 Matplotlib 该往哪个子图里画。
  • 不建议混用 plt.xlabel() 和 ax.set_xlabel()。前者修改“当前图”,后者修改“指定图”,一旦有多个子图,冲突就很难排查。
  • plt.subplots(nrows=2, ncols=2) 返回的是 axes 数组,常见访问方式是 axes[0, 1] 或 axes[1],而不是把它当成通用嵌套列表随意索引。
  • 调整布局时,可以用 plt.subplots_adjust(hspace=0.3) 手动改间距,但多数场景下 fig.tight_layout() 更省事,它会自动避让标签和标题,兼容性也更好。

如果你已经遇到“标题压到另一张图上”“明明设置了 xlabel 却出现在别的子图里”这类问题,通常就说明当前代码已经不适合继续靠 plt.* 的隐式状态推进了。

真正容易卡住的,是执行顺序和对象归属

回头看这些常见问题,会发现它们大多不是语法错误,而是上下文没有理顺:

  • %matplotlib inline 没先执行,导致 Notebook 单元格里根本不出图。
  • 中文字体在绘图之后才配置,结果第一张图乱码、后面的图才正常。
  • 子图场景里混用了 plt.* 和 ax.*,导致标签、标题和坐标轴设置落到错误的位置。
  • 布局拥挤时只盯着单个参数调整,却忽略了 tight_layout() 这类更直接的方式。

因此,Jupyter Notebook 中 Matplotlib 的稳定写法,可以概括成一条顺序链:先启用 %matplotlib inline,再做 plt.rcParams 和风格配置,随后用 plt.subplots() 获取明确的 axes,最后再开始绘图。把这个执行顺序固定下来,图表不显示、中文乱码和多子图混乱这几类问题,基本都会少很多。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。