Matplotlib 常用功能

2026 | ming


一. 简介

学术绘图工具千千万,但我用的最多的依然是Python的Matplotlib绘图库。

这并非因为它能做出最炫丽的图表(虽然认真调整后完全可以),而是因为它足够轻量、上手极快、且高度可定制——如果你已经熟悉 Python,那么几乎可以立即开始画图。它的核心库体积很小,却提供了从基础到高级几乎无限的可调细节。尤其在当前 AI 辅助编码逐渐普及的背景下,那些现代化高端的图表样式完全可以交给AI去完成,自己只需把握图表的核心结构即可。

或许你会问:为什么不用另一个Python绘图库 Seaborn?它默认样式美观,代码也更简洁。确实,Seaborn 在快速绘制统计图表时非常出色,它与 Matplotlib 同属 Python 可视化生态中的重要成员,选用哪一个更多取决于场景和个人习惯。

我之所以选择Matplotlib,是因为考虑到Seaborn同样是基于Matplotlib开发的,它本质是Matplotlib的高级封装,虽然提供了便捷性,但若是要深度定制化非常规图表,还是要回到Matplotlib底层接口。因此,我认为掌握 Matplotlib 相当于掌握了 Python 科学绘图的基础“语言”,能够让你在可视化设计上拥有更大的自由度。

注意:本系列教程假设你已经具备基础的 Python 语法知识。另外,Matplotlib 与 NumPy 和 pandas 的协同能力极为出色,在实际的数据分析与科研绘图中也常常搭配使用——它们共同构成 Python 数据科学生态中的核心。不过为了降低入门门槛,本系列的示例均使用原生 Python 数据结构。

百闻不如一见,一图胜千言,下面就来简单的看一下我曾经使用matplotlib在短时间内绘制出来的图表:

本教程将按图表类型进行分类讲解。Matplotlib 的参数配置项非常丰富,光看文字和图片是远远不够的——一定要动手实践。请务必复制文章中的示例代码,自己运行一遍,并尝试调整其中的参数,观察图形如何变化。只有亲手操作,才能真正理解每个选项的作用,记忆也会更加深刻。

此外,虽然图表类型多样,但 Matplotlib 的设计思想与核心 API 在各类图表中是共通的。因此,无论你是否需要绘制折线图,第二章“绘图基础 / 折线图绘制”都是必读的重点。我会以最简单的折线图为例,系统讲解图形构成、坐标轴、线条样式、标签标题等基础组件与常用 API。掌握这一部分后,再学习柱状图、散点图、子图绘制等其他图表时,你会发现它们的使用逻辑非常相似,上手也会轻松得多。

二. 绘图基础/折线图绘制

2.1 安装与基础设置

要使用Matplotlib,首先需要安装它。安装非常简单,只需要在终端或命令行中执行以下命令:pip install matplotlib

安装完成后,在Python代码中引入Matplotlib的核心绘图模块:

import matplotlib.pyplot as plt 

这是Matplotlib的标准引入方式,plt是约定俗成的别名,方便后续调用。

Matplotlib默认不支持图表中出现中文字体,直接使用中文会出现乱码(显示为方框)。解决方法很简单,在导入库后添加以下配置代码:

# 设置中文字体
plt.rcParams["font.sans-serif"] = ["SimHei"]  # 使用黑体
plt.rcParams["axes.unicode_minus"] = False   # 正常显示负号

2.2 基础折线图绘制

要画图,首先需要什么?当然是纸了,没有纸,怎么画图呢。在matplotlib中也是如此,只不过是需要画布,才能画图,我们可以这样创建一个画布。

fig, ax = plt.subplots(figsize=(6, 4))

这里的figsize=(6, 4)表示创建一个宽6英寸、高4英寸的画布,这个可以自己根据需求自行设置

有了画布,就要在画布上画图了;在画图表之前,先想一想,我要在这个画布上画几张表呢?其实不论你想画几张表,只要你是通过上面的代码创建的画布,那么这个画布上就只能容下一张表(先不用管为什么)。并且变量ax就是那张表, fig变量代表整个画布,暂时没什么用,不用管它。

现在,我们直接展示一下这个画布。使用如下代码就可以展示当前画布:

plt.show()

运行后会显示一个空白坐标系,因为我们啥也没画。这个坐标系默认是二维直角坐标系,包含x轴和y轴,以及刻度线和边框。

现在让我们在坐标系上绘制一条折线。折线由一系列点连接而成,每个点由 (x,y)(x, y) 坐标确定:

x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 7, 11]
# 调用ax表上的plot方法,plot就是绘制折线
# plot函数第一个参数是x坐标,第二个参数是y坐标
ax.plot(x, y)	

ax.plot()函数将依次连接坐标点 (1,1),(2,4),(3,9),(4,7),(5,11)(1,1),(2,4),(3,9),(4,7),(5,11),形成一条折线。绘制完成后,再次使用plt.show()显示图形如图1所示。

如果我们只传入两个点,就可以绘制一条连接这两个点的直线(这是一个非常有用的小技巧哦,比如绘制辅助线、趋势线等)

x1 = [2, 4]
y2 = [5, 1]
ax.plot(x1, y2)	

绘制的效果如图2所示。可以看到,之前绘制的蓝色折线并没有被“擦除”,这是因为在Matplotlib中,绘图操作是追加的,而不是覆盖。这种设计让你可以轻松地在同一张图上叠加多种元素,从而实现更丰富的信息表达。

接下来,我们尝试绘制一个一元三次函数

f(x)=12x3+x2x+2, x[3,1.5]f(x) = frac{1}{2}x^{3} + x^{2} - x + 2,space xin [-3,1.5]

不过在绘制之前,我们先定义两个在函数可视化中非常实用的辅助函数(未来会多次用到):

def apply_function_to_vector(values, func):
    """将给定函数应用于值列表的每个元素"""
    return [func(value) for value in values]

def generate_range(start, end, step):
    """生成从start到end(不含end),步长为step的序列"""
    return [start + i * step for i in range(int((end - start) / step))]

如果你不太理解这两个函数的作用,这里有一个简单的例子:

a_list = generate_range(1, 3, 0.5)
print(a_list)
# 输出:
# [1.0, 1.5, 2.0, 2.5]

接着,定义一元三次函数及其定义域:

def cubic_polynomial(x):
    return 0.5 * x**3 + x**2 - x + 2

x = generate_range(-3, 1.5, 0.05)  # 在 [-3, 1.5] 上每隔 0.05 取一个点

现在,将每个 xx 代入函数,得到对应的 yy 值:

# 将 x 列表中的每个值传递给 cubic_polynomial 函数,生成对应的 y 列表
y = apply_function_to_vector(x, cubic_polynomial)

绘制图像,结果如图3:

