Matplotlib

Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。使用它可以很方便的绘制出版质量级别的图形。

概述

官网

效果展示

matplotlib基本功能

  1. 基本绘图 (在二维平面坐标系中绘制连续的线)
    1. 设置线型、线宽和颜色
    2. 设置坐标轴范围
    3. 设置坐标刻度
    4. 设置坐标轴
    5. 图例
    6. 特殊点
    7. 备注
  2. 图形对象(图形窗口)
    1. 子图
    2. 刻度定位器
    3. 刻度网格线
    4. 半对数坐标
    5. 散点图
    6. 填充
    7. 条形图(柱状图)
    8. 饼图
    9. 等高线图
    10. 热成像图
    11. 极坐标系
    12. 三维曲面
    13. 简单动画

基本绘图

案例:绘制一条正弦曲线

1
2
3
4
5
6
7
8
import numpy as np
import matplotlib.pyplot as mp

# xarray: <序列> 水平坐标序列
# yarray: <序列> 垂直坐标序列
mp.plot(xarray, yarray)
#显示图表
mp.show()

绘制水平线与垂直线:

1
2
3
4
5
6
7
8
9
import numpy as np
import matplotlib.pyplot as mp

# vertical 绘制垂直线
mp.vlines(vval, ymin, ymax, ...)
# horizotal 绘制水平线
mp.hlines(xval, xmin, xmax, ...)
#显示图表
mp.show()

线型、线宽和颜色

1
2
3
4
5
6
7
8
#linestyle: '-' 实线  '--' 虚线  ':' 点线
#linewidth: 线宽
# 数字
#color: <关键字参数> 颜色
# 英文颜色单词 或 常见颜色英文单词首字母 或 #495434 或 (1,1,1) 或 (1,1,1,1)
#alpha: <关键字参数> 透明度
# 浮点数值
mp.plot(xarray, yarray, linestyle='', linewidth=1, color='', alpha=0.5)

linestyle 见附录
linecolor 见附录

设置坐标轴范围

案例:把坐标轴范围设置为 -π ~ π

1
2
3
4
5
6
#x_limt_min:	<float> x轴范围最小值
#x_limit_max: <float> x轴范围最大值
mp.xlim(x_limt_min, x_limit_max)
#y_limt_min: <float> y轴范围最小值
#y_limit_max: <float> y轴范围最大值
mp.ylim(y_limt_min, y_limit_max)

应用场景
查看可视范围,例如只看第一象限;

设置坐标刻度

案例:把横坐标的刻度显示为:0, π/2, π, 3π/2, 2π

1
2
3
4
5
6
#x_val_list: 	x轴刻度值序列
#x_text_list: x轴刻度标签文本序列 [可选]
mp.xticks(x_val_list , x_text_list )
#y_val_list: y轴刻度值序列
#y_text_list: y轴刻度标签文本序列 [可选]
mp.yticks(y_val_list , y_text_list )

刻度文本的特殊语法LaTex排版语法字符串

1
r'$x^n+y^n=z^n$',   r'$\int\frac{1}{x} dx = \ln |x| + C$',     r'$-\frac{\pi}{2}$'

$$
x^n+y^n=z^n, \int\frac{1}{x} dx = \ln |x| + C, -\frac{\pi}{2}
$$
具体见附录

设置坐标轴

坐标轴名:left / right / bottom / top

1
2
3
4
5
6
7
8
9
10
11
# 获取当前坐标轴对象,{'left':左轴,'right':右轴,'bottom':下轴,'top':上轴 }
ax = mp.gca()
# 获取其中某个坐标轴
axis = ax.spines['坐标轴名']
# 设置坐标轴的位置。 该方法需要传入2个元素的元组作为参数
# type: <str> 移动坐标轴的参照类型 一般为'data' (以数据的值作为移动参照值)
# val: 参照值
axis.set_position((type, val))
# 设置坐标轴的颜色
# color: <str> 颜色值字符串
axis.set_color(color)

案例:设置坐标轴至中心。

