matplotlib初级教程
前言
Matplotlib 是 Python 中最受欢迎的数据可视化软件包之一,支持跨平台运行,它是 Python 常用的 2D 绘图库,同时它也提供了一部分 3D 绘图接口。Matplotlib 通常与 NumPy、Pandas 一起使用,是数据分析中不可或缺的重要工具之一。
Matplotlib 是 Python 中类似 MATLAB 的绘图工具,如果您熟悉 MATLAB,那么可以很快的熟悉它。Matplotlib 提供了一套面向对象绘图的 API,它可以轻松地配合 Python GUI 工具包(比如 PyQt,WxPython、Tkinter)在应用程序中嵌入图形。与此同时,它也支持以脚本的形式在 Python、IPython Shell、Jupyter Notebook 以及 Web 应用的服务器中使用。
教程特点
本套教程适合 Matplotlib 的初学者学习,在学习完本教程后,您将掌握 Matplotlib 的种绘图方法,并对数据可视化这一概念,有一个全新的认识。
本套教程从 Matplotlib 基础知识入手,手把手教你如何使用matplotlib.pyplot模块绘制各种图形,比如柱状图、饼状图、折线图等。教程中介绍了与 Matplotlib 绘图相关的图形对象、轴域对象、坐标轴设置等知识,通过学习这些知识,您将全面掌握如何 Matplotlib 的绘图方法。本套教程中使用了大量的绘图实例,通过实例与知识相结合的方式,让学习 Matplotlib 绘图变的轻松、有趣。
阅读条件
Matplotlib 是用 Python 语言编写的,并且能够与 Python 的科学计算库 NumPy 搭配使用。因此,在阅读本教程前,你应该掌握 Python 的基础知识,并且对 NumPy 库有一定程度的了解,在您学习本套教程时,这些知识对您大有裨益。
1 Matplotlib是什么
Matplotlib 是一款用于数据可视化的 Python 软件包,支持跨平台运行,它能够根据 NumPy ndarray 数组来绘制 2D 图像,它使用简单、代码清晰易懂,深受广大技术爱好者喜爱。
''' NumPy 是 Python 科学计算的软件包,ndarray 则是 NumPy 提供的一种数组结构。'''
Matplotlib 由 John D. Hunter 在 2002 年开始编写, 2003 年 Matplotlib 发布了第一个版本,并加入了 BSD 开源软件组织。Matplotlib 1.4 是最后一个支持 Python 2 的版本,它的最新版本 3.1.1 已于 2019 年 7 月 1 日发布。

Matplotlib 提供了一个套面向绘图对象编程的 API 接口,能够很轻松地实现各种图像的绘制,并且它可以配合 Python GUI 工具(如 PyQt、Tkinter 等)在应用程序中嵌入图形。同时 Matplotlib 也支持以脚本的形式嵌入到 IPython shell、Jupyter 笔记本、web 应用服务器中使用。
2 Matplotlib结构
Matplotlib架构组成
Matplotlib 由三个不同的层次结构组成,分别是脚本层、美工层和后端层。

图2:Matplotlib架构图
1) 脚本层
脚本层是 Matplotlib 结构中的最顶层。我们编写的绘图代码大部分代码都在该层运行,它的主要工作是负责生成图形与坐标系。
2) 美工层
美工层是结构中的第二层,它提供了绘制图形的元素时的给各种功能,例如,绘制标题、轴标签、坐标刻度等。
3) 后端层
后端层是 Matplotlib 最底层,它定义了三个基本类,首先是 FigureCanvas(图层画布类),它提供了绘图所需的画布,其次是 Renderer(绘图操作类),它提供了在画布上进行绘图的各种方法,最后是 Event(事件处理类),它提供了用来处理鼠标和键盘事件的方法。
Matplotlib图形结构
matplotlib图形包含容器层、辅助显示层、图像层的三层结构构成:
- 容器层:
- Canvas层(画板层):位于最底层的系统层,在绘图的过程中充当画板的角色,即放置画布(Figure)的工具。
- Figure层(画布层):Canvas上方的第一层,也是需要用户来操作的应用层的第一层,在绘图的过程中充当画布的角色。
- Axes层(绘图区层):应用层的第二层,在绘图的过程中相当于画布上的坐标系/绘图区的角色,可以通过使用plt.subplots()来分割画布来得到若干个坐标系/绘图区,返回的是绘画区的列表,通过调用列表中每个绘画区在对应的位置画图;注意:设置绘画区的编号应该从编号1开始的。坐标系Axis这个很容易和Axes混淆,实际上它是位于每个Axes上,可以通过其设置显示图形所在坐标轴的大小、刻度、刻度标签。
- 辅助显示层:
辅助显示层为Axes(绘图区)内的除了根据数据绘制出的图像以外的内容,主要包括Axes外观(facecolor)、边框线(spines)、坐标轴(axis)、坐标轴名称(axis label)、坐标轴刻度(tick)、坐标轴刻度标签(tick label)、网格线(grid)、图例(legend)、标题(title)等内容。
该层的设置可使图像显示更加直观更加容易被用户理解,但又不会对图像产生实质的影响。 - 图像层:图像层指Axes内通过plot、scatter、bar、histogram、pie等函数根据数据绘制出的图像。

总结
Canvas(画板)位于最底层,用户一般接触不到
Figure(画布)建立在Canvas之上
Axes(绘图区)建立在Figure之上
坐标轴(axis)、图例(legend)等辅助显示层以及图像层都是建立在Axes之上
Matplotlib 生成的图形主要由以下几个部分构成:

- Figure:指整个图形,您可以把它理解成一张画布,它包括了所有的元素,比如标题、轴线等;
- Axes:绘制 2D 图像的实际区域,也称为轴域区,或者绘图区;
- Axis:指坐标系中的垂直轴与水平轴,包含轴的长度大小(图中轴长为 7)、轴标签(指 x 轴,y轴)和刻度标签;
- Artist:您在画布上看到的所有元素都属于 Artist 对象,比如文本对象(title、xlabel、ylabel)、Line2D 对象(用于绘制2D图像)等。
补充:可以有两种理解方式,第一种,Figure当作图,Axes当作子图,axis是子图的坐标轴,有且只有一个图,有一个或者多个子图;第二种,Figure当作画布,Axes当作绘图区域,axis是绘图区域坐标轴,有且只有一个画布,有一个或者多个绘图区域,axis是每个绘图区域的坐标轴。
画图步骤
Matplotlib功能扩展包
许多第三方工具包都对 Matplotlib 进行了功能扩展,其中有些安装包需要单独安装,也有一些允许与 Matplotlib 一起安装。常见的工具包如下:
- Bashmap:这是一个地图绘制工具包,其中包含多个地图投影,海岸线和国界线;
- Cartopy:这是一个映射库,包含面向对象的映射投影定义,以及任意点、线、面的图像转换能力;
- Excel tools: 这是 Matplotlib 为了实现与 Microsoft Excel 交换数据而提供的工具;
- Mplot3d:它用于 3D 绘图;
- Natgrid:这是 Natgrid 库的接口,用于对间隔数据进行不规则的网格化处理。
3 Matplotlib下载和安装
Matplotlib 是 Python 的第三方绘图库,它非常类似于 MATLAB。在使用 Matplotlib 软件包之前,需要对其进行安装。本节以 Windows10 系统为例,介绍 Matplotlib 的几种安装方式。
MATLAB 是一款商业软件,主要用于数据分析、图像处理、计算机视觉等领域。
使用pip理器安装
使用 Python 包管理器 pip 来安装 Matplotlib 是一种最轻量级的方式。打开 CMD 命令提示符窗口,并输入以下命令:
1 pip install matplotlib
使用Anaconda安装
安装 Matplotlib 的最好的方法是下载 Python 的 Anaconda 发行版,因为 Matplotlib 被预先安装在 Anaconda 中。安装方法如下:
Anaconda 是一个开源的 Python 发行版本,其包含了 Python、NumPy、Matplotlib 等180多个科学包及其依赖项。
验证安装
要验证 Matplotlib 是否成功安装,可以在命令提示符窗口执行以下命令:
import matplotlib matplotlib.__version__ '3.1.1'
4 Matplotlib.pyplot接口汇总
Matplotlib 中的 pyplot 模块是一个类似命令风格的函数集合,这使得 Matplotlib 的工作模式和 MATLAB 相似。
pyplot 模块提供了可以用来绘图的各种函数,比如创建一个画布,在画布中创建一个绘图区域,或是在绘图区域添加一些线、标签等。以下表格对这些函数做了简单地介绍。
绘图类型
| 函数名称 | 描述 |
|---|---|
| Bar | 绘制条形图 |
| Barh | 绘制水平条形图 |
| Boxplot | 绘制箱型图 |
| Hist | 绘制直方图 |
| his2d | 绘制2D直方图 |
| Pie | 绘制饼状图 |
| Plot | 在坐标轴上画线或者标记 |
| Polar | 绘制极坐标图 |
| Scatter | 绘制x与y的散点图 |
| Stackplot | 绘制堆叠图 |
| Stem | 用来绘制二维离散数据绘制(又称为“火柴图”) |
| Step | 绘制阶梯图 |
| Quiver | 绘制一个二维按箭头 |
Image函数
| 函数名称 | 描述 |
|---|---|
| Imread | 从文件中读取图像的数据并形成数组。 |
| Imsave | 将数组另存为图像文件。 |
| Imshow | 在数轴区域内显示图像。 |
Axis函数
| 函数名称 | 描述 |
|---|---|
| Axes | 在画布(Figure)中添加轴 |
| Text | 向轴添加文本 |
| Title | 设置当前轴的标题 |
| Xlabel | 设置x轴标签 |
| Xlim | 获取或者设置x轴区间大小 |
| Xscale | 设置x轴缩放比例 |
| Xticks | 获取或设置x轴刻标和相应标签 |
| Ylabel | 设置y轴的标签 |
| Ylim | 获取或设置y轴的区间大小 |
| Yscale | 设置y轴的缩放比例 |
| Yticks | 获取或设置y轴的刻标和相应标签 |
Figure函数
| 函数名称 | 描述 |
|---|---|
| Figtext | 在画布上添加文本 |
| Figure | 创建一个新画布 |
| Show | 显示数字 |
| Savefig | 保存当前画布 |
| Close | 关闭画布窗口 |
5 第一个Matplotlib绘图程序
本节学习第一个 Matplotlib 绘图程序,如何使用 Matplotlib 绘制一个简单的折线图。下面绘制一个简单正弦曲线图,它显示了角度与正弦函数值之间的关系。
第一个绘图程序
首先导入 Matplotlib 包中的 Pyplot 模块,并以 as 别名的形式简化引入包的名称。
1 import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
接下来,使用 NumPy 提供的函数 arange() 创建一组数据来绘制图像。
#引入numpy包 import numpy as np #获得0到2π之间的ndarray对象 x = np.arange(0, math.pi*2, 0.05)
上述所得 x 的值作用到 x 轴上,而该值对应的正弦值,也就是 y 值,使用以下方法获取:
y = np.sin(x)
使用 plot() 函数对 x、y 进行绘制。
plt.plot(x,y)
主要的绘图工作已经完成,不过还需要绘制一些细节,需要我们补充一下,比如图像的标题(title)、x 轴与 y 轴的标签(label)等。
plt.xlabel("angle")
plt.ylabel("sine")
plt.title('sine wave')
完整的程序代码如下:
from matplotlib import pyplot as plt
import numpy as np
import math
#调用math.pi方法弧度转为角度
x = np.arange(0, math.pi*2, 0.05)
y = np.sin(x)
plt.plot(x,y)
plt.xlabel("angle")
plt.ylabel("sine")
plt.title('sine wave')
#使用show展示图像
plt.show()
代码执行后,显示结果如下:

图1:sine正弦函数图像
您也可以在 Jupyter 笔记本中运行 Matplotlib 的绘图程序。通过命令行或者开始菜单的方式启动 Jupyter 笔记本。启动成功后,将上述代码拷贝到输入行内,如下所示:

图2:Jupyter交互式笔记本
注意:%matplotlib inline 是 Jupyter 提供的魔法命令,它可以把输出图显示在笔记本内部,否则会以查看器的形式单独显示。
6 PyLab绘制曲线图
PyLab 是一个面向 Matplotlib 的绘图库接口,其语法和 MATLAB 十分相近。它和 Pyplot 模快都够实现 Matplotlib 的绘图功能。PyLab 是一个单独的模块,随 Matplotlib 软件包一起安装,该模块的导包方式和 Pyplot 不同,如下所示:
#Pyplot导包方式 from matplotlib import pyplot as plt #PyLab导包有两种方式 import pylab from pylab import *
PyLab 是一个很便捷的模块,下面对它的使用方法做相应的介绍。
基本绘图
提供一对相同长度的数组(或序列),然后使用plot()绘制曲线,示例如下:
from numpy import * from pylab import * x = linspace(-3, 3, 30) y = x**2 plot(x, y) show()
输出结果:

图1:绘制曲线图
如果您要绘制特殊类型的线条,并想添加一些颜色,PyLab 提供了如下方法:
| 符号 | '-','--','-.',':','.',',',,o,^,v,<,>,s,+,x,D,d,1,2,3,4,h,H,p,| ,_ |
| 颜色 | b(蓝色),g(绿色),r(红色),c(青色),m(品红),y(黄色),k(黑色),w(白色) |
使用示例如下:
from pylab import * x = linspace(-3, 3, 30) y = x**2 plot(x, y, 'r.') show()
输出结果:

图2:红点曲线图
如果您想在同一绘图区域内绘制多个图形,只需要使用多个绘图命令。示例如下:
from pylab import * plot(x, sin(x)) plot(x, cos(x), 'r-') plot(x, -sin(x), 'g--') show()
输出结果:

图3:绘制多条不同曲线
如果您想清除图像,直接在程序末尾调用 clf() 方法即可。
7 Matplotlib figure图形对象
通过前面的学习,我们知道matplotlib.pyplot模块能够快速地生成图像,但如果使用面向对象的编程思想,我们就可以更好地控制和自定义图像。
在 Matplotlib 中,面向对象编程的核心思想是创建图形对象(figure object)。通过图形对象来调用其它的方法和属性,这样有助于我们更好地处理多个画布。在这个过程中,pyplot 负责生成图形对象,并通过该对象来添加一个或多个 axes 对象(即绘图区域)。
Matplotlib 提供了matplotlib.figure图形类模块,它包含了创建图形对象的方法。
1 class matplotlib.figure.Figure(figsize=None, dpi=None, facecolor=None, edgecolor=None, linewidth=0.0, frameon=None, subplotpars=None, tight_layout=None, constrained_layout=None, *, layout=None, **kwargs)[source]
通过调用 pyplot 模块中 figure() 函数来实例化 figure 对象。如下所示:
from matplotlib import pyplot as plt #创建图形对象 fig = plt.figure()
该函数的参数值,如下所示:
| 参数 | 说明 |
|---|---|
| figsize | 指定画布的大小,(宽度,高度),单位为英寸。 |
| dpi | 指定绘图对象的分辨率,即每英寸多少个像素,默认值为80。 |
| facecolor | 背景颜色。 |
| edgecolor | 边框颜色。 |
| frameon | 是否显示边框。 |
下面使用 figure() 创建一个空白画布:
fig = plt.figure()
我们使用 add_axes() 将 axes 轴域添加到画布中。如下所示:
ax=fig.add_axes([0,0,1,1])
add_axes() 的参数值是一个序列,序列中的 4 个数字分别对应图形的左侧,底部,宽度,和高度,且每个数字必须介于 0 到 1 之间。
设置 x 和 y 轴的标签以及标题,如下所示:
ax.set_title("sine wave")
ax.set_xlabel('angle')
ax.set_ylabel('sine')
调用 axes 对象的 plot() 方法,对 x 、 y 数组进行绘图操作:
ax.plot(x,y)
完整的代码如下所示:
from matplotlib import pyplot as plt
import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
y = np.sin(x)
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.plot(x,y)
ax.set_title("sine wave")
ax.set_xlabel('angle')
ax.set_ylabel('sine')
plt.show()
输出结果如下:

图1:运行结果图
在 Jupyter Notebook 中运行程序,结果如下:

图2:运行结果
8 Matplotlib axes类
Matplotlib 定义了一个 axes 类(轴域类),该类的对象被称为 axes 对象(即轴域对象),它指定了一个有数值范围限制的绘图区域。在一个给定的画布(figure)中可以包含多个 axes 对象,但是同一个 axes 对象只能在一个画布中使用。
2D 绘图区域(axes)包含两个轴(axis)对象;如果是 3D 绘图区域,则包含三个。
通过调用 add_axes() 方法能够将 axes 对象添加到画布中,该方法用来生成一个 axes 轴域对象,对象的位置由参数rect决定, 在一个画布figure中可以添加多个axes绘图区域。
rect 是位置参数,接受一个由 4 个元素组成的浮点数列表,必须是0-1之间,形如 [left, bottom, width, height] ,它表示添加到画布中的矩形区域的左下角坐标(x, y),以及宽度和高度。如下所示:
ax=fig.add_axes([0.1,0.1,0.8,0.8])
注意:每个元素的值是画布宽度和高度的分数。即将画布的宽、高作为 1 个单位。比如,[ 0.1, 0.1, 0.8, 0.8],它代表着从画布 10% 的位置开始绘制, 宽高是画布的 80%。
下面介绍 axes 类的其他成员函数,这些函数在绘图过程中都承担着不同的作用。
legend()绘制图例
axes 类的 legend() 方法负责绘制画布中的图例,它需要三个参数,如下所示:
ax.legend(handles, labels, loc)
- handles 图例的句柄,被添加到图例的美工(Artist)实例的list。
- labels 字符串list,用来指定标签的名称;
- loc 是指定图例位置的参数,其参数值可以用字符串或整数来表示;
下面是 loc 参数的表示方法,分为字符串和整数两种,如下所示:
| 位置 | 字符串表示 | 整数数字表示 |
|---|---|---|
| 自适应 | Best | 0 |
| 右上方 | upper right | 1 |
| 左上方 | upper left | 2 |
| 左下 | lower left | 3 |
| 右下 | lower right | 4 |
| 右侧 | right | 5 |
| 居中靠左 | center left | 6 |
| 居中靠右 | center right | 7 |
| 底部居中 | lower center | 8 |
| 上部居中 | upper center | 9 |
| 中部 | center |
10 |
两种添加图例的方法如下:
第一种:
1 fig = plt.figure(1) 2 ax = plt.subplot(111) 3 x = np.arange(0., 5., 0.2) 4 cosx = np.cos(x) 5 sinx = np.sin(x) 6 line1, = ax.plot(x, cosx, 'r-.',label = 'y=cos(x)' ) 7 line2, =ax.plot(x, sinx, 'c',label = 'y=sin(x)') 8 # 创建第一个图例:y=cosx 9 first_legend = plt.legend(handles=[line1], loc='lower right') 10 # 添加第一个图例 11 ax.add_artist(first_legend) 12 # 添加第二个图例 13 ax.legend(handles=[line2], loc='upper right') 14 plt.show()

第二种:
1 fig = plt.figure(1) 2 ax = plt.subplot(111) 3 x = np.arange(0., 5., 0.2) 4 cosx = np.cos(x) 5 sinx = np.sin(x) 6 line1, = ax.plot(x, cosx, 'r-.') 7 line2, =ax.plot(x, sinx, 'c') 8 ax.legend(handles=[line1,line2], labels= ['y=cos(x)', 'y=sin(x)' ], loc='upper right') 9 plt.show()