ax.plot(x, y)
plt.show()

你会看到曲线非常光滑,这是因为我们在区间内取了足够多的点(步长 0.05)。点的密度越高,折线在视觉上就越接近连续的函数曲线。

2.3 基础样式

实际上,折线图的核心绘制方法已经讲完了,接下来的重点是样式设置——如何让图表更清晰美观。下面是一段完整的示例代码,注释非常详细,建议你亲自在本地运行,并尝试修改不同参数,观察效果变化。

示例一:

import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"] 
plt.rcParams["axes.unicode_minus"] = False

def apply_function_to_vector(values, func):
    return [func(value) for value in values]

def generate_range(start, end, step):
    return [start + i * step for i in range(int((end - start) / step))]

def cubic_polynomial(x):
    return 0.5 * x**3 + x**2 - x + 2

# cubic_polynomial的导函数
def d_cubic_polynomial(x):
    return 1.5 * x**2 + 2 * x - 1

# 创建图形与坐标轴
fig, ax = plt.subplots(figsize=(6, 4))

# 生成 x 并计算 y 与 dy
x = generate_range(-3, 1.5, 0.3)
y = apply_function_to_vector(x, cubic_polynomial)
dy = apply_function_to_vector(x, d_cubic_polynomial)

# 绘制一元三次函数f(x)
ax.plot(
    x,
    y,
    linewidth=2,  				# 线条的宽度(默认1.5)
    linestyle="-",  			# 线条的样式(默认实线)其它可选项:(实线'-', 虚线'--', 点线':', 点划线'-.')
    color=(0, 0, 0), 		 	# 线条的颜色(黑色),RGB三元组,0~1之间的浮点数表示
    # color = "#FF5733"  		# 也可以使用十六进制颜色代码
    alpha=0.8,  				# 线条的不透明度,取值范围0~1(默认1.0)
    marker="o",  				# 数据点的标记样式,圆形(默认无标记), 其它可选项在后文表格处查询
    markersize=7,  				# 标记点的大小(默认6)
    markerfacecolor="#1E3FCF",  # 标记点的填充颜色,蓝色
    markeredgecolor="#FF5733",  # 标记点的边框颜色,红色
    markeredgewidth=1.5,  		# 标记点边框的宽度(默认1.0)
    markevery=2,  				# 每隔两个数据点绘制一个标记点
    label="三元一次函数 $f(x)$",  # 给这条折线取一个名字(用于图例显示),支持 LaTeX 数学公式
)

# 绘制f(x)的导函数f'(x)
ax.plot(
    x,
    dy,
    color = (0,0,0),
    alpha = 0.6,
    linestyle = '--',
    label = "导数 $f'(x)$"
)

# 坐标轴标签与标题
ax.set_xlabel("这里写x轴标签")
ax.set_ylabel("这里写y轴标签")
ax.set_title("这里写这张表的标题")
ax.legend() # 显示图例,如果没有这行代码就不会显示图例
ax.grid(True)  # 显示背景网格

# 设置次刻度(使坐标轴更精细)
from matplotlib.ticker import AutoMinorLocator
# x轴的每两个主刻度之间放四个小刻度(次刻度)
ax.xaxis.set_minor_locator(AutoMinorLocator(4)) 
# y轴的每两个主刻度之间放2个小刻度
# ax.yaxis.set_minor_locator(AutoMinorLocator(2))

# ax.spines["top"].set_visible(False) # 隐藏顶部边框
# ax.spines["right"].set_visible(False)   # 隐藏右侧边框

plt.show()

运行上述代码后,你会得到如图4所示的图表:

另外,图例、坐标轴标签、网格等元素都是高度可配置的。以下是常用参数的设置示例(可以按需更改):

# y 轴标签样式设置(x 轴与标题类似)
ax.set_ylabel(
    "y 轴标签",
    fontsize=15,	  # 字体大小
    color="#991A1A",  # 文字颜色
    rotation=0,		  # 文字旋转角度
    alpha=0.7,		  # 不透明度
    fontweight=500,	  # 字体粗细
    labelpad=15,  	  # 文字与轴线(边框)的距离
    loc="center",  	  # 文字所处位置,可选参数有 center, left, right, best, top, bottom
)

# 图例样式设置
ax.legend(
    loc="upper left",  # 图例位置设置,其他可选值:upper right lower left center best
    framealpha=0.5,    # 边框不透明度
    frameon=True,      # 是否显示边框
    shadow=False, 	   # 是否显示阴影
    fancybox=True,     # 是否圆角边框
    fontsize=10,       # 字体大小
    title="xxxx",      # 图例标题
    title_fontsize="large",	# 图例标题大小
)

# 网格显示,关于which和axis参数的使用示例可以查看图4.1
ax.grid(
    True,			# 是否显示网格
    which="major",  # 网格类型(分主刻度网格和次刻度网格):'both','major','minor'
    axis="both",  	# 只显示特定方向的背景线条:'both','x','y'
    linestyle="-",  # 线型
    linewidth=0.5,  # 线宽
    color="gray",  	# 颜色
    alpha=0.4,  	# 不透明度
)

示例二:自定义主刻度与刻度标签

在默认情况下,Matplotlib 会根据数据范围自动设置刻度位置,但很多时候我们需要手动指定刻度位置甚至自定义标签。下面通过几个典型的设置来说明如何操作。

运行以下代码,我们将手动设置 x 轴和 y 轴的刻度位置,结果如图5所示。

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 4))
ax.set_xticks([0,1,3,4.5,10])	# 设置 x 轴的主刻度位置
ax.set_yticks([-5,-1,0,3.2,5])	# 设置 y 轴的主刻度位置
plt.show()

默认刻度位于坐标轴底部(x 轴)和左侧(y 轴)。如果需要将刻度移到另一侧,可以使用以下方法。运行结果如图6所示。

ax.xaxis.set_ticks_position("top")    # 将 x 轴刻度置于顶部
ax.yaxis.set_ticks_position("right")  # 将 y 轴刻度置于右侧
# 其他可选参数:'bottom', 'top', 'left', 'right', 'both', 'none'

除了调整刻度位置,我们还可以完全自定义每个刻度对应的标签,并设置标签的样式(如旋转、字体大小等)。运行结果如图7所示。

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 4))
ax.set_xticks([0, 1, 3, 4.5, 10])  # 设置 x 轴的主刻度位置
# 自定义刻度标签文本与样式,这行代码一定要跟在set_xticks方法后面
ax.set_xticklabels(    
    ["我是0", "我是1", "我是3", "我是4.5", "我是10"],
    rotation=-45,                   # 标签旋转 -45 度
    fontsize=10,                    # 标签字体大小
)
plt.show()

常用标记点样式marker速查表:

绘制散点图或折线图时,marker 参数用于指定数据点的形状。下表列出最常用的几种样式:

参数值样式描述图示
'.'● (小圆点)
'o'圆圈○ (空心圆)
's'正方形
'D'钻石形
'^'正三角形
'v'倒三角形
'>'右三角形
'<'左三角形
'p'五边形
'*'星号
'h'六边形1
'H'六边形2
'+'加号
'x'乘号×
'd'小钻石

2.4 常用辅助元素

辅助元素包括参考线、参考区间带、文本标注等,它们能够帮助读者更清晰地理解图表中的关键位置或范围。下面通过一个例子演示如何添加这些元素。

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 4))

# 再绘制一遍上文中的一元三次函数
# =====================================
def apply_function_to_vector(values, func):
    return [func(value) for value in values]

def cubic_polynomial(x):
    return 0.5 * x**3 + x**2 - x + 2

def generate_range(start, end, step):
    return [start + i * step for i in range(int((end - start) / step))]

x = generate_range(-3,1.5,0.05)
y = apply_function_to_vector(x, cubic_polynomial)
ax.plot(x, y)
# =====================================

# 添加一条水平参考线
ax.axhline(
    y=4.0,               # 参考线所在的 y 坐标
    color="#B92D2D",     # 颜色(红色)
    linestyle="--",      # 线型:虚线
    linewidth=1,         # 线宽
    alpha=0.5,           # 不透明度
)

# 添加一条垂直参考线
ax.axvline(
    x=-2,                # 参考线所在的 x 坐标
    color="#1D9B43",     # 颜色(绿色)
    linestyle="--", 
    linewidth=1,
)

# 添加一条对角参考线
ax.axline(
    (0, 2),        # 过(0,2)点
    slope=-0.8,    # 作一条斜率为-0.8的参考线
    color="gray", 
    linestyle="--", 
    linewidth=0.5
)

# 添加水平参考区间带(常用于表示置信区间或目标范围)
ax.axhspan(
    ymin=0.5,            # 区间下界
    ymax=1.2,            # 区间上界
    facecolor="green", 	 # 区间颜色
    alpha=0.2            # 较低的透明度使背景不被过度突出
) 

# 添加垂直参考区间带
ax.axvspan(xmin=-1.2, xmax=-0.3, facecolor="red", alpha=0.1)

# 在图表中添加文本标注
# 如下配置项众多,推荐直接给AI提供你的需求,让AI帮你写如下配置项
bbox_props = dict(
    boxstyle="round",     # 圆角文本框
    facecolor="white",    # 填充色
    edgecolor="black",    # 边框颜色
    linewidth=1,          # 边框宽度
    alpha=0.8,            # 整体透明度
    pad=0.4,              # 文本与边框的内边距
)
ax.text(
    0.0,                  # 文本框锚点的 x 坐标(数据坐标系)
    3.6,                  # 文本框锚点的 y 坐标
    "Your Text",          # 文本内容
    fontsize=10, 		  # 文字大小
    fontfamily="serif",   # 衬线字体
    fontstyle="italic",   # 斜体
    fontweight="bold",    # 粗体
    color="black",        # 字体颜色
    ha="left",            # 水平对齐方式:左对齐
    va="bottom",          # 垂直对齐方式:底部对齐
    rotation=0,           # 文本旋转角度(度)
    bbox=bbox_props,      # 应用上述文本框样式
)

plt.show()

运行结果如图8所示。

2.5 保存为图片

绘制完成后,我们通常需要将图表保存为图片文件以便在报告、文章或演示中使用。除了手动截图,更规范的做法是在程序的结尾使用 plt.savefig() 函数。该函数支持多种格式(PNG、PDF、SVG 等)和丰富的输出设置。

plt.savefig(
    "output.png",               # 文件路径,支持多种图片后缀(可使用相对或绝对路径)
    dpi=300,                    # 分辨率,数值越高图片越清晰
    bbox_inches="tight",        # 自动裁剪图表周围多余的空白区域
    facecolor="white",          # 画布背景颜色
    edgecolor="none",           # 画布边缘颜色
    transparent=False,          # 若为 True,则背景透明(适合叠加在其他图上)
    orientation="portrait",     # 纸张方向:'portrait'(纵向)或 'landscape'(横向)
    metadata={                  # 可选的元数据,会嵌入到图片文件中
        "Title": "Experimental Results",
        "Author": "Ming",
        "Copyright": "CC-BY 4.0",
    },
)

这样的话,运行完程序后,就会将图表保存为图片存放在你指定的位置。

三. 进阶绘图操作

3.1 区间填充

区间填充,指的是在给定的 xx 区间内,根据该区间对应的上下边界值,将其之间的区域用颜色或图案进行填充。这种可视化方法常用于表示误差范围、置信区间、函数包围区域等,能直观地展示数据或函数在某一范围内的波动情况。下图 9 展示了一个典型的区间填充效果:

要实现上面的效果也很简单,在 Matplotlib 中,我们可以使用 ax.fill_between() 函数轻松实现这一效果。下面是一个基础示例:

fig, ax = plt.subplots(figsize=(6, 4))
x = [1, 2, 3]
y_up = [2, 5, 4]
y_down = [1, -1, 2]

# 绘制上下两条折线
ax.plot(x, y_up)
ax.plot(x, y_down)

# 填充两条线之间的区域
ax.fill_between(
    x,              # x 坐标序列
    y_up,           # 上边界 y 值
    y_down,         # 下边界 y 值
    color='#2ca02c', # 填充颜色
    alpha=0.2       # 不透明度
)

再来看一个例子:

# 定义两个多项式函数
# 一元三次函数
def cubic_polynomial(x):
    return 0.5 * x**3 + x**2 - x + 2
# 一元二次函数
def quadratic_polynomial(x):
    return (3 * x**2 + 5 * x - 2) / 1.5
fig, ax = plt.subplots(figsize=(6, 4))

# 绘制这两个函数
x = generate_range(-3, 1.5, 0.05)
y3 = apply_function_to_vector(x, cubic_polynomial)
y2 = apply_function_to_vector(x, quadratic_polynomial)
ax.plot(x, y3,label="Cubic")
ax.plot(x, y2,label="Quadratic")

# 填充x在[-2,0]之间,以一元三次函数为上限,一元二次函数为下限的区间
interval_x = generate_range(-2,0,0.05)
interval_y3 = apply_function_to_vector(interval_x, cubic_polynomial)
interval_y2 = apply_function_to_vector(interval_x, quadratic_polynomial)
ax.fill_between(
    interval_x,     # x 区间
    interval_y3,    # 上边界(三次函数)
    interval_y2,    # 下边界(二次函数)
    color="#2B6DA3", # 填充颜色
    alpha=0.25,     # 透明度
    label="Interval" # 用于图例的标签
    # hatch="//"    #这个属性的介绍详见条形图章节
)