1
2
3
4
5
6
7
# 设置坐标轴
ax = mp.gca()
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.spines['left'].set_position(('data', 0))
ax.spines['bottom'].set_position(('data', 0))
mp.yticks([-1, -0.5, 0.5, 1])

图例

图例就是标注哪条线是什么意思

显示两条曲线的图例,并测试loc属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 再绘制曲线时定义曲线的label
# label: <关键字参数 str> 支持LaTex排版语法字符串
mp.plot(xarray, yarray ... label='', ...)
# 设置图例的位置
# loc: <关键字参数> 制定图例的显示位置 (若不设置loc,则显示默认位置)
# =============== =============
# Location String Location Code
# =============== =============
# '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
# =============== =============
mp.legend(loc='')

特殊点

1
2
3
4
5
6
7
8
9
# xarray: <序列> 所有需要标注点的水平坐标组成的序列
# yarray: <序列> 所有需要标注点的垂直坐标组成的序列
mp.scatter(xarray, yarray,
marker='', #点型 ~ matplotlib.markers
s=60, #大小
edgecolor='', #边缘色
facecolor='', #填充色
zorder=3 #绘制图层编号 (编号越大,图层越靠上)
)

marker点型可参照:help(matplotlib.markers)

也可参照附录:point样式

备注

为在某条曲线上的点添加备注,指明函数方程与值。

1
2
3
4
5
6
7
8
9
10
# 在图表中为某个点添加备注。包含备注文本,备注箭头等图像的设置。
mp.annotate(
r'$\frac{\pi}{2}$', #备注中显示的文本内容
xycoords='data', #备注目标点所使用的坐标系(data表示数据坐标系)
xy=(x, y), #备注目标点的坐标
textcoords='offset points', #备注文本所使用的坐标系(offset points表示参照点的偏移坐标系)
xytext=(x, y), #备注文本的坐标
fontsize=14, #备注文本的字体大小
arrowprops=dict() #使用字典定义文本指向目标点的箭头样式
)

arrowprops参数使用字典定义指向目标点的箭头样式

1
2
3
4
5
#arrowprops字典参数的常用key
arrowprops=dict(
arrowstyle='', #定义箭头样式
connectionstyle='' #定义连接线的样式
)

箭头样式(arrowstyle)字符串如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
============   =============================================
Name Attrs
============ =============================================
'-' None
'->' head_length=0.4,head_width=0.2
'-[' widthB=1.0,lengthB=0.2,angleB=None
'|-|' widthA=1.0,widthB=1.0
'-|>' head_length=0.4,head_width=0.2
'<-' head_length=0.4,head_width=0.2
'<->' head_length=0.4,head_width=0.2
'<|-' head_length=0.4,head_width=0.2
'<|-|>' head_length=0.4,head_width=0.2
'fancy' head_length=0.4,head_width=0.4,tail_width=0.4
'simple' head_length=0.5,head_width=0.5,tail_width=0.2
'wedge' tail_width=0.3,shrink_factor=0.5
============ =============================================

连接线样式(connectionstyle)字符串如下