axes.plot()
这是 axes 类的最基本方法,用于绘制XY坐标系的点、线或者其它标记。调用方法:
plot([x], y, [fmt], data=None, **kwargs)
plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
点和线的坐标由参数x,y提供,x非必须。可选参数fmt是一个快捷字符串,用于定义颜色,标记符号和线条形状,例如:
1 plot(x, y) # 使用默认颜色和形状 2 plot(x, y, 'bo') # 使用蓝色(blue)、圆点型绘图 3 plot(y) # 绘制y坐标,x坐标使用列表0..N-1 4 plot(y, 'r+') # 同上,但使用红色(red)+号形状
也可使用Line2D属性作为关键字,以此来更好地控制显示效果,Line属性和fmt可以混合使用,下面的两种写法效果相同,当关键字与fmt冲突时,关键字优先。
1 plot(x, y, 'go--', linewidth=2, markersize=12) 2 plot(x, y, color='green', marker='o', linestyle='dashed', linewidth=2, markersize=12)
注意:fmt由颜色、标记和线型三种类型组合,每种类型只能选一种样式。
颜色代码如下表:
| 字符 | 颜色 |
|---|---|
'b' |
blue 蓝色 |
'g' |
green 绿色 |
'r' |
red 红色 |
'c' |
cyan 青色 |
'm' |
magenta 紫红色 |
'y' |
yellow 黄色 |
'k' |
black 黑色 |
'w' |
white 白色 |
支持的marker标记符号如下表:
| 字符 | 描述 |
|---|---|
'.' |
point marker 点标记 |
',' |
pixel marker 像素 |
'o' |
circle marker 圆圈型 |
'v' |
triangle_down marker 下三角 |
'^' |
triangle_up marker 上三角 |
'<' |
triangle_left marker 左三角 |
'>' |
triangle_right marker 右三角 |
'1' |
tri_down marker |
'2' |
tri_up marker |
'3' |
tri_left marker |
'4' |
tri_right marker |
's' |
square marker 方形 |
'p' |
pentagon marker 五角形 |
'*' |
star marker 星型 |
'h' |
hexagon1 marker 六角形1 |
'H' |
hexagon2 marker 六角形2 |
'+' |
plus marker 加号 |
'x' |
x marker ×型标记 |
'D' |
diamond marker 钻石型 |
'd' |
thin_diamond marker 细钻石型 |
'|' |
vline marker 竖线型 |
'_' |
hline marker 横线型 |
支持的line线型表示字符有:
| 字符 | 描述 |
| '-' | solid line style 实线 |
| '--' | dashed line style 虚线 |
| '-.' | dash-dot line style 交错点线 |
| ':' | dotted line style 点线 |
| 'H' | 六角形 |
返回值lines代表绘制数据的Line2D对象。
其它参数:
scalex,scaley:布尔值,可选,默认为True。
这组参数用于设置图形坐标的边界是否适应数据的边界,参数值传给autoscale_view。
**kwargs:Line2D属性,可选。
kwargs用于设置特殊的属性,如线条标签、线条宽度、平滑效果、标记点的颜色等。
如果使用一个命令绘制多条线,那么kwargs的样式将被用于所有线条。
Line2D 的全部属性:
|
Property |
Description |
|---|---|
|
a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array |
|
|
scalar or None |
|
|
bool |
|
|
|
bool |
|
bool |
|
|
Patch or (Path, Transform) or None |
|
|
|
color |
|
|
|
|
|
|
|
sequence of floats (on/off ink in points) or (None, None) |
|
|
(2, N) array or two 1D arrays |
|
|
|
{'default', 'steps', 'steps-pre', 'steps-mid', 'steps-post'}, default: 'default' |
|
{'full', 'left', 'right', 'bottom', 'top', 'none'} |
|
|
str |
|
|
bool |
|
|
object |
|
|
|
{'-', '--', '-.', ':', '', (offset, on-off-seq), ...} |
|
|
float |
|
marker style string, |
|
|
|
color |
|
|
float |
|
|
color |
|
|
color |
|
|
float |
|
None or int or (int, int) or slice or list[int] or float or (float, float) or list[bool] |
|
|
float or callable[[Artist, Event], tuple[bool, dict]] |
|
|
float |
|
|
bool |
|
|
(scale: float, length: float, randomness: float) |
|
|
bool or None |
|
|
|
|
|
|
|
|
unknown |
|
|
str |
|
|
bool |
|
|
1D array |
|
|
1D array |
|
|
float |
一条命令绘制三条不同的线:
格式:plt.plot(x1,y1,fmt1, x2,y2,fmt2, xn,yn,fmtn)
1 import numpy as np 2 import matplotlib.pyplot as plt 3 4 # evenly sampled time at 200ms intervals 5 t = np.arange(0., 5., 0.2) 6 7 # red dashes, blue squares and green triangles 8 plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^') 9 plt.show()

3种不同的连线效果:
1 import numpy as np 2 import matplotlib.pyplot as plt 3 4 5 def plot_angle(ax, x, y, angle, style): 6 phi = np.radians(angle) 7 xx = [x + .5, x, x + .5 * np.cos(phi)] 8 yy = [y, y, y + .5 * np.sin(phi)] 9 ax.plot(xx, yy, lw=8, color='blue', solid_joinstyle=style) 10 ax.plot(xx[1:], yy[1:], lw=1, color='black') 11 ax.plot(xx[1::-1], yy[1::-1], lw=1, color='black') 12 ax.plot(xx[1:2], yy[1:2], 'o', color='red', markersize=3) 13 ax.text(x, y + .2, '%.0f degrees' % angle) 14 15 16 fig, ax = plt.subplots() 17 ax.set_title('Join style') 18 19 for x, style in enumerate((('miter', 'round', 'bevel'))): 20 ax.text(x, 5, style) 21 for i in range(5): 22 plot_angle(ax, x, i, pow(2.0, 3 + i), style) 23 24 ax.set_xlim(-.5, 2.75) 25 ax.set_ylim(-.5, 5.5) 26 plt.show()

下面的例子,以直线图的形式展示了电视、智能手机广告费与其所带来产品销量的关系图。其中描述电视的是带有黄色和方形标记的实线,而代表智能手机的则是绿色和圆形标记的虚线。
import matplotlib.pyplot as plt
y = [1, 4, 9, 16, 25,36,49, 64]
x1 = [1, 16, 30, 42,55, 68, 77,88]
x2 = [1,6,12,18,28, 40, 52, 65]
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
#使用简写的形式color/标记符/线型
l1 = ax.plot(x1,y,'ys-')
l2 = ax.plot(x2,y,'go--')
ax.legend(labels = ('tv', 'Smartphone'), loc = 'lower right') # legend placed at lower right
ax.set_title("Advertisement effect on sales")
ax.set_xlabel('medium')
ax.set_ylabel('sales')
plt.show()
输出结果如下:

9 Matplotlib subplot()
在使用 Matplotlib 绘图时,我们大多数情况下,需要将一张画布划分为若干个子区域,之后,我们就可以在这些区域上绘制不用的图形。在本节,我们将学习如何在同一画布上绘制多个子图。matplotlib.pyplot模块提供了一个 subplot() 函数,它可以均等地划分画布,该函数的参数格式如下:
matplotlib.pyplot.subplot(*args, **kwargs)
接口格式包含:
subplot(nrows, ncols, index, **kwargs) subplot(pos, **kwargs) subplot(**kwargs) subplot(ax)
参数含义如下:
- *args: int, (int, int, index), or
SubplotSpec, default: (1, 1, 1); 绘制的子图区域; - projection: {None, 'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', 'rectilinear', str}, optional; 投影类型;
- polar: bool, default: False; 是否支持极坐标;
- sharex, sharey:
Axes, optional; 是否共享X/Y轴; - label: str; 给返回的子图Axes的标签。
- 其它参数: **kwargs。
返回:
返回当前绘图区域子图的对象axes.SubplotBase, or another subclass of Axes;
常用格式:
plt.subplot(nrows, ncols, index)
nrows 与 ncols 表示要划分几行几列的子区域(nrows*nclos表示子图数量),index 的初始值为1,用来选定具体的某个子区域。
例如: subplot(233)表示在当前画布的右上角创建一个两行三列的绘图区域(如下图所示),同时,选择在第 3 个位置绘制子图。

如果新建的子图与现有的子图重叠,那么重叠部分的子图将会被自动删除,因为它们不可以共享绘图区域。
import matplotlib.pyplot as plt
plt.plot([1,2,3])
#现在创建一个子图,它表示一个有2行1列的网格的顶部图。
#因为这个子图将与第一个重叠,所以之前创建的图将被删除
plt.subplot(211)
plt.plot(range(12))
#创建带有黄色背景的第二个子图
plt.subplot(212, facecolor='y')
plt.plot(range(12))
上述代码运行结果,如下图所示:

图2:subplot绘制结果
如果不想覆盖之前的图,需要使用 add_subplot() 函数,代码如下:
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot([1,2,3])
ax2 = fig.add_subplot(221, facecolor='y')
ax2.plot([1,2,3])
执行上述代码,输出结果如下:

图3:add_subplot()绘图结果
通过给画布添加 axes 对象可以实现在同一画布中插入另外的图像。
import matplotlib.pyplot as plt
import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
fig=plt.figure()
axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # main axes
axes2 = fig.add_axes([0.55, 0.55, 0.3, 0.3]) # inset axes
y = np.sin(x)
axes1.plot(x, y, 'b')
axes2.plot(x,np.cos(x),'r')
axes1.set_title('sine')
axes2.set_title("cosine")
plt.show()
输出结果如下:

图4:输出结果图
10 Matplotlib subplots()函数
matplotlib.pyplot模块提供了一个 subplots() 函数,它的使用方法和 subplot() 函数类似,两个对比学习。其不同之处在于,subplots() 既创建了一个包含子图区域的画布,又创建了一个 figure 图形对象,而 subplot() 只是创建一个包含子图区域的画布。
matplotlib.pyplot.subplots(nrows=1, ncols=1, *, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw)[source]
参数:
- nrows, ncols: int, default: 1; 画布占用的行数和列数;
- sharex, sharey: bool or {'none', 'all', 'row', 'col'}, default: False; 是否共享x/y轴;
- squeeze: bool, default: True;
- subplot_kw:dict, optional
- gridspec_kw:dict, optional
- **fig_kw:
返回:
subplots 常用函数格式如下:
fig , ax = plt.subplots(nrows, ncols)
nrows 与 ncols 表示两个整数参数,它们指定子图所占的行数、列数。
注意:
plt.subplots()与plt.subplot()的区别,subplot是在当前画布的基础上,创建N个绘图区域axes,并返回指定的绘图区域作为当前的默认绘图区域;
subplots()是创建N个绘图区域axes,并且返回画布对象figure和所有绘图区域的ndarray数组axeses。
fig, axes = plt.subplots(2,2)
ax = plt.subplot(2,2,1)
type(fig),type(axes),type(axes[0][0]),type(ax)
(matplotlib.figure.Figure,
numpy.ndarray,
matplotlib.axes._subplots.AxesSubplot,
matplotlib.axes._subplots.AxesSubplot)
函数的返回值是一个元组,包括一个图形对象和所有的 axes 对象。其中 axes 对象的数量等于 nrows * ncols,且每个 axes 对象均可通过索引值访问(从1开始)。
下面我们创建了一个 2 行 2 列的子图,并在每个子图中显示 4 个不同的图像。
import matplotlib.pyplot as plt
fig,a = plt.subplots(2,2)
import numpy as np
x = np.arange(1,5)
#绘制平方函数
a[0][0].plot(x,x*x)
a[0][0].set_title('square')
#绘制平方根图像
a[0][1].plot(x,np.sqrt(x))
a[0][1].set_title('square root')
#绘制指数函数
a[1][0].plot(x,np.exp(x))
a[1][0].set_title('exp')
#绘制对数函数
a[1][1].plot(x,np.log10(x))
a[1][1].set_title('log')
plt.show()
上述代码的输出结果如下:

11 subplot2grid()函数
matplotlib.pyplot 模块提供了 subplot2grid() ,该函数能够在画布的常规网格特定位置创建 axes 对象(即绘图区域)。不仅如此,它还可以使用不同数量的行、列来创建跨度不同的绘图区域。与 subplot() 和 subplots() 函数不同,subplot2gird() 函数以非等分的形式对画布进行切分,并按照绘图区域的大小来展示最终绘图结果。这里的grid更准确的说法应该是绘图区域layout布局网格,与每个子图中的网格不同。
函数语法格式如下:
AxesSubplot = plt.subplot2grid(shape, location, rowspan, colspan)
参数含义如下:
- shape:设定绘图布局。组合图框架形状,以元组形式传递,该参数值规定的网格区域作为绘图区域,如2行3列可以表示为(2,3);
- location:选中绘图。根据网格指定绘制子图所在位置,初始位置 (0,0) 表示第1行第1列;
- rowsapan/colspan:确定选中行列区域数量,编号从0开始。指定子图需要跨几行几列。如果没有指定,默认跨越1行1列。
- 返回子图对象axes。
以3X3布局为例,说明子图位置与跨行列问题:

下面,在画布(figure)中添加了行、列跨度均不相同的绘图子区域,然后在每个绘图区上,绘制不同的图形。示例代码如下:
1 import matplotlib.pyplot as plt
2 #使用 colspan指定列,使用rowspan指定行
3 a1 = plt.subplot2grid((3,3),(0,0),colspan = 2)
4 a2 = plt.subplot2grid((3,3),(0,2), rowspan = 3)
5 a3 = plt.subplot2grid((3,3),(1,0),rowspan = 2, colspan = 2)
6 import numpy as np
7 x = np.arange(1,10)
8 a2.plot(x, x*x)
9 a2.set_title('square')
10 a1.plot(x, np.exp(x))
11 a1.set_title('exp')
12 a3.plot(x, np.log(x))
13 a3.set_title('log')
14 plt.tight_layout()
15 plt.show()
输出结果如下:

图1:subplot2grid()输出结果
12 设置网格格式Axes.grid()
通过 Matplotlib axes 对象提供的 grid() 方法可以开启或者关闭画布中的网格(即是否显示网格)以及网格的主/次刻度。除此之外,grid() 函数还可以设置网格的颜色、线型以及线宽等属性。
Axes.grid(visible=None, which='major', axis='both', **kwargs)
参数含义如下:
- visible: bool or None, optional;网格线是否可见;
- which:{'major', 'minor', 'both'}, optional;应用更改的网格线;
- axis:{'both', 'x', 'y'}, optional;应用更改的坐标轴;
- **kwargs:
Line2Dproperties;定义的网格线Line2D线对象属性;
常用接口形式:
grid(color='r', linestyle='-', linewidth=2)
网格在默认状态下是关闭的,通过调用上述函数,网格会被自动开启,如果您只是想开启不带任何样式的网格,可以通过 grid(True) 来实现。
实例如下:
1 import matplotlib.pyplot as plt
2 import numpy as np
3 #fig画布;axes子图区域
4 fig, axes = plt.subplots(1,3, figsize = (12,4))
5 x = np.arange(1,11)
6 axes[0].plot(x, x**3, 'g',lw=2)
7 #开启网格
8 axes[0].grid(True)
9 axes[0].set_title('default grid')
10 axes[1].plot(x, np.exp(x), 'r')
11 #设置网格的颜色,线型,线宽
12 axes[1].grid(color='b', ls = '-.', lw = 0.25)
13 axes[1].set_title('custom grid')
14 axes[2].plot(x,x)
15 axes[2].set_title('no grid')
16 fig.tight_layout()
17 plt.show()
上述代码执行后,输出结果:

12A 图脊Spines模块
matplotlib中,Spines一般指绘图区四周的边界线,姑且翻译为图脊。用于在创建axes时生成Spine对象axes.spins, 如图所示。
但也可以手工添加直线型、弧形、圆形图脊,此时不一定是绘图区的边界线,可以是绘图区的任意位置。

spines模块定义了一个Spine类,为类定义了约25个方法,其中包含3个类方法,结构如图:

Spines是Patch的子类,并且继承了Patch的大多数行为,基类为matplotlib.patches.Patch。
Spines 绘制 a line, a circle, 或者 an arc,取决于调用了 set_patch_line, set_patch_circle, or set_patch_arc 中的哪一个。默认是 Line。
参数:
- axes:容纳该Spine的Axes实例;
- spine_type: str, spine的类型,spine的类型分为两大类:
- line直线型:包括left,right,top和bottom。
- circle圆型:包括arc弧形,circle圆形。
- path:用于绘制该spine的Path实例。
Axes.spines 属性是一个字典对象OrderDict 。
Axes 的 projection 不同, OrderDict 的 keys 也不同:
笛卡尔坐标系的 OrderDict.keys() = odict_keys([‘left’, ‘right’, ‘bottom’, ‘top’])
polar 坐标系的 OrderDict.keys() = odict_keys([‘polar’, ‘start’, ‘end’, ‘inner’])
在matplotlib的图中,可以通过ax = plt.gca()方法获取figure的axes对象,gca是‘get current axes’的缩写。axes默认有四个 Spine对象,两个横轴和两个竖轴,分别是 top、bottom、left、right。
import matplotlib.pyplot as plt import numpy as np fig = plt.figure(figsize=(9.6,4.8)) ax1 = plt.subplot(121) ax2 = plt.subplot(122, projection='polar') N = 100 theta = np.linspace(0.0, 2 * np.pi, N, endpoint=True) ax1.plot(theta,theta/6,'--',lw=2) ax2.plot(theta,theta/6,'--',lw=2) print(plt.gca()) #返回当前 axes,如果需要则创建一个 print(ax1.spines.keys()) print(ax2.spines.keys()) plt.savefig('spines21.png',facecolor='w',dpi=200) plt.show()
PolarAxesSubplot(0.547727,0.125;0.352273x0.755) odict_keys(['left', 'right', 'bottom', 'top']) odict_keys(['polar', 'start', 'end', 'inner'])

Spins常用的方法包括:
- 获取图脊:通过
axes.Spines['key']来获取 axes.spines 中的单个对象,并设置它的属性。 - 隐藏图脊:使用
set_color()将图脊的颜色设置为None,可以隐藏图脊,注意只是隐藏,默认创建的图脊无法删除。 - 设置图脊位置:使用
set_position()方法设置图脊位置,其参数为 tuple 类型 ,包含两个需要设置的值(position_type, amount)。
一个是位置类型:
-
- ‘outward’,将图脊向图形区域外移动;
- ‘axes’,将图脊放在指定的 Axes 坐标(0到1之间);
- ‘data’,将图脊放在指定的数据坐标位置。
另外还有两个特殊值:
-
- ‘center’ 表示 (‘axes’, 0.5)
- ‘zero’ 表示 (‘data’, 0.0)
- 设置spine图脊边界:set_bounds(*self*, *low=None*, *high=None*)
- low:float or None, optional。图脊的下边界,传递 None,保留原 limit 不改变。也可以在第一个位置参数传递 (low, high) tuple。
- high:float or None, optional。spine 的上界。传递 None,保留原 limit 不改变。
- 偏移axis坐标轴:
- 设置patch:
- set_patch_arc()
- set_patch_circle()
- set_pathc_line()
- 多 vertices 的 path:
import cv2 # cv2格式BGR,BMP位图历史原因造成 import numpy as np import matplotlib.pyplot as plt # matplotlib是RGB %matplotlib inline from matplotlib.path import Path from matplotlib.spines import Spine fig = plt.figure(figsize=(6.4,4.8)) ax = plt.axes(polar=False) x = np.linspace(-1, 1., 100) ax.plot(x, np.sin(x*np.pi)) # 设置左边边界 ax.spines['left'].set_bounds((-2, 2)) # 移动 left 和 bottom spines 到 (0,0) 位置 ax.spines["left"].set_position(("data", 0)) # ax.spines["bottom"].set_position(("data", 0)) ax.spines['left'].set_color('r') #left's Spine 设置为红色 ax.spines['left'].set_linewidth(5) #left's 线宽 ax.spines['top'].set_visible(False) #top's Spine 不可见 print(ax.spines['bottom']) # axes.spines['key']返回的是 Spine 实例 # plt.savefig('spines.png',facecolor='w') plt.show()

13 设置坐标轴比例尺set_xscale()/set_yscale()
Matplotlib 通过 axes 对象的xscale或yscale属性来实现对坐标轴的格式设置。
matplotlib.axes.Axes.set_xscale
Axes.set_xscale(value, **kwargs)
参数:
- value: {"linear", "log", "symlog", "logit", ...} or
ScaleBase;可选的轴刻度标尺;- linear:线性;
- log:对数,其中
basex|basey关键字指定对数的基; - logit: 以2为底的对数;
- symlog:对数,其中
basex|basey关键字指定对数的基;
- **kwargs:不同标尺可选关键字;包含:
matplotlib.scale.SymmetricalLogScale
示例:右侧的子图显示对数刻度,左侧子图则显示标量刻度。
1 import matplotlib.pyplot as plt
2 import numpy as np
3 fig, axes = plt.subplots(1, 2, figsize=(10,4))
4 x = np.arange(1,5)
5 axes[0].plot( x, np.exp(x))
6 axes[0].plot(x,x**2)
7 axes[0].set_title("Normal scale")
8 axes[1].plot (x, np.exp(x))
9 axes[1].plot(x, x**2)
10 #设置y轴
11 axes[1].set_yscale("log")
12 axes[1].set_title("Logarithmic scale (y)")
13 axes[0].set_xlabel("x axis")
14 axes[0].set_ylabel("y axis")
15 axes[0].xaxis.labelpad = 10
16 #设置x、y轴标签
17 axes[1].set_xlabel("x axis")
18 axes[1].set_ylabel("y axis")
19 plt.show()

图1:对数关系图
轴是连接刻度的线,也就是绘图区域的边界,在绘图区域(axes 对象)的顶部、底部、左侧和右侧都有一个边界线(轴)。通过指定轴的颜色和宽度,从而对进行显示格式设置,比如将所有轴的颜色设置为 None,那么它们都会成为隐藏状态,或者也可以给轴添加相应的颜色。以下示例为左侧轴、底部轴分别设置了红色、蓝色,如下所示:
1 import matplotlib.pyplot as plt
2 fig = plt.figure()
3 ax = fig.add_axes([0,0,1,1])
4 #为左侧轴,底部轴添加颜色
5 ax.spines['bottom'].set_color('blue')
6 ax.spines['left'].set_color('red')
7 ax.spines['left'].set_linewidth(2)
8 #将侧轴、顶部轴设置为None
9 ax.spines['right'].set_color(None)
10 ax.spines['top'].set_color(None)
11 ax.plot([1,2,3,4,5])
12 plt.show()
输出结果如下:

图2:输出结果
14 设置坐标轴范围set_xlim()/set_ylim()
Matplotlib 可以根据自变量与因变量的取值范围,自动设置 x 轴与 y 轴的数值大小。当然,您也可以用自定义的方式,通过 set_xlim() 和 set_ylim() 设置 x、y 轴的数值范围进行设置。
当对 3D 图像进行设置的时,会增加一个 z 轴,此时使用 set_zlim() 可以对 z 轴进行设置。
Axes.set_xlim(left=None, right=None, emit=True, auto=False, *, xmin=None, xmax=None)
参数:
- left: float, optional
-
左侧的限制。也可以使用一个二元组。
- right: float, optional
-
右侧的限制。
- emit: bool, default: True
-
是否通知改变。
- auto: bool or None, default: False
-
是否开启x轴的自动缩放。
- xmin, xmax: float, optional
-
分别相当于left和right。不能与left和right混用。
返回值:
- left, right(float, float)
-
新的轴显示的数据范围。
下面示例分别对自动设置和自定义设置做了演示:第一种 Matplotlib 自动设置
1 import matplotlib.pyplot as plt
2 import numpy as np
3 fig = plt.figure()
4 #添加绘图区域
5 a1 = fig.add_axes([0,0,1,1])
6 #准备数据
7 x = np.arange(1,10)
8 #绘制函数图像
9 a1.plot(x, np.exp(x))
10 #添加题目
11 a1.set_title('exp')
12 plt.show()

第二种:自定义设置,set_xlim() 将 x 轴的数值范围设置为(0到10); set_ylim() 将 y 轴的范围设置为(0到10000)。
1 import matplotlib.pyplot as plt
2 fig = plt.figure()
3 a1 = fig.add_axes([0,0,1,1])
4 import numpy as np
5 x = np.arange(1,10)
6 a1.plot(x, np.exp(x),'r')
7 a1.set_title('exp')
8 #设置y轴
9 a1.set_ylim(0,10000)
10 #设置x轴
11 a1.set_xlim(0,10)
12 plt.show()
输出结果如下:

15 设置刻度和刻度标签set_xticks()/set_yticks()
刻度指的是轴上数据点的标记,Matplotlib 能够自动的在 x 、y 轴上绘制出刻度。这一功能的实现得益于 Matplotlib 内置的刻度定位器和格式化器(两个内建类)。在大多数情况下,这两个内建类完全能够满足我们的绘图需求,但是在某些情况下,刻度标签或刻度也需要满足特定的要求,比如将刻度设置为“英文数字形式”或者“大写阿拉伯数字”,此时就需要对它们重新设置。
Axes.set_xticks(ticks, labels=None, *, minor=False, **kwargs)
参数:
- ticks: list of floats. 刻度位置的列表。
- labels: list of str, optional. 刻度标签的列表,如果没有设置,则显示数据值。老版本使用set_xticklabels()设置标签,与labels参数功能一致。
- minor: bool, default: False. 如果为False,则设置主刻度;如果为True,则设置子刻度。
- **kwargs: 标签的文本属性,只有在传递labels参数时才生效。其它情况请使用
tick_params.
xticks() 和 yticks() 函数接受一个列表对象作为参数,列表中的元素表示对应数轴上要显示的刻度。如下所示:
ax.set_xticks([2,4,6,8,10])
x 轴上的刻度标记,依次为 2,4,6,8,10。您也可以分别通过 set_xticklabels() 和 set_yticklabels() 函数设置与刻度线相对应的刻度标签。
下面示例对刻度和标签的使用方法做了说明。
1 import matplotlib.pyplot as plt
2 import numpy as np
3 import math
4 x = np.arange(0, math.pi*2, 0.05)
5 #生成画布对象
6 fig = plt.figure()
7 #添加绘图区域
8 ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
9 y = np.sin(x)
10 ax.plot(x, y)
11 #设置x轴标签
12 ax.set_xlabel('angle')
13 ax.set_title('sine')
14 ax.set_xticks([0,2,4,6])
15 #设置x轴刻度标签
16 ax.set_xticklabels(['zero','two','four','six'])
17 #设置y轴刻度
18 ax.set_yticks([-1,0,1])
19 plt.show()
输出结果如下:

图1:绘制坐标轴刻度与标签
16 中文乱码解决方案(两种方式)
Matplotlib 默认不支持中文字体,这因为 Matplotlib 只支持 ASCII 字符,但中文标注更加符合中国人的阅读习惯。因此,本节重点讲解如何在 Windows 环境下让 Matplotlib 显示中文。
Matplotlib中文乱码
当不对 Matplotlib 进行设置,而直接使用中文时,绘制的图像会出现中文乱码。下面是一个含有中文乱码的折线图:

从上图可以看出,本应该显示在红框内的中文字体没有显示出来(红框是自己标注出来的),下面给出了两种解决方案:第一种是临时解决方案,第二种是一劳永逸的解决方案。
一次性方法:重写配置文件
通过临时重写配置文件的方法,可以解决 Matplotlib 显示中文乱码的问题,代码如下所示:
1 import matplotlib.pyplot as plt
2 plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
3 plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
将上述代码添加到您的绘图程序中,即可解决中文乱码的问题。这是一种非常灵活、便捷的解决方法。完整的程序代码如下:
1 #绘制折线图
2 import matplotlib.pyplot as plt
3 plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
4 plt.rcParams["axes.unicode_minus"]=False #正常显示负号
5 year = [2017, 2018, 2019, 2020]
6 people = [20, 40, 60, 70]
7 #生成图表
8 plt.plot(year, people)
9 plt.xlabel('年份')
10 plt.ylabel('人口')
11 plt.title('人口增长')
12 #设置纵坐标刻度
13 plt.yticks([0, 20, 40, 60, 80])
14 #设置填充选项:参数分别对应横坐标,纵坐标,纵坐标填充起始值,填充颜色
15 plt.fill_between(year, people, 20, color = 'green')
16 #显示图表
17 plt.show()
输出结果如下:

不过上述解决方案适用于所有操作系统,其唯一弊端是每编写一个绘图程序就要添加一次相同的代码。
永久性方法:修改配置文件
下面介绍第二种方式:通过直接修改配置文件的方法,可以一劳永逸的解决 Matplotlib 的中文乱码问题。注意此过程在 Windows 环境下进行。
Matplotlib 从配置文件 matplotlibrc 中读取相关配置信息,比如字体、样式等,因此我们需要对该配置文件进行更改。首先查看 matplotlibrc 所在的目录,使用如下代码确定目录位置:
1 import matplotlib
2 matplotlib.matplotlib_fname()
输出结果:
D:\python\python37\lib\site-packages\matplotlib\mpl-data\matplotlibrc
然后修改配置文件 matplotlibrc。打开配置文件后,找到以下信息:
#font.family: sans-serif #font.serif: DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
将上述配置项前面的#去掉,并修改的配置项,如下所示:
font.family : Microsoft YaHei, sans-serif
font.serif: Microsoft YaHei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
注意,由于版本问题,上述内容配置信息可能存在一些差异,请自动忽略。
最后,在以下目录中复制中文字体微软雅黑:
C:\Windows\Fonts\Microsoft YaHei UI
复制完成后,将字体粘贴至以下路径文件中:
D:\python\python37\lib\site-packages\matplotlib\mpl-data\fonts\ttf
字体粘贴后会出现一个 MSYH.ttc 的字体文件,如下所示:

编写如下代码进行测试:
1 import matplotlib.pyplot as plt
2 import numpy as np
3 x = np.linspace(-8, 8, 1024)
4 y1 = 0.618 * np.abs(x) - 0.8 * np.sqrt(64 - x ** 2)
5 y2 = 0.618 * np.abs(x) + 0.8 * np.sqrt(64 - x ** 2)
6 plt.plot(x, y1, color='r')
7 plt.plot(x, y2, color='r')
8 plt.title("我爱C语言中文网",fontsize=20,color="b")
9 plt.show()
如果你对自己编写的程序没有强烈的“洁癖”,可以接受重复的代码,那么建议您选择第一种解决方法,因为这种方法灵活、轻便。当然您也可以选择第二种方式,一劳永逸的解决中文乱码问题。
17 双轴图Axes.twinx()、Axes.twiny()
在一些应用场景中,有时需要绘制两个 x 轴或两个 y 轴,这样可以更直观地显现图像,从而获取更有效的数据。Matplotlib 提供的 twinx() 和 twiny() 函数,除了可以实现绘制双轴的功能外,还可以使用不同的单位来绘制曲线,比如一个轴绘制对函数,另外一个轴绘制指数函数。
Axes.twinx()
参数: 无
返回值:新创建的Axes实例。
下面示例绘制了一个具有两个 y 轴的图形,一个显示指数函数 exp(x),另一个显示对数函数 log(x)。
1 import matplotlib.pyplot as plt
2 import numpy as np
3 #创建图形对象
4 fig = plt.figure()
5 #添加子图区域
6 a1 = fig.add_axes([0,0,1,1])
7 #准备数据
8 x = np.arange(1,11)
9 #绘制指数函数
10 a1.plot(x,np.exp(x))
11 a1.set_ylabel('exp')
12 #添加双轴
13 a2 = a1.twinx()
14 #‘ro’表示红色圆点
15 a2.plot(x, np.log(x),'ro-')
16 #绘制对数函数
17 a2.set_ylabel('log')
18 #绘制图例
19 fig.legend(labels = ('exp','log'),loc='upper left')
20 plt.show()
输出结果:

18 柱状图
柱状图是一种用矩形柱来表示数据分类的图表,柱状图可以垂直绘制,也可以水平绘制,它的高度与其所表示的数值成正比关系。柱状图显示了不同类别之间的比较关系,图表的水平轴 X 指定被比较的类别,垂直轴 Y 则表示具体的类别值。
Matplotlib 提供了bar()函数来绘制柱状图,它可以应用在 MATLAB 样式以及面向对象的绘图方法中。当它与 axes 对象一起使用时,其语法格式如下:
Axes.bar(x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
该函数的参数说明,如下表所示:
bar()函数参数说明
| x | 一个标量序列,代表柱状图的x坐标,默认x取值是每个柱状图所在的中点位置,或者也可以是柱状图左侧边缘位置。 |
| height | 一个标量或者是标量序列,代表柱状图的高度。 |
| width | 可选参数,标量或类数组,柱状图的默认宽度值为 0.8。 |
| bottom | 可选参数,标量或类数组,柱状图的y坐标默认为None。 |
| algin | 有两个可选项 {"center","edge"},默认为 'center',该参数决定 x 值位于柱状图的位置。 |
该函数的返回值是一个 Matplotlib 容器对象,该对象包含了所有柱状图。
下面是一个关于 Matplotlib 柱状图的简单示例。它用来显示了不同编程语言的学习人数。
1 import matplotlib.pyplot as plt 2 #创建图形对象 3 fig = plt.figure() 4 #添加子图区域,参数值表示[left, bottom, width, height ] 5 ax = fig.add_axes([0,0,1,1]) 6 #准备数据 7 langs = ['C', 'C++', 'Java', 'Python', 'PHP'] 8 students = [23,17,35,29,12] 9 #绘制柱状图 10 ax.bar(x=langs,height=students, width=0.5) 11 plt.show()
输出结果如下:

通过调整柱状图的宽度,可以实现在同一 x 轴位置绘制多个柱状图。您可以将它们设置成不同的颜色,从而使它们更容易区分。下面示例描述了某工程学院过去四年中,三个专业录取的统招学生数量。
1 import numpy as np
2 import matplotlib.pyplot as plt
3 #准备数据
4 data =
5 [[30, 25, 50, 20],
6 [40, 23, 51, 17],
7 [35, 22, 45, 19]]
8 X = np.arange(4)
9 fig = plt.figure()
10 #添加子图区域
11 ax = fig.add_axes([0,0,1,1])
12 #绘制柱状图
13 ax.bar(X + 0.00, data[0], color = 'b', width = 0.25)
14 ax.bar(X + 0.25, data[1], color = 'g', width = 0.25)
15 ax.bar(X + 0.50, data[2], color = 'r', width = 0.25)
上述代码执行后,将显示四个柱状图,将每个柱状图又均分为三个小柱状图,每个柱状图占据 0.25 个单位。

柱状图除了上述使用方法外,还有另外一种堆叠柱状图。所谓堆叠柱状图就是将不同数组别的柱状图堆叠在一起,堆叠后的柱状图高度显示了两者相加的结果值。
bar() 函数提供了一个可选参数bottom,该参数可以指定柱状图开始堆叠的起始值,一般从底部柱状图的最大值开始,依次类推。
下面是一个不同国家参加奥林匹克运动会所得奖牌(金银铜)的柱状堆叠图示例,如下所示:
1 import numpy as np
2 import matplotlib.pyplot as plt
3 countries = ['USA', 'India', 'China', 'Russia', 'Germany']
4 bronzes = np.array([38, 17, 26, 19, 15])
5 silvers = np.array([37, 23, 18, 18, 10])
6 golds = np.array([46, 27, 26, 19, 17])
7 # 此处的 _ 下划线表示将循环取到的值放弃,只得到[0,1,2,3,4]
8 ind = [x for x, _ in enumerate(countries)]
9 #绘制堆叠图
10 plt.bar(ind, golds, width=0.5, label='golds', color='gold', bottom=silvers+bronzes)
11 plt.bar(ind, silvers, width=0.5, label='silvers', color='silver', bottom=bronzes)
12 plt.bar(ind, bronzes, width=0.5, label='bronzes', color='#CD853F')
13 #设置坐标轴
14 plt.xticks(ind, countries)
15 plt.ylabel("Medals")
16 plt.xlabel("Countries")
17 plt.legend(loc="upper right")
18 plt.title("2019 Olympics Top Scorers")
19 plt.show()
在上述代码中,第一次调用plt.bar()绘制了黄色柱状图, 第二次调用plot.bar()时绘制了灰色柱状图,最后一次调用plt.bar()则绘制最底部的柱状图。两个柱状图相接触的位置就是顶部与底部的位置,这样就构成了柱状堆叠图。

19 直方图Axes.hist()
直方图(Histogram),又称质量分布图,它是一种条形图的一种,由一系列高度不等的纵向线段来表示数据分布的情况。 直方图的横轴表示数据类型,纵轴表示分布情况。
首先,我们需要了解柱状图和直方图的区别。直方图用于概率分布,它显示了一组数值序列在给定的数值范围内出现的概率;而柱状图则用于展示各个类别的频数。
例如,我们对某工厂的员工年龄做直方图统计,首先我们要统计出每一位员工的年龄,然后设定一个 20 至 65 的数值范围,并将该数值范围细分为 4 个区间段 (20,35),(35,45),(45,55),(55,65) , 最后通过直方图的形式,展示该工厂员工在相应年龄区间的分布情况。
如果想要构建直方图,必须遵循以下步骤:
- 将整个值范围划分为一系列区间。
- 区间值(bin)的取值,不可遗漏数据;
- 计算每个区间中有多少个值。
通常将 bin 指定为连续且不重叠的数值区间,而 bin 值指区间开始和结束的数值。
您可以使用下面的函数来绘制直方图:
Axes.hist(x, bins=None, range=None, density=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, *, data=None, **kwargs)
注意:类似使用matplotlib.pyplot.hist()接口绘制图形,与使用Axes.hist()实际是一致的,pyplot类似方法只是对Axes同名方法做了一次封装,内置属性和方法都是一样的。
该函数的参数说明如下:
| x | 必填参数,数组或者数组序列。 |
| bins | 可选参数,整数或者序列,bins 表示每一个间隔的边缘(起点和终点)默认会生成10个间隔。 |
| range | 指定全局间隔的下限与上限值 (min,max),元组类型,默认值为 None。 |
| density | 如果为 True,返回概率密度直方图;默认为 False,返回相应区间元素的个数的直方图。 |
| histtype | 要绘制的直方图类型,默认值为“bar”,可选值有 barstacked(堆叠条形图)、step(未填充的阶梯图)、stepfilled(已填充的阶梯图)。 |
以下示例绘制了班级学生得分情况的直方图。其中定义了四个区间(bins)分别是:0-25、26-50、51-75 和 76-100。直方图显示了相应范围的学生人数。
1 from matplotlib import pyplot as plt
2 import numpy as np
3 #创建图形对象和轴域对象
4 fig,ax = plt.subplots(1,1)
5 a = np.array([22,87,5,43,56,73,55,54,11,20,51,5,79,31,27])
6 #绘制直方图
7 ax.hist(a, bins = [0,25,50,75,100])
8 #设置坐标轴
9 ax.set_title("histogram of result")
10 ax.set_xticks([0,25,50,75,100])
11 ax.set_xlabel('marks')
12 ax.set_ylabel('no.of students')
13 plt.show()
上述代码执行后,输出结果如下:

20 饼状图Axes.pie()
饼状图用来显示一个数据系列,具体来说,饼状图显示一个数据系列中各项目的占项目总和的百分比。
Axes.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, rotatelabels=False, *, normalize=True, data=None)
Matplotlib 提供了一个 pie() 函数,该函数可以生成数组中数据的饼状图。您可使用 x/sum(x) 来计算各个扇形区域占饼图总和的百分比。pie() 函数的参数说明如下:
| X | 数组序列,数组元素对应扇形区域的数量大小。 |
| labels | 列表字符串序列,为每个扇形区域备注一个标签名字。 |
| color | 为每个扇形区域设置颜色,默认按照颜色周期自动设置。 |
| autopct | 格式化字符串"fmt%pct",使用百分比的格式设置每个扇形 区的标签,并将其放置在扇形区内。 |
以下示例:关于不同计算机语言学习人数的饼状图。autopct 参数设置为 %1.2f% ,并将各项所占总和的百分比显示在相对应的扇形区内。
1 from matplotlib import pyplot as plt
2 import numpy as np
3 #添加图形对象
4 fig = plt.figure()
5 ax = fig.add_axes([0,0,1,1])
6 #使得X/Y轴的间距相等
7 ax.axis('equal')
8 #准备数据
9 langs = ['C', 'C++', 'Java', 'Python', 'PHP']
10 students = [23,17,35,29,12]
11 #绘制饼状图
12 ax.pie(students, labels = langs,autopct='%1.2f%%')
13 plt.show()
输出结果如下:

21 折线图
折线图(line chart)是我们日常工作、学习中经常使用的一种图表,它可以直观的反映数据的变化趋势。与绘制柱状图、饼状图等图形不同,Matplotlib 并没有直接提供绘制折线图的函数,因此本节着重讲解如何绘制一幅折线图。
绘制单条折线
下面示例是关于用户活跃度的折线图:
1 import matplotlib.pyplot as plt
2 #准备绘制数据
3 x = ["Mon", "Tues", "Wed", "Thur", "Fri","Sat","Sun"]
4 y = [20, 40, 35, 55, 42, 80, 50]
5 # "g" 表示红色,marksize用来设置'D'菱形的大小
6 plt.plot(x, y, "g", marker='D', markersize=5, label="周活")
7 #绘制坐标轴标签
8 plt.xlabel("登录时间")
9 plt.ylabel("用户活跃度")
10 plt.title("活跃度")
11 #显示图例
12 plt.legend(loc="lower right")
13 #调用 text()在图像上绘制注释文本
14 #x1、y1表示文本所处坐标位置,ha参数控制水平对齐方式, va控制垂直对齐方式,str(y1)表示要绘制的文本
15 for x1, y1 in zip(x, y):
16 plt.text(x1, y1, str(y1), ha='center', va='bottom', fontsize=10)
17 #保存图片
18 plt.savefig("1.jpg")
19 plt.show()

绘制多条折线图
当学习完如何绘制单条折线的绘制后,再绘制多条折线也变的容易,只要准备好绘制多条折线图的数据即可。
下面是一个简单示例,绘制了两天内同一时刻,天气温度随时间变化的折线图:
1 import matplotlib.pyplot as plt
2 #对比两天内同一时刻温度的变化情况
3 x = [5, 8, 12, 14, 16, 18, 20]
4 y1 = [18, 21, 29, 31, 26, 24, 20]
5 y2 = [15, 18, 24, 30, 31, 25, 24]
6 #绘制折线图,添加数据点,设置点的大小
7 # * 表示绘制五角星;此处也可以不设置线条颜色,matplotlib会自动为线条添加不同的颜色
8 plt.plot(x, y1, 'r',marker='*', markersize=10)
9 plt.plot(x, y2, 'b', marker='*',markersize=10)
10 plt.title('温度对比折线图') # 折线图标题
11 plt.xlabel('时间(h)') # x轴标题
12 plt.ylabel('温度(℃)') # y轴标题
13 #给图像添加注释,并设置样式
14 for a, b in zip(x, y1):
15 plt.text(a, b, b, ha='center', va='bottom', fontsize=10)
16 for a, b in zip(x, y2):
17 plt.text(a, b, b, ha='center', va='bottom', fontsize=10)
18 #绘制图例
19 plt.legend(['第一天', '第二天'])
20 #显示图像
21 plt.show()
显示结果如下:

22 散点图Axes.scatter()
散点图用于在水平轴和垂直轴上绘制数据点,它表示了因变量随自变量变化的趋势。通俗地讲,它反映的是一个变量受另一个变量的影响程度。
散点图将序列显示为一组点,其中每个散点值都由该点在图表中的坐标位置表示。对于不同类别的点,则由图表中不同形状或颜色的标记符表示。同时,您也可以设置标记符的颜色或大小。
Axes.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, *, edgecolors=None, plotnonfinite=False, data=None, **kwargs)[source]
主要参数:
- x, y: float or array-like, shape (n, );数据点位置;
- s: float or array-like, shape (n, ), optional;标记点marker大小值;
- c: array-like or list of colors or color, optional;标记点marker颜色;
- alpha: float, default: None; 透明度,0-1之间;
import numpy as np import matplotlib.pyplot as plt import matplotlib.cbook as cbook # Load a numpy record array from yahoo csv data with fields date, open, close, # volume, adj_close from the mpl-data/example directory. The record array # stores the date as an np.datetime64 with a day unit ('D') in the date column. price_data = (cbook.get_sample_data('goog.npz', np_load=True)['price_data'] .view(np.recarray)) price_data = price_data[-250:] # get the most recent 250 trading days delta1 = np.diff(price_data.adj_close) / price_data.adj_close[:-1] # Marker size in units of points^2 volume = (15 * price_data.volume[:-2] / price_data.volume[0])**2 close = 0.003 * price_data.close[:-2] / 0.003 * price_data.open[:-2] fig, ax = plt.subplots() ax.scatter(delta1[:-1], delta1[1:], c=close, s=volume, alpha=0.5) ax.set_xlabel(r'$\Delta_i$', fontsize=15) ax.set_ylabel(r'$\Delta_{i+1}$', fontsize=15) ax.set_title('Volume and percent change') ax.grid(True) fig.tight_layout() plt.show()
23 Matplotlib等高线图
等高线图(也称“水平图”)是一种在二维平面上显示 3D 图像的方法。等高线有时也被称为 “Z 切片”,如果您想要查看因变量 Z 与自变量 X、Y 之间的函数图像变化(即 Z=f(X,Y)),那么采用等高线图最为直观。
自变量 X 和 Y 需要被限制在矩形网格内,您可以将 x 、y 数组作为参数传递给 numpy.meshgrid() 函数来构建一个网格点矩阵。
关于 meshgrid() 函数用法可参考《numpy.meshgrid()用法详解》。
Matplotlib API 提供了绘制等高线(contour)与填充等高线( contourf)的函数。这两个函数都需要三个参数,分别是 X、Y 与 Z。
1 import numpy as np
2 import matplotlib.pyplot as plt
3 #创建xlist、ylist数组
4 xlist = np.linspace(-3.0, 3.0, 100)
5 ylist = np.linspace(-3.0, 3.0, 100)
6 #将上述数据变成网格数据形式
7 X, Y = np.meshgrid(xlist, ylist)
8 #定义Z与X,Y之间的关系
9 Z = np.sqrt(X**2 + Y**2)
10 fig,ax=plt.subplots(1,1)
11 #填充等高线颜色
12 cp = ax.contourf(X, Y, Z)
13 fig.colorbar(cp) # 给图像添加颜色柱
14 ax.set_title('Filled Contours Plot')
15 ax.set_xlabel('x (cm)')
16 ax.set_ylabel('y (cm)')
17 #画等高线
18 plt.contour(X,Y,Z)
19 plt.show()
代码执行后,输出结果如下:

左侧图像绘制了两个变量 X、Y ,右侧的颜色柱(colorbar)则表示 X 的取值,颜色越深表示值越小,中间深色部分的圆心点表示 x=0,y=0,z=0。
24 Matplotlib振动图
振动图也叫磁场图,或量场图,其图像的表现形式是一组矢量箭头,其数学含义是在点 (x,y) 处具有分向量 (u,v)。
Matplotlib 提供绘制量场图的函数,如下所示:
quiver(x,y,u,v)
上述函数表示,在指定的 (x,y) 坐标上以箭头的形式绘制向量,参数说明如下:
| 参数 | 说明 |
|---|---|
| x | 一维、二维数组或者序列,表示箭头位置的x坐标。 |
| y | 一维、二维数组或者序列,表示箭头位置的y坐标。 |
| u | 一维、二维数组或者序列,表示箭头向量的x分量。 |
| v | 一维、二维数组或者序列,表示箭头向量的y分量。 |
| c | 一维、二维数组或者序列,表示箭头颜色。 |
以下示例,绘制了一个简单的振动图:
1 import matplotlib.pyplot as plt
2 import numpy as np
3 x,y = np.meshgrid(np.arange(-2, 2, 0.2), np.arange(-2, 2, 0.25))
4 z = x*np.exp(-x**2 - y**2)
5 #计算数组中元素的梯度
6 v, u = np.gradient(z, 0.2, 0.2)
7 fig, ax = plt.subplots()
8 q = ax.quiver(x,y,u,v)
9 plt.show()
上述代码执行后,输出结果如下:

25 Matplotlib箱型图
箱型图(也称为盒须图)于 1977 年由美国著名统计学家约翰·图基(John Tukey)发明。它能显示出一组数据的最大值、最小值、中位数、及上下四分位数。
在箱型图中,我们从上四分位数到下四分位数绘制一个盒子,然后用一条垂直触须(形象地称为“盒须”)穿过盒子的中间。上垂线延伸至上边缘(最大值),下垂线延伸至下边缘(最小值)。箱型图结构如下所示:

箱型如结构图
首先准备创建箱型图所需数据:您可以使用numpy.random.normal()函数来创建一组基于正态分布的随机数据,该函数有三个参数,分别是正态分布的平均值、标准差以及期望值的数量。如下所示:
1 #利用随机数种子使每次生成的随机数相同
2 np.random.seed(10)
3 collectn_1 = np.random.normal(100, 10, 200)
4 collectn_2 = np.random.normal(80, 30, 200)
5 collectn_3 = np.random.normal(90, 20, 200)
6 collectn_4 = np.random.normal(70, 25, 200)
7 data_to_plot=[collectn_1,collectn_2,collectn_3,collectn_4]
然后用 data_to_plot 变量指定创建箱型图所需的数据序列,最后用 boxplot() 函数绘制箱型图,如下所示:
1 fig = plt.figure()
2 #创建绘图区域
3 ax = fig.add_axes([0,0,1,1])
4 #创建箱型图
5 bp = ax.boxplot(data_to_plot)
6 plt.show()
上述代码执行后,输出结果如下:

箱型图输出结果
26 Matplotlib提琴图
小提琴图(Violin Plot)是用来展示数据分布状态以及概率密度的图表。这种图表结合了箱形图和密度图的特征。小提琴图跟箱形图类似,不同之处在于小提琴图还显示数据在不同数值下的概率密度。
小提琴图使用核密度估计(KDE)来计算样本的分布情况,图中要素包括了中位数、四分位间距以及置信区间。在数据量非常大且不方便一一展示的时候,小提琴图特别适用。
概率密度估计、置信区间、四分位间距都属于统计学中的概念,可自行查阅,这里不做说明。
小提琴图比箱型图能提供了更多的信息。虽然箱型图显示了均值、中位数和上、下四分位数等统计信息,但是小提琴图却显示了数据的完整分布情况,这更利于数据的分析与比对。下面是小提琴图的使用示例:
1 import matplotlib.pyplot as plt
2 np.random.seed(10)
3 collectn_1 = np.random.normal(100, 10, 200)
4 collectn_2 = np.random.normal(80, 30, 200)
5 collectn_3 = np.random.normal(90, 20, 200)
6 collectn_4 = np.random.normal(70, 25, 200)
7 #创建绘制小提琴图的数据序列
8 data_to_plot = [collectn_1, collectn_2, collectn_3, collectn_4]
9 #创建一个画布
10 fig = plt.figure()
11 #创建一个绘图区域
12 ax = fig.add_axes([0,0,1,1])
13 # 创建一个小提琴图
14 bp = ax.violinplot(data_to_plot)
15 plt.show()
输出结果如下:

小提琴图绘制
27 Matplotlib 3D绘图
最初开发的 Matplotlib,仅支持绘制 2d 图形,后来随着版本的不断更新, Matplotlib 在二维绘图的基础上,构建了一部分较为实用的 3D 绘图程序包,比如 mpl_toolkits.mplot3d,通过调用该程序包一些接口可以绘制 3D散点图、3D曲面图、3D线框图等
mpl_toolkits 是 Matplotlib 的绘图工具包。
第一个三维绘图程序
下面编写第一个三维绘图程序。
首先创建一个三维绘图区域, plt.axes() 函数提供了一个参数projection,将其参数值设置为 "3d"。如下所示:
1 #导入三维工具包mplot3d
2 from mpl_toolkits import mplot3d
3 import numpy as np
4 import matplotlib.pyplot as plt
5 fig = plt.figure()
6 #创建3d绘图区域
7 ax = plt.axes(projection='3d')
有了三维绘图区域,接下来就要构建 3d 图像,如下所示:
1 #从三个维度构建
2 z = np.linspace(0, 1, 100)
3 x = z * np.sin(20 * z)
4 y = z * np.cos(20 * z)
最后调用 plot3D() 方法绘制 3d 图形,代码如下:
1 #调用 ax.plot3D创建三维线图
2 ax.plot3D(x, y, z, 'gray')
3 ax.set_title('3D line plot')
4 plt.show()
完整程序如下所示:
1 from mpl_toolkits import mplot3d
2 import numpy as np
3 import matplotlib.pyplot as plt
4 fig = plt.figure()
5 #创建3d绘图区域
6 ax = plt.axes(projection='3d')
7 #从三个维度构建
8 z = np.linspace(0, 1, 100)
9 x = z * np.sin(20 * z)
10 y = z * np.cos(20 * z)
11 #调用 ax.plot3D创建三维线图
12 ax.plot3D(x, y, z, 'gray')
13 ax.set_title('3D line plot')
14 plt.show()
输出结果如下所示:

三维线图(3D Line)
上述代码中的 ax.plot3D() 函数可以绘制各种三维图形,这些三维图都要根据(x,y,z)三元组类来创建。
3D散点图
通过 ax.scatter3D() 函数可以绘制 3D 散点图,示例代码如下:
1 from mpl_toolkits import mplot3d
2 import numpy as np
3 import matplotlib.pyplot as plt
4 fig = plt.figure()
5 #创建绘图区域
6 ax = plt.axes(projection='3d')
7 #构建xyz
8 z = np.linspace(0, 1, 100)
9 x = z * np.sin(20 * z)
10 y = z * np.cos(20 * z)
11 c = x + y
12 ax.scatter3D(x, y, z, c=c)
13 ax.set_title('3d Scatter plot')
14 plt.show()
输出结果图:

Matplotlib 3D绘图
3D等高线图
ax.contour3D() 可以用来创建三维等高线图,该函数要求输入数据均采用二维网格式的矩阵坐标。同时,它可以在每个网格点(x,y)处计算出一个 z 值。
以下示例展示了如何绘制三维正弦等高线图。代码如下:
1 from mpl_toolkits import mplot3d
2 import numpy as np
3 import matplotlib.pyplot as plt
4 def f(x, y):
5 return np.sin(np.sqrt(x ** 2 + y ** 2))
6 #构建x、y数据
7 x = np.linspace(-6, 6, 30)
8 y = np.linspace(-6, 6, 30)
9 #将数据网格化处理
10 X, Y = np.meshgrid(x, y)
11 Z = f(X, Y)
12 fig = plt.figure()
13 ax = plt.axes(projection='3d')
14 #50表示在z轴方向等高线的高度层级,binary颜色从白色变成黑色
15 ax.contour3D(X, Y, Z, 50, cmap='binary')
16 ax.set_xlabel('x')
17 ax.set_ylabel('y')
18 ax.set_zlabel('z')
19 ax.set_title('3D contour')
20 plt.show()
输出结果图如下:

3D线框图
线框图同样要采用二维网格形式的数据,与绘制等高线图类似。
线框图可以将数据投影到指定的三维表面上,并输出可视化程度较高的三维效果图。通过 plot_wireframe() 能够绘制 3D 线框图。代码如下:
1 from mpl_toolkits import mplot3d
2 import numpy as np
3 import matplotlib.pyplot as plt
4 #要绘制函数图像
5 def f(x, y):
6 return np.sin(np.sqrt(x ** 2 + y ** 2))
7 #准备x,y数据
8 x = np.linspace(-6, 6, 30)
9 y = np.linspace(-6, 6, 30)
10 #生成x、y网格化数据
11 X, Y = np.meshgrid(x, y)
12 #准备z值
13 Z = f(X, Y)
14 #绘制图像
15 fig = plt.figure()
16 ax = plt.axes(projection='3d')
17 #调用绘制线框图的函数plot_wireframe()
18 ax.plot_wireframe(X, Y, Z, color='black')
19 ax.set_title('wireframe')
20 plt.show()
输出结果如下:

Matplotlib绘制线框图
3D曲面图
曲面图表示一个指定的因变量y与两个自变量x和z之间的函数关系。
3D 曲面图是一个三维图形,它非常类似于线框图。不同之处在于,线框图的每个面都由多边形填充而成。Matplotlib 提供的 plot_surface() 函数可以绘制 3D 曲面图,该函数需要接受三个参数值 x,y 和 z 。示例代码如下:
1 from mpl_toolkits import mplot3d
2 import numpy as np
3 import matplotlib.pyplot as plt
4 #求向量积(outer()方法又称外积)
5 x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
6 #矩阵转置
7 y = x.copy().T
8 #数据z
9 z = np.cos(x ** 2 + y ** 2)
10 #绘制曲面图
11 fig = plt.figure()
12 ax = plt.axes(projection='3d')
13 调用plot_surface()函数
14 ax.plot_surface(x, y, z,cmap='viridis', edgecolor='none')
15 ax.set_title('Surface plot')
16 plt.show()
输出结果图:

Matplotlib绘制曲面图
28 绘制文本Axes.text()
Matplotlib 支持广泛的文本格式,比如 TTF 页面语言、Unicode 字符等。这是因为 Matplotlib 内置了 matplotlib.font_manager 字体管理器,它是一个实现了跨平台,并符合 W3C 字体查找算法的字体集合。
用户可以对文本属性进行控制,比如字体大小、粗细、位置和颜色等。
Axes.text(x, y, s, fontdict=None, **kwargs)
参数:
- x, y: float;放置文本的位置,
- s: str; 文本内容字符串
- fontdictdict, default: None;用于覆盖默认文本属性的字典。
返回:创建的Text实例。
与此同时,Matplotlib 也支持绘制 TeX 包含的数学符号。TeX 是一套功能强大、十分灵活的排版语言,它可以用来绘制文本、符号、数学表达式等。通过下表中的方法可以绘制出相应的内容:
| text | 在绘图区域的任意位置添加文本。 |
| annotate | 在绘图区域的任意位置添加带有可选箭头的注释。 |
| xlabel | 在绘图区域的 x 轴上添加标签。 |
| ylabel | 在绘图区域的 y 轴上添加标签。 |
| title | 为绘图区域添加标题。 |
| figtext | 在画布的任意位置添加文本。 |
| suptitle | 为画布中添加标题。 |
下面使用 text() 函数会创建一个文本对象。示例如下:
import matplotlib import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot() fig.subplots_adjust(top=0.85) # Set titles for the figure and the subplot respectively fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold') ax.set_title('axes title') ax.set_xlabel('xlabel') ax.set_ylabel('ylabel') # Set both x- and y-axis limits to [0, 10] instead of default [0, 1] ax.axis([0, 10, 0, 10]) ax.text(3, 8, 'boxed italics text in data coords', style='italic', bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10}) ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15) ax.text(3, 2, 'unicode: Institut für Festkörperphysik') ax.text(0.95, 0.01, 'colored text in axes coords', verticalalignment='bottom', horizontalalignment='right', transform=ax.transAxes, color='green', fontsize=15) ax.plot([2], [1], 'o') ax.annotate('annotate', xy=(2, 1), xytext=(3, 4), arrowprops=dict(facecolor='black', shrink=0.05)) plt.show()

29 数学表达式
Matplotlib 中的文本字符串都可以使用 Text Markup(一种文本标记语言)显现出来,具体的使用方法是将文本标记符放在一对美元符号$内,语法格式如下:
#数学表达式 plt.title(r'$\alpha > \beta$')
如果要绘制下标和上标,您需要使用'_'和'^'符号,下面是一个简单的示例:
1 import matplotlib.pyplot as plt 2 3 fig, ax = plt.subplots() 4 5 ax.plot([1, 2, 3], label=r'$\sqrt{x^2}$') 6 ax.legend() 7 8 ax.set_xlabel(r'$\Delta_i^j$', fontsize=20) 9 ax.set_ylabel(r'$\Delta_{i+1}^j$', fontsize=20) 10 ax.set_title(r'$\Delta_i^j \hspace{0.4} \mathrm{versus} \hspace{0.4} ' 11 r'\Delta_{i+1}^j$', fontsize=20) 12 13 tex = r'$\mathcal{R}\prod_{i=\alpha_{i+1}}^\infty a_i\sin(2 \pi f x_i)$' 14 ax.text(1, 1.6, tex, fontsize=20, va='bottom') 15 16 fig.tight_layout() 17 plt.show()

30 图像处理matplotlib.image
Matplotlib 软件包中的image模块提供了加载、缩放和显示图像的功能,模块结构如下:

matplotlib本身只能支持 PNG 格式的图片,如果格式不符,需要对图片的格式进行转换。但是一般可以借用Pillow库PIL处理图像。
from PIL import Image
matplotlib.image.imread(fname, format=None)
参数:
- fname: str or file-like;要读取的二进制文件名或对象;不推荐使用url,如果是url,推荐使用Pillow打开后再传入,如:np.array(PIL.Image.open(urllib.request.urlopen(url)))
- format:str, optional;读取图像文件的格式,如果设置为“png”,则当fname是带有png的文件名则以png加载,否则格式由
PIL.Image.open自动检测。
返回:
下面示例,imread() 函数用于读取图像数据并形成 ndarray 数组 ,其数据类型为 float32。
1 import matplotlib.pyplot as plt
2 import matplotlib.image as mpimg
3 import numpy as np
4 img = mpimg.imread('mtplogo.png')
假设在当前目录中存在名为 mtplogo.png 的图像。

通过执行 imsave() 函数,可以将包含图像数据的 ndarray 数组保存到磁盘文件中。
plt.imsave("logo.png", img, cmap = 'gray', origin = 'lower')
如下所示,将 imsave()方法的origin参数设置为 lower 实现了原始图像的垂直翻转。

通过 imshow() 函数可以在 Matplotlib 查看器上绘制出相应的图像。其函数格式如下:
imgplot = plt.imshow(img)
下面列举一组示例:
1 import matplotlib.pyplot as plt
2 import numpy as np
3 fig=plt.figure()
4 ax1=fig.add_subplot(221)
5 ax2=fig.add_subplot(222)
6 ax3=fig.add_subplot(223)
7 ax4=fig.add_subplot(224)
8 #准备数据
9 #绘制z = sqrt(x^2+y^2)图像
10 points=np.arange(-5,5,0.01)
11 # meshgrid 接受两个一维数组,然后产生两个二维矩阵
12 xs,ys=np.meshgrid(points,points)
13 #绘制图像
14 z=np.sqrt(xs**2+ys**2)
15 ax = fig.add_subplot(221)
16 #默认
17 ax.imshow(z)
18 ax = fig.add_subplot(222)
19 ax.imshow(z,cmap = "gray")
20 ax = fig.add_subplot(223)
21 ax.imshow(z,cmap="cool")
22 ax = fig.add_subplot(224)
23 ax.imshow(z,cmap="hot")
24 #显示图像
25 plt.show()
输出结果如下:

31 Matplotlib转换对象
Matplotlib 是一款轻量级的图形转换框架,它通过转换对象轻松地实现了数据坐标系、轴域坐标系、图形坐标系,以及显示坐标系四者之间的相互转换,由于这种转换是 Matplotlib 自动完成的,因此无需考虑其底层原理。
坐标系转换对象
下面对四种坐标系做简单说明,其中ax代表轴域对象的实例;fig代表图形对象的实例。
Matplotlib坐标系和转换对象
| 坐标系 | 转换对象 | 描述 |
|---|---|---|
| Data | ax.transData | 数据坐标系,由 xlim 和 ylim 控制。 |
| Axes | ax.transAxes | 轴域坐标系(即绘图区坐标系),(0,0) 在轴域坐标系左下角,(1,1)在轴域坐标系的右上角。 |
| Figure | fig.transFigure | 图形坐标系。(0,0) 在图的左下角,(1,1) 在图的右上角。 |
| Display | None | 显示坐标系。(0,0)显示左下角,而(width,height) 则显示右上角。注意,此处以像素 px 为单位。 |
转换对象作用就是在不同对象之间架起一座沟通的桥梁。输入一组数据最终以图像的形式显示,这个过程就是依靠转换对象来实现的。
上表中的 Data、Axes、Figure,这三个转换对象都可以接受一组数据,它们会将接受的数据转换到显示坐标系中,即 Display。在这个过程中,显示坐标系只是充当数据的接收者,因此显示坐标系不存在转换对象。
示例说明
下面举一个简单的示例,现有文本“my text”放置在数据点 (x,y) 位置处:
1 axes.text(x,y,"my text")
通过 Axes 转换对象,我们可以指定文本的位置。使用以下代码,将文本移动至在坐标系的中心位置:
axes.text(0.5, 0.5, "middle of graph", transform=axes.transAxes)


浙公网安备 33010602011771号