ax.legend()

运行上述代码后,我们得到如图 10 所示的结果,其中蓝色区域即为两个函数在 x[2,0]x in [-2,0] 区间内的包围区域:

其实区间填充可以画出很多有趣的图,如下图11所展示的四张图表,仅需掌握上文所提到的内容即可绘制出来。

3.2 多子图

在上一节中,我们使用 fig, ax = plt.subplots(figsize=(6, 4)) 创建了一张画布,并在其上绘制了单个图表。然而在实际分析中,我们常常需要将多个图表并排展示,以便直观地比较不同数据或视角。这时,多子图(Subplots)功能就派上了用场。

通过 plt.subplots() 函数,我们可以轻松创建包含多个坐标轴(Axes)的网格布局。例如,以下代码创建了一个 2 行 4 列,总共 2×4=82 times 4 = 8 个子图的画布:

row = 2  # 设定子图行数为 2
col = 4  # 设定子图列数为 4
fig, axs = plt.subplots(row, col, figsize=(15, 6))

将其绘制出来,如图12所示

这里返回的 axs 是一个数组(这也是变量名带 “s” 的原因),其形状为 (row, col),即 (2, 4)。你可以通过二维索引来访问每一个子图坐标轴对象:

  • axs[0, 0] 对应第 1 行第 1 列的子图
  • axs[0, 1] 对应第 1 行第 2 列的子图
  • ……
  • axs[1, 3] 对应第 2 行第 4 列的子图

那么,如果我想在第 2 行第 2 列的子图中绘制一个三次函数,该怎么做呢? 方法与在单图中绘图完全一致,只需选中对应的坐标轴对象并进行操作即可。

fig, axs = plt.subplots(2,4,figsize=(15, 6))
x = generate_range(-3, 1.5, 0.05)
y = apply_function_to_vector(x, cubic_polynomial)

# 在第二行第二列(索引为 [1, 1])的子图中绘图
axs[1, 1].plot(x,y)
axs[1, 1].set_title("一元三次函数")
axs[1, 1].grid(True, which='both', linestyle='--', linewidth=0.5)
axs[1, 1].set_xlabel("这是x轴标签")
axs[1, 1].set_ylabel("这是y轴标签")

# 可选:调整子图之间的间距,避免标签重叠
fig.tight_layout()

运行结果如图13所示,可以看到只在指定的子图位置绘制了函数曲线:

当然,多子图还有更多高级布局方式,例如:

  • 共享坐标轴:多个子图共享同一 x 轴或 y 轴,便于比较。
  • 不均匀布局:使用 GridSpec 实现更灵活、大小不一的子图排列。
  • 嵌套布局:在大图中嵌入小图。

由于这些技巧在入门阶段使用频率相对较低,本篇文章暂不展开。如果你未来遇到相关需求,可以随时查阅 Matplotlib 官方文档或询问你身边的 AI 助手。

3.3 双轴图

什么是双轴图? 简单来说,双轴图就是在同一张图中使用两个独立的Y轴(通常共享同一个X轴),用来同时展示两种不同量纲或数量级的数据。这样一来,我们就能在同一个坐标系下清晰对比两组差异很大的数据,而不会被单一坐标轴的尺度所限制。

来看下面的例子(图14左图):

  • 左侧的红色Y轴范围是 -1 到 1,对应正弦函数 y=sin(x)y=text{sin}(x)
  • 右侧的蓝色Y轴范围是 0 到 200,对应缩放后的指数函数 y=0.01exy=0.01 cdot e^{x}

如果不用双轴,而是把两条曲线画在同一个Y轴下(图14右图),由于指数函数的数值远大于正弦函数,正弦曲线的波动就会被严重压缩,几乎看不出其形态细节。

Matplotlib 绘制双轴图非常简单,核心方法是使用 ax.twinx() 创建共享X轴的第二个坐标轴。下面我们通过代码一步步实现:

import matplotlib.pyplot as plt
import math
plt.rcParams["font.sans-serif"] = ["SimHei"]  # 使用SimHei字体(黑体)
plt.rcParams["axes.unicode_minus"] = False

# 定义两个函数:正弦函数和缩放后的指数函数
def sin(x):
    return math.sin(x)

def exp(x):
    return math.exp(x) * 0.01

x = generate_range(0,10,0.05)
y1 = apply_function_to_vector(x,sin)
y2 = apply_function_to_vector(x,exp)

fig, ax = plt.subplots(figsize=(5, 3))

# 正常绘制,在主坐标轴上绘制第一条曲线(正弦,红色)
ax.plot(x, y1, color='red')
ax.set_xlabel("X轴")  
ax.set_ylabel("主y轴: 正弦函数", color="red")

# 将主Y轴的刻度标签也设为红色,形成视觉统一
ax.tick_params(axis="y",labelcolor="red")

#  关键步骤:创建共享X轴的次坐标轴
sub_ax = ax.twinx()

# 在次坐标轴上绘制第二条曲线(指数,蓝色)
# sub_ax 和普通的ax使用方法一样
sub_ax.plot(x, y2, color='blue')
sub_ax.set_ylabel("次Y轴: 指数函数", color="blue")
sub_ax.tick_params(axis="y", labelcolor="blue")

ax.title("双Y轴示例: 正弦函数 vs 指数函数")
plt.show()
  • ax.twinx() 会创建一个与 ax 共享 X 轴的新坐标轴对象 sub_ax,其 Y 轴默认放置在右侧。
  • sub_ax 的使用方法与普通坐标轴完全相同,可以调用 plotset_ylabeltick_params 等方法。

四. 条形图

条形图(Bar Chart)是一种以矩形条的长度或高度表示数值大小的统计图表,通常用于展示分类数据的对比。与折线图强调趋势不同,条形图更侧重于类别之间的比较,常见于销售额对比、投票结果、价格比较等场景。

我们先来看一个典型的多类别条形图示例(图15),它清晰地展示了不同数据系列在多个类别上的分布与对比:

用 Matplotlib 绘制条形图非常简单,主要使用 ax.bar() 方法。我们以绘制一组水果批发价的条形图为例(运行结果如图16所示):

# 创建画布
fig, ax = plt.subplots(figsize=(6, 4.5))
# 设置次刻度:每两个主刻度之间包含5个次刻度(使坐标轴更精细)
ax.xaxis.set_minor_locator(AutoMinorLocator(5))

# 数据准备
wholesale_price = [5.1, 4.7, 5.5, 3.2, 4.3]  # 批发价(元/公斤)
x = [1, 2, 3, 4, 5]  # 横坐标位置