Name Attrs
‘angle’ angleA=90,angleB=0,rad=0.0
‘angle3’ angleA=90,angleB=0`
‘arc’ angleA=0,angleB=0,armA=None,armB=None,rad=0.0
‘arc3’ rad=0.0
‘bar’ armA=0.0,armB=0.0,fraction=0.3,angle=None

图形对象(图形窗口)

绘制两个窗口,一起显示。

1
2
3
4
5
6
7
8
9
# 手动构建 matplotlib 窗口
mp.figure(
'A', #窗口标题栏文本
facecolor='' #图表背景色
)
mp.figure('B')
mp.figure('A') # 把A创建置为当前窗口
mp.plot(....) # 将会作用在A窗口中
mp.show()

mp.figure方法不仅可以构建一个新窗口,如果已经构建过title=’xxx’的窗口,又使用figure方法构建了title=’xxx’ 的窗口的话,mp将不会创建新的窗口,而是把title=’xxx’的窗口置为当前操作窗口。

设置当前窗口的参数

案例:测试窗口相关参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 设置图表标题 显示在图表上方
mp.title(title, fontsize=12)
# 设置水平轴的文本
mp.xlabel(x_label_str, fontsize=12)
# 设置垂直轴的文本
mp.ylabel(y_label_str, fontsize=12)
# 设置刻度参数 labelsize设置刻度字体大小
mp.tick_params(labelsize=8)
# 设置图表网格线 linestyle设置网格线的样式
# - or solid 粗线
# -- or dashed 虚线
# -. or dashdot 点虚线
# : or dotted 点线
mp.grid(linestyle='')
# 设置紧凑布局,把图表相关参数都显示在窗口中
mp.tight_layout()

子图

矩阵式布局

绘制矩阵式子图布局相关API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mp.figure('Subplot Layout', facecolor='lightgray')
# 拆分矩阵
# rows: 行数
# cols: 列数
# num: 编号
mp.subplot(rows, cols, num)
# 1 2 3
# 4 5 6
# 7 8 9
mp.subplot(3, 3, 5) #操作3*3的矩阵中编号为5的子图
mp.plot()
mp.subplot(3, 3, 1) #操作3*3的矩阵中编号为1的子图
mp.plot()
mp.subplot(335) #简写

案例:绘制9宫格矩阵式子图,每个子图中写一个数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mp.figure('Subplot Layout', facecolor='lightgray')

for i in range(9):
mp.subplot(3, 3, i+1)
mp.text(
0.5, 0.5, i+1,
ha='center',
va='center',
size=36,
alpha=0.5
)
mp.xticks([])
mp.yticks([])

mp.tight_layout()
mp.show()

网格式布局

网格式布局支持单元格的合并。

绘制网格式子图布局相关API:

1
2
3
4
5
6
7
8
9
10
11
import matplotlib.gridspec as mg
mp.figure('Grid Layout', facecolor='lightgray')
# 调用GridSpec方法拆分网格式布局
# rows: 行数
# cols: 列数
# gs = mg.GridSpec(rows, cols) 拆分成3行3列
gs = mg.GridSpec(3, 3)
# 合并0行与0、1列为一个子图表
mp.subplot(gs[0, :2])
mp.text(0.5, 0.5, '1', ha='center', va='center', size=36)
mp.show()

案例:绘制一个自定义网格布局。

1
2
3
4
5
6
7
8
9
import matplotlib.gridspec as mg
mp.figure('GridLayout', facecolor='lightgray')
gridsubs = mp.GridSpec(3, 3)
# 合并0行、0/1列为一个子图
mp.subplot(gridsubs[0, :2])
mp.text(0.5, 0.5, 1, ha='center', va='center', size=36)
mp.tight_layout()
mp.xticks([])
mp.yticks([])

自由式布局

自由式布局相关API:

1
2
3
4
5
6
7
8
9
10
mp.figure('Flow Layout', facecolor='lightgray')
# 设置图标的位置,给出左下角点坐标与宽高即可
# left_bottom_x: 坐下角点x坐标
# left_bottom_x: 坐下角点y坐标
# width: 宽度
# height: 高度
# mp.axes([left_bottom_x, left_bottom_y, width, height])
mp.axes([0.03, 0.03, 0.94, 0.94])
mp.text(0.5, 0.5, '1', ha='center', va='center', size=36)
mp.show()

案例:测试自由式布局,定位子图。

1
2
3
4
5
mp.figure('FlowLayout', facecolor='lightgray')

mp.axes([0.1, 0.2, 0.5, 0.3])
mp.text(0.5, 0.5, '1', ha='center', va='center', size=36)
mp.show()

刻度定位器

刻度定位器相关API:

1
2
3
4
5
6
# 获取当前坐标轴
ax = mp.gca()
# 设置水平坐标轴的主刻度定位器
ax.xaxis.set_major_locator(mp.NullLocator())
# 设置水平坐标轴的次刻度定位器为多点定位器,间隔0.1
ax.xaxis.set_minor_locator(mp.MultipleLocator(0.1))

案例:绘制一个数轴。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mp.figure('Locators', facecolor='lightgray')
# 获取当前坐标轴
ax = mp.gca()
# 隐藏除底轴以外的所有坐标轴
ax.spines['left'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
# 将底坐标轴调整到子图中心位置
ax.spines['bottom'].set_position(('data', 0))
# 设置水平坐标轴的主刻度定位器
ax.xaxis.set_major_locator(mp.NullLocator())
# 设置水平坐标轴的次刻度定位器为多点定位器,间隔0.1
ax.xaxis.set_minor_locator(mp.MultipleLocator(0.1))
# 标记所用刻度定位器类名
mp.text(5, 0.3, 'NullLocator()', ha='center', size=12)

案例:使用for循环测试刻度器样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
locators = ['mp.NullLocator()', 'mp.MaxNLocator(nbins=4)']

for i, locator in enumerate(locators):
mp.subplot(len(locators), 1, i+1)
mp.xlim(0, 10)
mp.ylim(-1, 1)
mp.yticks([])
# 获取当前坐标轴
ax = mp.gca()
# 隐藏除底轴以外的所有坐标轴
ax.spines['left'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
# 将底坐标轴调整到子图中心位置
ax.spines['bottom'].set_position(('data', 0))
# 设置水平坐标轴的主刻度定位器
ax.xaxis.set_major_locator(eval( ))
# 设置水平坐标轴的次刻度定位器为多点定位器,间隔0.1
ax.xaxis.set_minor_locator(mp.MultipleLocator(0.1))
mp.plot(np.arange(11), np.zeros(11), c='none')
# 标记所用刻度定位器类名
mp.text(5, 0.3, locator, ha='center', size=12)

常用刻度器如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 空定位器:不绘制刻度
mp.NullLocator()
# 最大值定位器:
# 最多绘制nbins+1个刻度
mp.MaxNLocator(nbins=3)
# 定点定位器:根据locs参数中的位置绘制刻度
mp.FixedLocator(locs=[0, 2.5, 5, 7.5, 10])
# 自动定位器:由系统自动选择刻度的绘制位置
mp.AutoLocator()
# 索引定位器:由offset确定起始刻度,由base确定相邻刻度的间隔
mp.IndexLocator(offset=0.5, base=1.5)
# 多点定位器:从0开始,按照参数指定的间隔(缺省1)绘制刻度
mp.MultipleLocator()
# 线性定位器:等分numticks-1份,绘制numticks个刻度
mp.LinearLocator(numticks=21)
# 对数定位器:以base为底,绘制刻度
mp.LogLocator(base=2)

刻度网格线

绘制刻度网格线的相关API:

1
2
3
4
5
6
7
8
9
10
ax = mp.gca()
#绘制刻度网格线
ax.grid(
which='', # 'major'/'minor' <-> '主刻度'/'次刻度'
axis='', # 'x'/'y'/'both' <-> 绘制x或y轴
linewidth=1, # 线宽
linestyle='', # 线型
color='', # 颜色
alpha=0.5 # 透明度
)

案例:绘制曲线 [1, 10, 100, 1000, 100, 10, 1],然后设置刻度网格线,测试刻度网格线的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
y = np.array([1, 10, 100, 1000, 100, 10, 1])
mp.figure('Normal & Log', facecolor='lightgray')
mp.subplot(211)
mp.title('Normal', fontsize=20)
mp.ylabel('y', fontsize=14)
ax = mp.gca()
ax.xaxis.set_major_locator(mp.MultipleLocator(1.0))
ax.xaxis.set_minor_locator(mp.MultipleLocator(0.1))
ax.yaxis.set_major_locator(mp.MultipleLocator(250))
ax.yaxis.set_minor_locator(mp.MultipleLocator(50))
mp.tick_params(labelsize=10)
ax.grid(which='major', axis='both', linewidth=0.75,
linestyle='-', color='orange')
ax.grid(which='minor', axis='both', linewidth=0.25,
linestyle='-', color='orange')
mp.plot(y, 'o-', c='dodgerblue', label='plot')
mp.legend()

半对数坐标

y轴将以指数方式递增。 基于半对数坐标绘制第二个子图,表示曲线:[1, 10, 100, 1000, 100, 10, 1]。

1
2
3
4
mp.figure('Grid', facecolor='lightgray')
y = [1, 10, 100, 1000, 100, 10, 1]
mp.semilogy(y)
mp.show()

散点图

可以通过每个点的坐标、颜色、大小和形状表示不同的特征值。

身高 体重 性别 年龄段 种族
180 80 中年 亚洲
160 50 青少 美洲

绘制散点图的相关API:

1
2
3
4
5
6
7
8
9
10
mp.scatter(
x, # x轴坐标数组
y, # y轴坐标数组
marker='', # 点型
s=10, # 大小
color='', # 颜色
edgecolor='', # 边缘颜色
facecolor='', # 填充色
zorder='' # 图层序号
)

numpy.random提供了normal函数用于产生符合 正态分布 的随机数

1
2
3
4
5
6
n = 100
# 172: 期望值
# 10: 标准差
# n: 数字生成数量
x = np.random.normal(172, 20, n)
y = np.random.normal(60, 10, n)

案例:绘制平面散点图。

1
2
3
4
mp.figure('scatter', facecolor='lightgray')
mp.title('scatter')
mp.scatter(x, y)
mp.show()

设置点的颜色

1
2
3
4
mp.scatter(x, y, c='red')	
#直接设置颜色
d = (x-172)**2 + (y-60)**2
mp.scatter(x, y, c=d, cmap='jet') #以c作为参数,取cmap颜色映射表中的颜色值

cmap颜色映射表参附录cmap颜色映射表

填充

以某种颜色自动填充两条曲线的闭合区域。

1
2
3
4
5
6
7
8
mp.fill_between(
x, # x轴的水平坐标
sin_x, # 下边界曲线上点的垂直坐标
cos_x, # 上边界曲线上点的垂直坐标
sin_x<cos_x, # 填充条件,为True时填充
color='', # 填充颜色
alpha=0.2 # 透明度
)

案例:绘制两条曲线: sin_x = sin(x) cos_x = cos(x / 2) / 2 [0-8π]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
n = 1000
x = np.linspace(0, 8 * np.pi, n)
sin_y = np.sin(x)
cos_y = np.cos(x / 2) / 2
mp.figure('Fill', facecolor='lightgray')
mp.title('Fill', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(x, sin_y, c='dodgerblue',
label=r'$y=sin(x)$')
mp.plot(x, cos_y, c='orangered',
label=r'$y=\frac{1}{2}cos(\frac{x}{2})$')
mp.fill_between(x, cos_y, sin_y, cos_y < sin_y,
color='dodgerblue', alpha=0.5)
mp.fill_between(x, cos_y, sin_y, cos_y > sin_y,
color='orangered', alpha=0.5)
mp.legend()
mp.show()

条形图(柱状图)

绘制柱状图的相关API:

1
2
3
4
5
6
7
8
9
mp.figure('Bar', facecolor='lightgray')
mp.bar(
x, # 水平坐标数组
y, # 柱状图高度数组
width, # 柱子的宽度
color='', # 填充颜色
label='', #
alpha=0.2 #
)

案例:先以柱状图绘制苹果12个月的销量,然后再绘制橘子的销量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apples = np.array([30, 25, 22, 36, 21, 29, 20, 24, 33, 19, 27, 15])
oranges = np.array([24, 33, 19, 27, 35, 20, 15, 27, 20, 32, 20, 22])
mp.figure('Bar' , facecolor='lightgray')
mp.title('Bar', font size=20)
mp.xlabel('Month', fontsize=14)
mp.ylabel('Price', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=':')
mp.ylim((0, 40))
x = np.arange(len(apples))
mp.bar(x-0.2, apples, 0.4, color='dodgerblue',label='Apple')
mp.bar(x + 0.2, oranges, 0.4, color='orangered',label='Orange', alpha=0.75)
mp.xticks(x, [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])
mp.legend()
mp.show()

饼图

绘制饼状图的基本API:

1
2
3
4
5
6
7
8
9
10
mp.pie(
values, # 值列表
spaces, # 扇形之间的间距列表
labels, # 标签列表
colors, # 颜色列表
'%d%%', # 标签所占比例格式
shadow=True, # 是否显示阴影
startangle=90 # 逆时针绘制饼状图时的起始角度
radius=1 # 半径
)

案例:绘制饼状图显示5门语言的流行程度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mp.figure('pie', facecolor='lightgray')
#整理数据
values = [26, 17, 21, 29, 11]
spaces = [0.05, 0.01, 0.01, 0.01, 0.01]
labels = ['Python', 'JavaScript',
'C++', 'Java', 'PHP']
colors = ['dodgerblue', 'orangered',
'limegreen', 'violet', 'gold']
mp.figure('Pie', facecolor='lightgray')
mp.title('Pie', fontsize=20)
# 等轴比例
mp.axis('equal')
mp.pie(
values, # 值列表
spaces, # 扇形之间的间距列表
labels, # 标签列表
colors, # 颜色列表
'%d%%', # 标签所占比例格式
shadow=True, # 是否显示阴影
startanle=90 # 逆时针绘制饼状图时的起始角度
radius=1 # 半径
)

等高线图

组成等高线需要网格点坐标矩阵,也需要每个点的高度。所以等高线属于3D数学模型范畴。

绘制等高线的相关API:

1
2
3
4
5
6
7
8
9
mp.contourf(x, y, z, 8, cmap='jet')
cntr = mp.contour(
x, # 网格坐标矩阵的x坐标 (2维数组)
y, # 网格坐标矩阵的y坐标 (2维数组)
z, # 网格坐标矩阵的z坐标 (2维数组)
8, # 把等高线绘制成8部分
colors='black', # 等高线的颜色
linewidths=0.5 # 线宽
)

案例:生成网格坐标矩阵,并且绘制等高线:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
n = 1000
# 生成网格化坐标矩阵
x, y = np.meshgrid(np.linspace(-3, 3, n),
np.linspace(-3, 3, n))
# 根据每个网格点坐标,通过某个公式计算z高度坐标
z = (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2)
mp.figure('Contour', facecolor='lightgray')
mp.title('Contour', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
# 绘制等高线图
mp.contourf(x, y, z, 8, cmap='jet')
cntr = mp.contour(x, y, z, 8, colors='black',
linewidths=0.5)
# 为等高线图添加高度标签
mp.clabel(cntr, inline_spacing=1, fmt='%.1f',
fontsize=10)
mp.show()

热成像图

用图形的方式显示矩阵及矩阵中值的大小
1 2 3
4 5 6
7 8 9

绘制热成像图的相关API:

1
2
3
4
5
# 把矩阵z图形化,使用cmap表示矩阵中每个元素值的大小
# origin: 坐标轴方向
# upper: 缺省值,原点在左上角
# lower: 原点在左下角
mp.imshow(z, cmap='jet', origin='low')

使用颜色条显示热度值:

1
mp.colorbar()

极坐标系

与笛卡尔坐标系不同,某些情况下极坐标系适合显示与角度有关的图像。例如雷达等。极坐标系可以描述极径ρ与极角θ的线性关系。

1
2
3
4
5
6
7
8
mp.figure("Polar", facecolor='lightgray')
mp.gca(projection='polar')
mp.title('Porlar', fontsize=20)
mp.xlabel(r'$\theta$', fontsize=14)
mp.ylabel(r'$\rho$', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.show()

在极坐标系中绘制曲线:

1
2
3
4
5
#准备数据
t = np.linspace(0, 4*np.pi, 1000)
r = 0.8 * t
mp.plot(t, r)
mp.show()

案例,在极坐标系中绘制正弦函数。 y=3 sin(6x)

1
2
3
x = np.linspace(0, 6*np.pi, 1000)
y = 3*np.sin(6*x)
mp.plot(x, y)

3D图像绘制

matplotlib支持绘制三维曲面。若希望绘制三维曲面,需要使用axes3d提供的3d坐标系。

1
2
from mpl_toolkits.mplot3d import axes3d
ax3d = mp.gca(projection='3d') # class axes3d

matplotlib支持绘制三维点阵、三维曲面、三维线框图:

1
2
3
ax3d.scatter(..)		# 绘制三维点阵
ax3d.plot_surface(..) # 绘制三维曲面
ax3d.plot_wireframe(..) # 绘制三维线框图

3d散点图的绘制相关API:

1
2
3
4
5
6
7
8
9
10
11
12
ax3d.scatter(
x, # x轴坐标数组
y, # y轴坐标数组
marker='', # 点型
s=10, # 大小
zorder='', # 图层序号
color='', # 颜色
edgecolor='', # 边缘颜色
facecolor='', # 填充色
c=v, # 颜色值 根据cmap映射应用相应颜色
cmap='' #
)

案例:随机生成3组坐标,程标准正态分布规则,并且绘制它们。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
n = 1000
x = np.random.normal(0, 1, n)
y = np.random.normal(0, 1, n)
z = np.random.normal(0, 1, n)
d = np.sqrt(x ** 2 + y ** 2 + z ** 2)
mp.figure('3D Scatter')
ax = mp.gca(projection='3d') # 创建三维坐标系
mp.title('3D Scatter', fontsize=20)
ax.set_xlabel('x', fontsize=14)
ax.set_ylabel('y', fontsize=14)
ax.set_zlabel('z', fontsize=14)
mp.tick_params(labelsize=10)
ax.scatter(x, y, z, s=60, c=d, cmap='jet_r', alpha=0.5)
mp.show()

3d平面图的绘制相关API:

1
2
3
4
5
6
7
8
ax3d.plot_surface(
x, # 网格坐标矩阵的x坐标 (2维数组)
y, # 网格坐标矩阵的y坐标 (2维数组)
z, # 网格坐标矩阵的z坐标 (2维数组)
rstride=30, # 行跨距
cstride=30, # 列跨距
cmap='jet' # 颜色映射
)

案例:绘制3d平面图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
n = 1000
# 生成网格化坐标矩阵
x, y = np.meshgrid(np.linspace(-3, 3, n),
np.linspace(-3, 3, n))
# 根据每个网格点坐标,通过某个公式计算z高度坐标
z = (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2)
mp.figure('3D', facecolor='lightgray')

ax3d = mp.gca(projection='3d')
mp.title('3D', fontsize=20)
ax3d.set_xlabel('x', fontsize=14)
ax3d.set_ylabel('y', fontsize=14)
ax3d.set_zlabel('z', fontsize=14)
mp.tick_params(labelsize=10)
# 绘制3D平面图
# rstride: 行跨距
# cstride: 列跨距
ax3d.plot_surface(x,y,z,rstride=30,cstride=30, cmap='jet')

案例:3d线框图的绘制

1
2
3
4
5
# 绘制3D平面图 
# rstride: 行跨距
# cstride: 列跨距
ax3d.plot_wireframe(x,y,z,rstride=30,cstride=30,
linewidth=1, color='dodgerblue')

简单动画

动画即是在一段时间内快速连续的重新绘制图像的过程。

matplotlib提供了方法用于处理简单动画的绘制。定义update函数用于即时更新图像。

1
2
3
4
5
6
7
8
9
10
import matplotlib.animation as ma
#定义更新函数行为
def update(number):
pass
# 每隔10毫秒执行一次update更新函数,作用于mp.gcf()当前窗口对象
# mp.gcf(): 获取当前窗口
# update: 更新函数
# interval: 间隔时间(单位:毫秒)
anim = ma.FuncAnimation(mp.gcf(), update, interval=10)
mp.show()

案例:随机生成各种颜色的100个气泡。让他们不断的增大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#自定义一种可以存放在ndarray里的类型,用于保存一个球
ball_type = np.dtype([
('position', float, 2), # 位置(水平和垂直坐标)
('size', float, 1), # 大小
('growth', float, 1), # 生长速度
('color', float, 4)]) # 颜色(红、绿、蓝和透明度)

#随机生成100个点对象
n = 100
balls = np.zeros(100, dtype=ball_type)
balls['position']=np.random.uniform(0, 1, (n, 2))
balls['size']=np.random.uniform(40, 70, n)
balls['growth']=np.random.uniform(10, 20, n)
balls['color']=np.random.uniform(0, 1, (n, 4))

mp.figure("Animation", facecolor='lightgray')
mp.title("Animation", fontsize=14)
mp.xticks
mp.yticks(())

sc = mp.scatter(
balls['position'][:, 0],
balls['position'][:, 1],
balls['size'],
color=balls['color'], alpha=0.5)

#定义更新函数行为
def update(number):
balls['size'] += balls['growth']
#每次让一个气泡破裂,随机生成一个新的
boom_ind = number % n
balls[boom_ind]['size']=np.random.uniform(40, 70, 1)
balls[boom_ind]['position']=np.random.uniform(0, 1, (1, 2))
# 重新设置属性
sc.set_sizes(balls['size'])
sc.set_offsets(balls['position'])

# 每隔30毫秒执行一次update更新函数,作用于mp.gcf()当前窗口对象
# mp.gcf(): 获取当前窗口
# update: 更新函数
# interval: 间隔时间(单位:毫秒)
anim = ma.FuncAnimation(mp.gcf(), update, interval=30)
mp.show()

使用生成器函数提供数据,实现动画绘制

在很多情况下,绘制动画的参数是动态获取的,matplotlib支持定义generator生成器函数,用于生成数据,把生成的数据交给update函数更新图像:

1
2
3
4
5
6
7
8
9
10
11
12
13
import matplotlib.animation as ma
#定义更新函数行为
def update(data):
t, v = data
...
pass

def generator():
yield t, v

# 每隔10毫秒将会先调用生成器,获取生成器返回的数据,
# 把生成器返回的数据交给并且调用update函数,执行更新图像函数
anim = ma.FuncAnimation(mp.gcf(), update, generator,interval=10)

案例:绘制信号曲线:y=sin(2 * π * t) * exp(sin(0.2 * π * t)),数据通过生成器函数生成,在update函数中绘制曲线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mp.figure("Signal", facecolor='lightgray')
mp.title("Signal", fontsize=14)
mp.xlim(0, 10)
mp.ylim(-3, 3)
mp.grid(linestyle='--', color='lightgray', alpha=0.5)
pl = mp.plot([], [], color='dodgerblue', label='Signal')[0]
pl.set_data([],[])

x = 0

def update(data):
t, v = data
x, y = pl.get_data()
x.append(t)
y.append(v)
#重新设置数据源
pl.set_data(x, y)
#移动坐标轴
if(x[-1]>10):
mp.xlim(x[-1]-10, x[-1])

def y_generator():
global x
y = np.sin(2 * np.pi * x) * np.exp(np.sin(0.2 * np.pi * x))
yield (x, y)
x += 0.05

anim = ma.FuncAnimation(mp.gcf(), update, y_generator, interval=20)
mp.tight_layout()
mp.show()

其他Python的绘图库

pyecharts

附录

linestyle

字符 描述
‘-‘ 实线样式
‘–’ 短横线样式
‘-.’ 点划线样式
‘:’ 虚线样式
‘.’ 点标记
‘,’ 像素标记
‘o’ 圆标记
‘v’ 倒三角标记
‘^’ 正三角标记
‘<’ 左三角标记
‘>’ 右三角标记
‘1’ 下箭头标记
‘2’ 上箭头标记
‘3’ 左箭头标记
‘4’ 右箭头标记
‘s’ 正方形标记
‘p’ 五边形标记
‘*’ 星形标记
‘h’ 六边形标记 1
‘H’ 六边形标记 2
‘+’ 加号标记
‘x’ X 标记
‘D’ 菱形标记
‘d’ 窄菱形标记
‘|’ 竖直线标记
‘_’ 水平线标记

上面是网上找的,但是实际测试中只有’-‘, ‘–’, ‘-.’, ‘:’, ‘None’, ‘ ‘, ‘’, ‘solid’, ‘dashed’, ‘dashdot’, ‘dotted’可以用

linecolor

laTex排版语法

laTeX语法表示数学符号示例

LaTeX语法集合

cmap颜色映射表

point样式