# 绘制条形图(注意:不是plot,而是bar)
ax.bar(
    x,                    # 每个柱子的横坐标位置
    wholesale_price,      # 每个柱子的高度(y值)
    width=0.4,            # 柱子的宽度
    label="批发价",        # 图例标签
    color="#35881B",      # 填充颜色(绿色系)
    edgecolor="black",    # 边框颜色
    alpha=0.8,            # 不透明度(0~1,1为完全不透明)
)

上面的基础条形图略显单调,我们通过以下步骤增强可读性与美观度(运行结果如图17所示):

fig, ax = plt.subplots(figsize=(6, 4.5))

# 具体化的水果价格属性
wholesale_price = [5.1, 4.7, 5.5, 3.2, 4.3]  # 批发价

# 设置水果标签
x = [1, 2, 3, 4, 5]
categories = ["香蕉", "橙子", "苹果", "橘子", "杏子"]

# 设置x轴刻度标签(用真实水果名替换数字)
ax.set_xticks(x)
ax.set_xticklabels(categories)

# 绘制条形图(换为更中性的深灰色)
ax.bar(
    x, wholesale_price,
    width=0.4,
    label="批发价",
    color="#272727",      # 深灰色
    edgecolor="black",
    alpha=0.8,
)

# 在每个柱子顶部添加数值标签 - 使用x和wholesale_price定位
# 本质使用ax.text在指定位置添加文本
for xi, price in zip(x, wholesale_price):
    ax.text(xi, price + 0.2, f"{price}", 
            ha="center",   # 水平居中
            va="bottom",   # 垂直底部对齐
            fontsize=12)

# 设置ax表的可见视窗大小,x在0.2~5.8之间,y在0~7之间,你可以自己调整,看看效果
# 主要就是让图形周围留有一定空间
ax.set_ylim(0, 7)          # y轴显示0~7
ax.set_xlim(0.2, 5.8)      # x轴显示0.2~5.8(柱子居中)

# 添加图例与网格
ax.legend()
ax.grid(axis="y", linestyle="--", alpha=0.5)

# 在ax表上继续绘制折线图,不要忘了,matplotlib不会擦除之前绘制的任何内容,因此你可以组合出很多奇特的图
ax.plot(x, wholesale_price,
        color="#2E2E2E",
        linestyle="--",
        alpha=0.5,
        marker="o")        # 数据点用圆圈标记

其实到这里,条形图就已经讲完了,但是在实际分析中,我们常需要比较同一分类下多个系列的数据,这就是多类别条形图(图15类型),其实你在学会上面的内容后,自然而然就会绘制多类别条形图了,它的本质就是在一个图表上绘制多个条形图,接下来就带你绘制一遍如图18所示的多类别条形图,代码如下:

fig, ax = plt.subplots(figsize=(7, 4.5))
ax.xaxis.set_minor_locator(AutoMinorLocator(5))

# 三种价格数据(单位:元/公斤)
wholesale_price = [5.1, 4.7, 5.5, 3.2, 4.3]   # 批发价
retail_price = [8.17, 9.74, 9.2, 8.58, 7.5]    # 零售价
online_price = [6.31, 6.42, 5.94, 7.35, 6.93]  # 电商价


categories = ["香蕉", "橙子", "苹果", "橘子", "杏子"]
# 确定每个分类的中心位置(这里为[1, 2.5, 4, 5.5, 7],间距为1.5)
x = [1, 2.5, 4, 5.5, 7]

ax.set_xticks(x)
ax.set_xticklabels(categories)

# 第一组:零售价(左侧偏移0.25)
ax.bar(
    [i - 0.25 for i in x],  # 横坐标左移0.25
    retail_price,
    width=0.5,
    label="零售价",
    color="#C5C5C5",        # 浅灰色
    edgecolor="black",
    alpha=0.8,
)

# 第二组:批发价(居中,宽度较窄)
ax.bar(
    [i - 0.25 for i in x],  # 与零售价同一基准位置
    wholesale_price,
    width=0.25,             # 较窄的柱子
    label="批发价",
    color="#555555",        # 中灰色
)

# 第三组:电商价(右侧偏移0.25)
ax.bar(
    [i + 0.25 for i in x],  # 横坐标右移0.25
    online_price,
    width=0.5,
    label="电商价",
    color="#FFFFFF",        # 白色填充
    edgecolor="black",
    hatch="///",            # 填充图案:斜线
)

# 设置坐标轴与标题
ax.set_ylim(0, 11)
ax.set_xlim(0, 8)
ax.set_xlabel("水果种类")
ax.set_ylabel("价格(元/公斤)")
ax.set_title("不同销售渠道的水果价格对比")
ax.legend()
ax.grid(axis="y", linestyle="--", alpha=0.5)

偏移原理

  • 每个分类的中心位置为 x[i]
  • 左侧柱子:x[i] - offset
  • 右侧柱子:x[i] + offset
  • 通过调整 widthoffset 控制柱子的宽度与间距

图案填充:(自己多多尝试就懂了)

  • hatch 参数支持多种填充模式:'/', '', '|', '-', '+', 'x', 'o', 'O', '.', '*'
  • 图案密度会随字符重复而增加,如 '///''/' 更密集

最后,我们综合运用前面学到的知识,完成一个具有实用价值的组合图(图19):绘制某城市的气温曲线和降水量柱状图。(你可以先自己尝试绘制一下,若发现哪里有卡住了再看看参考代码)

参考代码:

import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"] 
plt.rcParams["axes.unicode_minus"] = False

# 数据准备
month = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]  # 月份
temperature = [16, 16.5, 17.5, 19, 21, 24, 30, 32, 31, 26, 21, 18]  # 气温(℃)
precipitation = [12, 20, 21, 45, 79, 120, 140, 230, 180, 160, 153, 20]  # 降水量(mm)

fig, ax = plt.subplots(figsize=(5, 5.5))

# 左侧y轴:绘制气温折线图
ax.plot(
    month, temperature,
    color="black",
    marker="o", 
    markersize=5,  
    markerfacecolor="#292929",  # 标记点填充色
    markeredgecolor="#060504",  # 标记点边框色
    markeredgewidth=1,
)  
ax.set_xlabel("海口", fontsize=14) 
ax.set_ylabel("气温(℃)")
ax.set_xticks(month)
ax.set_ylim(-60, 40)  # 留出足够空间,避免条形图溢出

# 创建右侧y轴(共享同一x轴)
sub_ax = ax.twinx()

# 在右侧y轴坐标系中绘制降水量条形图
sub_ax.bar(
    month, precipitation,
    width=0.5,
    edgecolor="black",
    color="#FFFFFF",
    alpha=1,
    hatch="///"  # 用斜线填充,区别于纯色
)
sub_ax.set_ylabel("降水量(mm)")
sub_ax.set_ylim(0, 400)  # 设置合适的范围

# 为右侧y轴添加网格线(增强可读性)
sub_ax.grid(
    True,
    which="both", 
    axis="y",  
    linestyle="-", 
    linewidth=0.5,  
    color="gray", 
    alpha=0.4,  
)

plt.show()

五. 散点图

散点图是一种将成对数据 (x,y)(x,y) 绘制为二维平面中一个点的可视化方法。通过观察这些点的分布形态,我们可以直观地判断两个变量之间是否存在相关性、分布模式或异常值。因此,散点图在数据分析、模式识别和初步探索中极为常用。

接下来,我们绘制一个最基本的散点图,代码如下,运行结果如图20所示:

fig, ax = plt.subplots(figsize=(6, 3.5))

# 第一组数据点:(x1[i], y1[i])
x1 = [1.2, 3.1, 1.8, 2.6, 3.1, 2.2]
y1 = [2.5, 2.6, 1.8, 2.2, 3.0, 1.8]

# 第二组数据点:(x2[i], y2[i])
x2 = [2.1, 2.5, 2.8, 1.6, 1.1, 2.2]
y2 = [3.5, 3.1, 2.8, 3.6, 4.0, 2.8]

# 绘制第一组散点
ax.scatter(
    x1,
    y1,
    s=40,              # 点的大小
    color="#575757",   # 填充颜色(灰色)
    alpha=1,           # 不透明度
    edgecolors="#000000",  # 边缘颜色(黑色)
    linewidths=1,      # 边缘线宽
    marker="o",        # 点形状(圆形),更多选项可以查看“2.3基础样式”中的marker速查表
    label="Group A",   # 图例标签
)

# 绘制第二组散点
ax.scatter(
    x2,
    y2,
    s=40,
    color="#FFFFFF",   # 填充颜色(白色)
    alpha=1,
    edgecolors="#000000",
    linewidths=1,
    marker="o",
    label="Group B",
)

# 显示图例
ax.legend()

通过上面的例子,你已经可以画出清晰的分类散点图。在实际分析中,我们有时还需要用点的大小或颜色表示第三个维度的信息(例如权重、密度、类别等),需要做到精细化处理每一个点,给每个点设置不同的大小和颜色,实现起来也非常简单,要实现图21所示的效果,示例代码如下:

fig, ax = plt.subplots(figsize=(7, 3.5))

x1 = [1.2, 3.1, 1.8, 2.6, 3.1, 2.2]
y1 = [2.5, 2.6, 1.8, 2.2, 3.0, 1.8]

# 每个点的大小
sizes = [40, 60, 90, 100, 120, 140]

# 每个点的颜色值,用一个 0~1 的浮点数表示,对应颜色映射表中的位置
colors = [0, 0.2, 0.3, 0.4, 0.5, 1]

# 绘制带颜色映射的散点图
scatter = ax.scatter(
    x1,
    y1,
    s=sizes,        # 使用列表分别指定每个点的大小
    c=colors,       # 使用列表分别指定每个点的颜色值
    cmap="plasma",  # 颜色映射表,将 0~1 的值映射为具体颜色
    alpha=0.8,      # 不透明度
    linewidths=0,   # 边缘线宽(设为 0 表示无边框)
    marker="o",     # 点形状
)

# 添加颜色映射条(colorbar)
cbar = fig.colorbar(scatter, ax=ax)
# 可设置颜色条标题(按需启用)
cbar.set_label("颜色映射条标题", fontsize=9)

# 设定坐标轴范围,让图形更美观
ax.set_xlim(0.6, 3.6)
ax.set_ylim(1, 3.7)

常用的 cmap(颜色映射)选项包括:

  • 连续型plasmaviridiscoolwarmhotgray(适合表示数值大小)
  • 离散型tab10Set2(适合表示分类)

这些颜色映射的视觉对比如图22所示,你可以根据数据特性选择最合适的映射方案。

六. 直方图

直方图(Histogram)是一种用于展示数据分布情况的统计图表,它通过将数据划分到不同的区间(称为“箱”或“bin”),并统计每个区间内数据点的数量来绘制。直方图特别适合观察数据的整体分布、集中趋势和离散程度。

为了让你更直观地理解,我们用一个生活中的例子来说明:假设你有一所初中所有学生的身高数据,现在你想知道身高在 1.45 m–1.50 m 之间有多少人、1.50 m–1.55 m 之间有多少人……以此类推。如果你手动统计每个区间的人数,再用条形图画出来,当然可以,但这样做比较繁琐。而直方图正是为这种“分段统计”任务而生的工具,它能自动完成分箱和计数,并直接生成可视化的分布图。

以下是一段基础的直方图绘制代码,我们使用一组模拟数据来演示:

fig, ax = plt.subplots(figsize=(6, 4))
# 模拟数据
data = [1.1, 1.3, 1.6, 2.6, 2.2, 3.1, 3.4, 3.2, 3.9, 3.5,
        4.3, 5.1, 5.7, 5.8, 5.3, 5.1, 5.4, 5.6, 5.1, 5.0, 5.4, 5.6, 5.3]

# 使用 hist 函数绘制直方图
ax.hist(
    data,                     # 输入数据(一维数组或序列)
    bins=[1, 2, 3, 4, 5, 6], # 指定分箱边界:依次为 [1,2)、[2,3)、[3,4)、[4,5)、[5,6]
    range=(1, 5),            # 仅统计落在 range 范围内的数据(此处为 1 到 5),范围外的数据将被忽略
    histtype="stepfilled",   # 直方图类型:填充式阶梯图
    orientation="vertical",  # 方向:垂直(可选 'horizontal' 为水平)
    rwidth=0.9,              # 条形相对宽度(占 bin 宽度的比例)
    color="#277098",         # 填充颜色
    edgecolor="black",       # 边框颜色
    alpha=0.75,              # 填充不透明度
    label="普通直方图",      # 图例标签
)

plt.show()

代码执行结果如图23所示。

histtype可选参数有:bar - 柱状图,step - 阶梯状图,stepfilled - 阶梯状图并填充颜色,barstacked - 多数据堆叠条形图。(当选为阶梯状图时,rwidth参数无效)

通过这个例子,你可以看到 hist() 函数提供了丰富的参数来自定义直方图的视觉效果。建议你尝试修改各个参数(例如 histtypecolorrwidth 等),观察图形的变化,这对加深理解非常有帮助。如果有哪些参数自己实在不能理解,完全可以求助AI,加之自己的实践,理解并且运用它宾不是什么难事。

上面的示例数据量较小,在实际分析中我们常面对成千上万的数据点。此时,直方图能更清晰地揭示数据的整体分布规律。下面的例子生成了一个包含 2000 个数据点的合成数据集,它由两个不同的正态分布混合而成:

# 生成混合正态分布数据
import random
# 生成均值为 1、标准差为 3 的正态分布样本
random_array_1 = [random.gauss(1, 3) for _ in range(1000)]
# 生成均值为 12、标准差为 4 的正态分布样本
random_array_2 = [random.gauss(12, 4) for _ in range(1000)]
# 合并两组数据
random_array = random_array_1 + random_array_2

fig, ax = plt.subplots(figsize=(6, 4))
ax.hist(
    random_array,
    bins=50,           # 指定直方图柱子的数量(此处为 50 根),系统会自动均匀划分区间
    range=(-10, 25),   # 仅显示 -10 到 25 范围内的数据
    histtype="stepfilled",
    orientation="vertical",
    rwidth=0.9,
    color="#FFFFFF",   # 白色填充
    edgecolor="black",
    alpha=0.75,
    label="双峰分布直方图",
    hatch='///',       # 填充图案(参见第四章条形图相关说明)
)

plt.show()

该程序的运行结果如图24所示。

七. 等高线图

等高线图大家应该不陌生,在初高中地理课本上经常见到——它用一圈圈的闭合曲线表示地形的起伏,同一曲线上的海拔高度相同。

在数学上,等高线图其实是三维函数在二维平面上的投影。给定一个二元函数 z=f(x,y)z = f(x,y),我们可以在 xyxy 平面上画出所有满足 f(x,y)=cf(x,y)=ccc 为常数)的曲线,每一条曲线就称为一条“等高线”。多条等高线组合在一起,就能直观反映出函数值的变化趋势,如图25所示。

等高线图在日常绘图中使用频率不算高,因此本教程不展开详述(有了前面的基础,如果你需要深入学习,完全可以借助 AI 快速掌握)。不过,等高线图有一个非常重要的应用:绘制隐函数图像

比如下面这个隐函数方程:

(x2+y21)3=x2y3(x^2+y^2-1)^3=x^2y^3

它对应的曲线是一个心形,很难直接用 plot() 画出,因为你无法从中解出 y=g(x)y=g(x) 的显式表达式。这时候,就需要等高线图了。

绘制隐函数的本质就就是将方程改写为 f(x,y)=0f(x,y) = 0 的形式,即:

f(x,y)=(x2+y21)3x2y3f(x,y) = (x^2+y^2-1)^3 - x^2y^3

然后绘制 f(x,y)f(x,y) 的值为 0 的那条等高线,这条线就是原方程的解曲线。

如下是绘制代码:

# 绘制等高线通常需要生成网格数据,numpy能极大简化这一过程,如果没有numpy的话代码将会非常繁琐。
import numpy as np
x = np.linspace(-1.5, 1.5, 300)  # x范围:-1.5到1.5,取300个点,点越多绘制的图就越细致
y = np.linspace(-1.5, 1.5, 300)  # y范围:-1.5到1.5
X, Y = np.meshgrid(x, y)  		 # 生成网格坐标矩阵 X, Y

# 计算函数 f(x, y) = (x^2 + y^2 - 1)^3 - x^2 * y^3
F = (X**2 + Y**2 - 1)**3 - X**2 * Y**3  

# 创建图形
fig, ax = plt.subplots(figsize=(6, 4))

# contour函数来绘制 F=0 的等高线,也就是方程的解
# levels=[0] 表示只画值为0的等高线
ax.contour(X, Y, F, levels=[0], colors="red", linewidths=2,alpha=0.7)

ax.set_title("Closed Curve: $(x^2+y^2-1)^3=x^2y^3$", fontsize=11)
ax.grid(True, linestyle="--", alpha=0.7)
ax.axis("equal")   # 重要!保证 x、y 轴比例相同,图形不会拉伸变形

plt.show()

代码运行结果如图26所示。

八. 图像类图表

图像类图表允许你直接通过像素数据绘制图像,也可以读取图片并将其绘制到图表中充当背景,图像类图表的应用非常多,非常灵活。当 Matplotlib 没有提供你想要的图表类型时,你完全可以基于图像功能“创造”一个。而且它非常简单易学,核心函数参数不多,上手迅速。

如下代码展示了如何使用代码创建一个简单的单通道图像并且显示出来:(“通道”是数字图像处理中的基本概念,它代表图像中一种基本的颜色或亮度信息。如果你不知道什么是“通道”,那么你可以先自行搜索了解一下)

fig, ax = plt.subplots(figsize=(6, 4))

# 创建一个灰度图像,每个数字就代表一个颜色
img = [[0.0,0.2,0.4],
       [0.6,0.8,1.0],
       [0.0,0.5,1.0]]

# 使用 imshow 显示图像
ax.imshow(
    img,
    cmap='gray',          # 颜色映射:'gray' 表示灰度映射,更多映射规则详见散点图章节
    aspect='equal',       # 保持像素为正方形,防止图像拉伸
    interpolation='nearest',# 图像平滑插值方法,可选 nearest(默认锯齿,适合像素艺术), bilinear(双线性平滑), bicubic(双三次平滑), ...
    alpha=1.0,            # 不透明度,1.0 为完全不透明
    extent=(10.0, 20.0, 5.0, 15.0)  # 定义图像在坐标轴中的位置和范围
    # extent 格式: (左边界, 右边界, 下边界, 上边界)
)

运行结果如图27所示。由于我们设置了 extent=(10, 20, 5, 15),这个小小的 3x3 图像会被“拉伸”并放置到坐标系中 x[10,20],y[5,15]x in [10, 20], y in [5, 15] 的矩形区域内。并且由于使用了gray灰度映射,因此值为0的像素就会显示为纯黑色,值为1的像素就会显示为纯白色,中间值呈现相应的灰色。

当图像数据包含多个通道(例如 RGB 三个颜色通道)时,它就代表了彩色图像。此时,cmap 参数将不再生效,因为颜色信息已直接包含在数据中。处理这种多维数组数据,使用 NumPy 会非常方便。下面的教程默认你已熟悉 NumPy 的基本操作。

让我们尝试读取一个外部图片文件:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg  # Matplotlib 提供的图像读取工具
import numpy as np

fig, ax = plt.subplots(figsize=(2, 2))

# 读取图像 (支持 JPG, PNG, BMP, TIFF 等常见格式)
# 函数返回一个 NumPy 数组,像素值通常被自动归一化到 [0.0, 1.0] 区间
img = mpimg.imread("../media/icon48.png")
print(img.shape)
# ==== 输出示例 ====
# (48, 48, 4)

输出显示图像数组的形状为 (48, 48, 4)。这表示这是一张 48 像素高,48 像素宽 的图片,并且有 4 个通道。通常,这对应着 RGBA 模式:红、绿、蓝三个颜色通道,外加一个 Alpha 通道(控制透明度)。

我们可以对图像数组进行操作来实现各种效果。例如,先丢弃 Alpha 通道只保留 RGB,然后进行反色处理:

# 只保留前三个通道(RGB),丢弃 Alpha 通道
img_rgb = img[:, :, :3]

# 进行反色操作:1 - 原值
new_img = 1 - img_rgb

# 显示处理后的图像
ax.imshow(
    new_img,
    aspect="equal",           # 保持宽高比,像素呈正方形
    interpolation="bicubic",  # 使用双三次插值,使图像看起来更平滑
    alpha=1,                  # 不透明度
    extent=(0, 1, 0, 1),      # 将图像放置在坐标系中 (0,0) 到 (1,1) 的范围内
)

运行结果如图28所示。由于我们做了 1 - img 的反色计算,原本黑色的区域变成了白色,白色变成了黑色,得到了一个“底片”效果。这展示了图像数据的本质——只是一个数值数组,我们可以像处理普通矩阵一样对它进行加减乘除、滤波、变换等任何数学运算,从而创造出无穷的视觉效果。

图像功能的强大之处在于它能与 Matplotlib 的其他图表元素无缝融合。你可以把图片当作一个特殊的“图层”或“标记”,放置在坐标系的任何位置,或者自己用像素操作绘制一个图形,这让你能够创建出极具个性化和信息丰富的复合图表。

下面是一个简单的例子,将我们读取的图标与一个正弦函数曲线绘制在同一坐标系中:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

fig, ax = plt.subplots(figsize=(5, 5))

# 1. 首先,绘制图像
img = mpimg.imread("../media/icon48.png")
ax.imshow(
    img,
    aspect="equal",
    interpolation="bicubic",
    alpha=0.8,                 # 设置一点透明度,让后面的曲线若隐若现
    extent=(4, 5, -1, 0),      # 将图标放置在 x=[4,5], y=[-1,0] 的矩形区域
)

# 2. 然后,在同一个坐标系上绘制标准的函数曲线
x = np.linspace(0, 10, 100)
y = np.sin(x)
ax.plot(x, y, linewidth=2, label='sin(x)')

# 3. 设置坐标轴范围
ax.set_ylim(-2, 2)

运行结果如图29所示。

九. 动画渲染

Matplotlib 确实提供了动画功能,不过在实际应用中,我们通常不会将它作为专业的动画工具。对于复杂的数学可视化动画,业界有更专业的库可以选择,比如 3Blue1Brown 开源的 manim

尽管如此,了解 Matplotlib 动画的基本原理还是有价值的,尤其当你需要快速生成简单动画或教学演示时。

Matplotlib 动画的核心思路非常简单:生成一系列静态图表(帧),然后按顺序连续播放。每一帧对应数据的一个状态,将这些帧串联起来,就形成了动画。

Matplotlib 提供两种主要动画方法:

  • FuncAnimation:实时生成每一帧,适合动态更新或数据流场景
  • ArtistAnimation:预先生成所有帧并存储在内存中,适合帧数确定、内容不变的动画

考虑到易学性和典型使用场景,本教程主要介绍 ArtistAnimation 方式。

下面我们通过一个例子,绘制正弦波逐渐平移的动画:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np

fig, ax = plt.subplots()

# 坐标轴的基本设置(在循环外面设置)
ax.set_xlim(0, 2*np.pi)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('sin_Animation')
ax.grid(True)

frames = []  # 存储每帧的 Artist 列表
x = np.linspace(0, 2*np.pi, 100)

for i in range(50): # 生成50帧动画
    # 每帧绘制新内容,返回的 Artists 加入当前帧列表
    line, = ax.plot(x, np.sin(x + i*0.1), color='blue')
    text = ax.text(0.5, 0.9, f'Frame {i}', transform=ax.transAxes)
    
    # 将当前帧中会变化的元素(line 和 text)加入列表
    frames.append([line, text]) 

# 创建动画对象
ani = animation.ArtistAnimation(
    fig, 
    frames,           # 预先生成的帧序列
    interval=40,      # 每帧间隔 40 毫秒
    repeat=True,      # 循环播放
    blit=True         # 启用双缓冲优化,提升渲染性能
)

# 保存为 GIF 文件(也可保存为 MP4,但需要安装 ffmpeg)
ani.save(
    'sine_animation.gif',  # 文件名
    writer='pillow',       # 使用 Pillow 库写入 GIF
    fps=25,                # 帧率(与 interval=40 对应)
    dpi=100                # 输出分辨率
)

plt.show()

十. 3D图表

Matplotlib 本质上是二维绘图库,其三维功能是通过三维数据投影到二维平面,并配合深度排序(z-order)来实现的。这种方式适合简单的三维可视化,但在处理复杂三维场景时存在一定局限。它交互性比较弱,旋转、缩放不如专业三维软件流畅。它渲染效果有限,难以实现复杂光照、透明体绘制、流场模拟等高级特效。并且当数据量过大时,渲染会变慢很多。

因此对于复杂专业的3D图表绘制并不推荐使用matplotlib进行绘制,但是对于简单的3D演示Matplotlib 还是可以做到的,比如简单的3D曲面图,线框图,3D线图,3D散点图等

如果你需要专业的3D科研绘图软件/python库,推荐使用Mayavi

十一. 其它图表

至此,我们已经系统性地讲解了 Matplotlib 中最核心、最高频的图表类型和绘图逻辑。然而,它的能力远不止于此。就像一个功能丰富的工具箱,除了常用的“扳手”和“螺丝刀”,它还提供了许多针对特定场景的工具:

比如绘制简单图形(圆形,菱形,矩形等),极坐标系,箱形图,饼图,六边形分箱图,矢量场图,流线图,小提琴图,数据表格...

你不需要立即掌握所有这些内容。 本系列教程的核心目标,是为你构建一个坚实、通用的绘图思维框架和操作基础。你现在已经拥有了阅读官方文档、理解示例代码并快速上手的能力。

当你未来的项目需要某个特定类型的图表时,完全可以带着明确的目标去定向学习。在你厚实的基础上,再让AI来辅助学习理解,马上掌握一个新类型的图表不是什么难事。

记住,工具为思想服务。最后,我想说,不论你是什么专业,只要是打算学习python,那么pandas,matplotlib,numpy这三个库最好都去学习一下,因为它们是你在Python世界中,处理、分析和呈现数据基础能力三角。无论你是进行学术研究、商业分析、网站开发,还是学习人工智能,几乎所有的数据任务都绕不开这三个库以及它们的设计思想。它们构成了一个从数据到见解的完整工作流,掌握并且能熟练使用它们,你的Python可以说是真正的入门了。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com