Python Matplotlib 库基础

Matplotlib 是 Python 语言的一个图像绘制库。支持各种可视化类。
Reference:【MOOC】Python 数据分析与展示 - 北京理工大学 -【第二周】数据分析之展示 ; 公开课 ;Document;GitHub

Matplotlib 库的 pyplot 子库

一般通过 import matplotlib.pyplot as plt 来引用 Matplotlib 库的 pyplot 子库。
plt 通常为该模块的别名。

线形图

matplotlib.pyplot.plot
plt.plot() 为常用的画直线、折线或者曲线图像的函数。
最简单的使用 plt.plot(list_x or numpy.array_x):当 plt.plot 函数只有一个输入列表或者数组时,参数的元素的索引为 X 轴值,参数的元素的值为 Y 轴值。
当有两个输入列表或者数组时 plt.plot(list_x or numpy.array_x, list_y or numpy.array_y),第一个参数的元素的值为 X 轴值,第二个参数的元素的值为 Y 值。
当绘制多条曲线时,各条图像的 X 轴不能省略。
当有 2n 个输入列表或者数组时(n 为大于 1 的整数),将会绘制 n 条图像,第 i 个参数的元素的值为 X 轴值,第 i+1 个参数的元素的值为 Y 值(i 为 1 到 n 之间的整数)。
一般化的函数格式:
plt.plot(x, y, format_string, **kwargs:x 是 X 轴数据,列表或者数组,可选;y 是 Y 轴数据,列表或者数组;format_string 是控制曲线的格式,可选,**kwargs 是第二组或者更多 (x, y, format_string)。
format_string 是控制曲线的格式,由颜色字符、风格字符、标记字符组成。
- 颜色字符:

蓝色 绿色 红色 青绿色 洋红色 黄色 黑色 白色 RGB 某颜色 灰度值
'b' 'g' 'r' 'c' 'm' 'y' 'k' 'w' '#666666' '0.5'
  • 风格字符:
实线 破折线 点划线 虚线 无线条
'-' '--' '-.' ':' '' 或者 ' '
  • 标记字符:
点标记 像素标记(极小的点) 实心圆标记 上三角标记 下三角标记 右三角标记 左三角标记
'.' ',' 'o' 'v' '^' '>' '<'
下花三角标记 上花三角标记 左花三角标记 右花三角标记 实心方形标记 实心五角标记 星形标记
'1' '2' '3' '4' 's' 'p' '*'
竖六边形标记 横六边形标记 十字标记 叉标记 菱形标记 瘦菱形标记 垂直线标记
'h' 'H' '+' 'x' 'D' 'd' |

举例:

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

a = np.arange(5)
plt.plot(a, a, 'go-', a, a*1.5, 'r1', a, a*2, 'h', a, a*2.5, 'b:d')
plt.savefig('example', dpi=500)
plt.show()


因为三种格式所用字符均不相同,所以三者可以任意顺序排列,并且可选。
此外也可以通过属性赋值来设定格式:

属性 说明
color 线条颜色
linestyle 线条风格
marker 标记风格
markerfacecolor 标记颜色
markersize 标记尺寸
markevery 标记间隔

markevery 默认为 None, 此时所有点将会被标记。
markevery=N, N 为整数,此时每隔 N-1 个点将会被标记。
markevery=(start, N),start 和 N 均为整数,此时从第 start 个点开始,每隔 N-1 个点将会被标记。
markevery=slice(start, end, N),start、end 和 N 均为整数,此时从第 start 个点开始直到第 end-1 个点,每隔 N-1 个点将会被标记。
markevery=[x1, x2, ..., xi],只有第 x1, x2, ..., xi 个点被标记。这里列表为任意长度(最大长度为数据的总个数)。
markevery=n,n 为浮点数,此时标记的 x 轴坐标将会均匀间隔分布,标记个数为 1/n 取整。
markevery=(start, N),start 和 N 均为浮点数,此时标记的 x 轴坐标将会均匀间隔分布,标记个数为 (1-start)/n 取整,而且从第 l*start 个点开始,其中 l 为数据总个数。
plt.show() 显示所绘图像;plt.savefig(filename, dpi) 保存所绘图像为文件,默认 PNG 格式,dpi 表示输出质量。
plt.figure(num=None, figsize=None, dpi=None, facecolor=None, clear=False) 定义图像参数,其中 num 表示图像个数;figsize 表示图像尺寸,为一个二维元组;dpi 表示输出质量;facecolor 表示背景颜色;clear=True 表示清空之前的绘制。

pyplot 的子绘图区域

plt.subplot

matplotlib.pyplot.subplot
plt.subplot(nrows, ncols, plot_number) 在全局绘图区域中创建一个分区体系,并定位到一个子绘图区域。
举例:

注:参数之间的逗号可以省略。
调用 plt.subplot 函数后使用 plt.plot 函数绘图至对应区域。

plt.subplot2grid

plt.subplot2grid(GridSpec, CurSpec, colspan=1, rowspan=1) 设定网络,选中网络起始索引,从编号 0 开始,确定选中的行列区域跨越的数量。
举例:

注:为了使上面的 subplot2grid 函数的调用显示更加简洁,可以引入 GridSpec 类来实现该功能

1
2
3
4
5
6
7
8
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(3,3)

ax1 = plt.subplot(gs[0,:])
ax2 = plt.subplot(gs[1,:-1])
ax3 = plt.subplot(gs[0,-1])
ax4 = plt.subplot(gs[2,0])
ax5 = plt.subplot(gs[2,1])

pyplot 的文字显示

字体属性

中文字体分类:
黑体 楷体 隶书 仿宋 幼圆 宋体
'SimHei' 'Kaiti' 'LiSu' 'FangSong' 'YouYuan' 'STSong'
字体风格:
正常 斜体
'normal' 或者 'roman' 'italic' 或者 'oblique'
字体大小:
字号 极小 很小 比父元素更小 很大 极大 比父元素更大
整数 xx-small x-small small smaller medium large x-large xx-large larger
  1. 修改全局的字体属性:
    1
    2
    3
    4
    import matplotlib
    matplotlib.rcParams['font.family']='' #字体
    matplotlib.rcParams['font.style']='' #风格
    matplotlib.rcParams['font.size']='' #字号
  2. 修改局部的字体属性:
    在有文字显示的函数中增加属性 fontname 改变字体,fontstyle 改变风格,fontsize 改变字号

文本显示

函数 说明
plt.xlabel(string) 对 X 轴增加文本标签
plt.ylabel(string) 对 Y 轴增加文本标签
plt.title(string) 对图形整体增加文本标签
plt.text(x, y, string) 在任意位置增加文本标签
plt.annotate(s, xy=arrow_crd, xytext=text_crd, arrowprops=dict) 在图形中增加带箭头的注解

注:文本字符串中可以用一对 $ 符号来引入 LaTeX 公式。
annotate 函数的参数:plt.annotate(s, xy=arrow_crd, xytext=text_crd, arrowprops=dict)
s 为文本字符串;xy 为箭头指向的位置,即要注释的位置;xytext 为箭尾的位置,即文本位置;两个位置属性的值均为二维元组;arrowprops 为箭头的属性,如:facecolor 箭头颜色,shrink 箭头缩放成程度,width 箭头线段宽度,headwidth 箭头宽度,frac 箭头头部所占据的比例等;这些属性以字典形式传入。

坐标轴显示

函数 说明
plt.xticks(x, list) 对 X 轴增加坐标标记
plt.yticks(y, list) 对 Y 轴增加坐标标记
plt.xlim(min, max) 显示 X 轴坐标范围
plt.ylim(min, max) 显示 Y 轴坐标范围

其中 ticks 可以设置字体大小(fontsize)、旋转角度(rotation)等属性。

网格显示

plt.grid(Ture)

matplotlib 库的基础绘图函数

基础绘图函数

函数 说明
plt.plot(x,y,fmt) 绘制一个坐标图
plt.vlines(x, ymin, ymax) 绘制一个垂直线
plt.hlines(y, xmin, xmax) 绘制一个水平线
plt.axvline(x=0, ymin=0, ymax=1) 绘制一个垂直线
plt.axhline(y=0, xmin=0, xmax=1) 绘制一个水平线
plt.axvspan(xmin, xmax, ymin=0, ymax=1) 绘制一个垂直矩形
plt.axhspan(ymin, ymax, xmin=0, xmax=1) 绘制一个水平矩形
plt.boxplot(data,notch,position) 绘制一个箱形图
plt.bar(left,height,width,bottom) 绘制一个条形图
plt.barh(width,bottom,left,height) 绘制一个横向条形图
plt.hist(x,bins,normed) 绘制一个直方图
plt.pie(data, explode) 绘制一个饼状图
plt.scatter(x,y) 绘制一个散点图
plt.stem(x,y,linefmt,markerfmt) 绘制一个柴火图
plt.step(x,y,where) 绘制一个步阶图
pyplot.psd() 绘制一个能量谱密度图
pyplot.magnitude_spectrum() 绘制一个幅度频谱图
pyplot.phase_spectrum() 绘制一个相角频谱图
pyplot.angle_spectrum() 绘制一个相位频谱图

绘制垂直、水平线、矩形

matplotlib.pyplot.axhline;matplotlib.pyplot.axvline;matplotlib.pyplot.hlines;matplotlib.pyplot.vlines;matplotlib.pyplot.axhspan;matplotlib.pyplot.axvspan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

# draw a default hline at y=1 that spans the xrange
plt.axhline(y=1)
# draw a default vline at x=1 that spans the yrange
plt.axvline(x=1)

# draw a thick red hline at y=0 that spans the xrange
plt.axhline(linewidth=8, color='#d62728')
# draw a thick blue vline at x=0 that spans the yrange from 0.8 to 1.4
plt.axvline(x=0.25, ymin=0.6, ymax=0.8, linewidth=8, color='#1f77b4')
plt.axvline(x=0.5, ymin=0.8, ymax=0.6, linewidth=8, color='#1f77b4')
plt.vlines(x=0.75, ymin=0.8, ymax=1.4, linewidth=8, color='#1f77b4')
plt.vlines(x=1, ymin=1.4, ymax=0.8, linewidth=8, color='#1f77b4')
# draw a default hline at y=.5 that spans the middle half of the axes
plt.axhline(y=0.5, xmin=0.25, xmax=0.75)

plt.axhspan(0.25, 0.75, xmin=0.2, xmax=0.7, facecolor='0.5', alpha=0.5)
plt.axvspan(1.25, 1.55, ymin=0.2, ymax=0.7, facecolor='#2ca02c', alpha=0.5)

plt.axis([-1, 2, -1, 2])


plt.axvline(x=0, ymin=0, ymax=1)plt.axhline(y=0, xmin=0, xmax=1)plt.vlines(x, ymin, ymax)plt.hlines(y, xmin, xmax) 类似,但是前者可以不填任何参数,而后者必须指定三个参数。其中第一个参数为线段的x轴或者y轴位置,第二、第三个参数为线段的起点和终点位置。其中对于前者,起点和终点位置是由距离坐标系两端的距离的比例来决定,对于后者,起点和终点位置是由绝对坐标来决定。
例如 plt.axvline(x=0.25, ymin=0.6, ymax=0.8, linewidth=8, color='#1f77b4') 表示线段从(0.25,0.6*(2-(-1))+(-1))到(0.25,0.8*(2-(-1))+(-1))。其中ymin和ymax的值交换位置不影响结果。而 plt.vlines(x=0.75, ymin=0.8, ymax=1.4, linewidth=8, color='#1f77b4') 表示线段从(0.75,0.8)到(0.75,1.4)。同样的,ymin和ymax的值交换位置不影响结果。从图中还可以观察到,axvline形成的线段上下端也有宽度,而vline形成的线段没有,所以前者形成的线段比后者稍长。
除x,y,xmin,xmax,ymin,ymax之外的参数为通用参数,其中facecolor或者fc表示面积颜色,alpha表示透明度(取值为0到1之间的浮点数)。

绘制箱形图、条形图、直方图

箱形图

matplotlib.pyplot.boxplot

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
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
data = np.random.lognormal(size=(25, 4), mean=1.5, sigma=1.75)
labels = list('ABCD')

fig, axes = plt.subplots(nrows=2, ncols=6, figsize=(12, 6), sharey=True)
axes[0, 0].boxplot(data, labels=labels)
axes[0, 1].boxplot(data, labels=labels, showmeans=True)
axes[0, 2].boxplot(data, labels=labels, showmeans=True, meanline=True)
axes[0, 3].boxplot(data, labels=labels, showbox=False, showcaps=False)
axes[0, 4].boxplot(data, labels=labels, notch=True, bootstrap=10000)
axes[0, 5].boxplot(data, labels=labels, showfliers=False)

boxprops = dict(linestyle='--', linewidth=3, color='darkgoldenrod')
flierprops = dict(marker='o', markerfacecolor='green', markersize=12, linestyle='none')
medianprops = dict(linestyle='-.', linewidth=2.5, color='firebrick')
meanpointprops = dict(marker='D', markeredgecolor='black', markerfacecolor='firebrick')
meanlineprops = dict(linestyle='--', linewidth=2.5, color='purple')

axes[1, 0].boxplot(data, boxprops=boxprops)
axes[1, 1].boxplot(data, flierprops=flierprops, medianprops=medianprops)
axes[1, 2].boxplot(data, whis='range')
axes[1, 3].boxplot(data, meanprops=meanpointprops, meanline=False, showmeans=True)
axes[1, 4].boxplot(data, meanprops=meanlineprops, meanline=True, showmeans=True)
axes[1, 5].boxplot(data, whis=[15, 85])



data为随机生成的4×25数组,图片划分为2栏6列,sharey=Ture 表示共享Y轴坐标。
axes为坐标系对象是一个2×6的数组,每一个元素对应一个坐标系。
plt.boxplot() 第一个参数为所展示的数据,数组形式;label为X轴坐标的标签。
vert=False 表示箱形图案为横向放置,patch_artist=True 表示箱形图框内有填充。
showmeans=Ture 表示显示平均值,meanline=Ture 表示使平均值以虚线形式显示。
showbox=False 表示不显示箱形边框,showcaps=False 表示不显示上下两端的error_bar。
notch=True 表示显示槽口,bootstrap=10000 表示显示中值周围的置信区间。
showfliers=False 表示不显示上下error_bar之外的值。
boxprops 表示箱形图案的属性;flierprops 表示error_bar之外的点的属性;medianprops 表示中值点的属性;meanprops 表示平均值点的属性。
whis 表示数据范围的属性:它的值可以是浮点数、字符串、数组范围。
- 如果 whis='range' 表示error_bar的范围为所有数值的最小值到所有数值的最大值,即没有上下极端值。
- 如果 whis=[a,b],其中a,b是两个数字(整型或者浮点型均可),则error_bar的范围为所有数值由小到大排列后第a%位的值到所有数值由小到大排列后第b%位的值。
- 如果 whis=c,其中c是一个浮点数,则表示error_bar的范围为(Q1-c*(Q3-Q1))到(Q3+c*(Q3-Q1)),其中Q1所有数值由小到大排列后第25%的值,Q3所有数值由小到大排列后第75%的值。
- 如果不设置whis,则默认值为 whis=1.5

条形图

matplotlib.pyplot.bar;matplotlib.pyplot.barh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
import matplotlib.pyplot as plt

N = 5
menMeans = (20, 35, 30, 35, 27)
womenMeans = (25, 32, 34, 20, 25)
menStd = (2, 3, 4, 1, 2)
womenStd = (3, 5, 2, 3, 3)
ind = np.arange(N) # the x locations for the groups
width = 0.5 # the width of the bars: can also be len(x) sequence

p1 = plt.bar(ind, menMeans, width, color='r', hatch='o')
plt.errorbar(ind+0.25, menMeans, yerr=menStd, capsize=5, elinewidth=5, capthick=5, ecolor='g', linewidth=0)
p2 = plt.bar(ind, womenMeans, width, bottom=menMeans, yerr=womenStd)
plt.errorbar(ind+0.25, np.array(womenMeans)+np.array(menMeans) , yerr=womenStd, capsize=5, elinewidth=5, capthick=5, ecolor='y', linewidth=0)

plt.ylabel('Scores')
plt.title('Scores by group and gender')
plt.xticks(ind+0.25, ('G1', 'G2', 'G3', 'G4', 'G5'))
plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('Men', 'Women'))


plt.bar(x, height, width, bottom, align='center') 表示画一个柱状图案(矩形),其上下左右边界分别为bottom+height、bottom、x-width/2、x+width/2
align表示x表示矩形的中间(align='center')还是矩形的左边边界(align='edge')。如果需要让x表示矩形的右边边界,则设置align='edge'且width为一个负数。align的默认值为'center'。
其他常用的属性有:
color : 柱状图案的填充颜色
edgecolor : 柱状图案的边框颜色
linewidth : 柱状图案的边框粗细
xerr : x轴的error bar
yerr : y轴的error bar
elinewidth: error bar的宽度
capsize: error bar的帽子大小
capthick: error bar的帽子宽度
ecolor : error bar的颜色
log : 如果为true,则坐标为对数显示
hatch:图案填充, ['/' | '' | '|' | '-' | '+' | 'x' | 'o' | 'O' | '.' | '*']
如果绘制横向条形图,则使用 plt.barh(y, height, width, left, align='center'),使用方法同上。

直方图

matplotlib.pyplot.hist

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
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

np.random.seed(0)

# example data
mu = 100 # mean of distribution
sigma = 25 # standard deviation of distribution
x = mu + sigma * np.random.randn(500)
num_bins = 50

fig, ax = plt.subplots()

# the histogram of the data
n, bins, patches = ax.hist(x, num_bins, normed=True)
for i in patches[::2]:
i.set_color('y')

# add a 'best fit' line
y = mlab.normpdf(bins, mu, sigma)
ax.plot(bins, y, '--')
ax.set_xlabel('Smarts')
ax.set_ylabel('Probability density')
ax.set_title(r'Histogram of IQ: $\mu=100$, $\sigma=25$')


data为随机生成的以mu为均值,以sigma为标准差的正态分布数组,数组长度为500。
所绘制的直方图有50个分组。
plt.bar(x, num_bins, normed=True) 中x为data,num_bins为分组个数,normed为是否归一化。
并且返回n, bins, patches三个数组,n和patches的数组维度均为分组个数,而bins的数组维度为分组个数+1;
其中n为数据落在每个分组中的个数或者概率密度,bins为每个分组的两端的x坐标值,patches表示每个分组,可以通过patches对分组属性进行设置。
当normed=False时,n为数据落在每个分组中的个数;当normed=True,n为数据落在每个分组中的概率密度(注意,不是概率分布,sum(n)*(max(num_bins)-min(num_bins))=num_bins)。
i.set_color('y') 设置了每隔一个分组颜色为黄色。
y = mlab.normpdf(bins, mu, sigma) 返回一个数组,数组为以mu为均值,以sigma为标准差的正态分布曲线上bins所对应的y轴值。
ax.plot(bins, y, '--') 则绘制匹配直方图的正态分布图曲线。

绘制饼状图

matplotlib.pyplot.pie

1
2
3
4
5
6
7
8
9
10
import matplotlib.pyplot as plt

# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.5, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')

fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', pctdistance=0.5, labeldistance=1.2, radius=2, shadow=True, startangle=90)
ax1.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.


explode表示每部分饼状图案偏离圆心的距离,为绝对距离。
autopct表示显示数字的格式。pctdistance表示显示数字距离圆心的相对距离,默认值为0.6,表示数字离圆心0.6个半径距离。
shadow表示是否有阴影,startangle表示绘制饼状图的起始角度。
labels表示标签,labeldistance表示标签离圆心的相对距离,默认为1.1,表示数字离圆心1.1个半径距离。
radius表示饼状图的半径,为绝对距离。
plt.axis('equal')表示饼状图为正圆形,否则为椭圆形。

绘制散点图

matplotlib.pyplot.scatter

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

N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radii

plt.scatter(x, y, s=area, c=colors, alpha=0.5)


data为50个任意点,颜色也为任意的0-1之间的数,半径为0-15π之间任意的数。
x,y是维度一样的列表,其中每个元素表示每个点的横纵坐标。
s表示大小。alpha表示透明度。

绘制柴火图、步阶图

matplotlib.pyplot.stemmatplotlib.pyplot.step

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import matplotlib.pyplot as plt
from numpy import ma
import numpy as np

plt.figure(figsize=(16,4))
plt.subplot(1, 2, 1)
x = np.linspace(0.1, 2*np.pi, 10)
plt.stem(x, np.cos(x), '-.')

plt.subplot(1, 2, 2)
x = np.arange(1, 7, 0.4)
y0 = np.sin(x)
y = y0.copy() + 2.5
plt.step(x, y, label='pre (default)')
y -= 0.5
plt.step(x, y, where='mid', label='mid')
y -= 0.5
plt.step(x, y, where='post', label='post')
y = ma.masked_where((y0 > -0.15) & (y0 < 0.15), y - 0.5)
plt.step(x, y, label='masked (pre)')
plt.legend()
plt.xlim(0, 7)
plt.ylim(-0.5, 4)


x, y表示数据的横纵坐标。
在step函数中有一个where属性,where属性有三个取值'pre'或'post'或'mid'。
where='pre' 是默认值,表示每个步阶的坐标是从(x[i],y[i+1])到(x[i+1],y[i+1])。
where='mid' 表示每个步阶的坐标是从(x[i],y[i])到(x[i+1],y[i])。
where='post' 表示每个步阶的跳跃是从步阶的一半开始。

绘制频谱图

matplotlib.pyplot.psd;matplotlib.pyplot.magnitude_spectrum;matplotlib.pyplot.angle_spectrum;matplotlib.pyplot.phase_spectrum

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
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(0)
dt = 0.01
Fs = 1/dt
t = np.arange(0, 10, dt)
nse = np.random.randn(len(t))
r = np.exp(-t/0.05)
cnse = np.convolve(nse, r)*dt
cnse = cnse[:len(t)]
s = 0.1*np.sin(2*np.pi*t) + cnse

plt.subplot(3, 2, 1)
plt.plot(t, s)

plt.subplot(3, 2, 2)
plt.psd(s, Fs=Fs)

plt.subplot(3, 2, 3)
plt.magnitude_spectrum(s, Fs=Fs)

plt.subplot(3, 2, 4)
plt.magnitude_spectrum(s, Fs=Fs, scale='dB')

plt.subplot(3, 2, 5)
plt.angle_spectrum(s, Fs=Fs)

plt.subplot(3, 2, 6)
plt.phase_spectrum(s, Fs=Fs)


pyplot.psd() 绘制能量谱密度图;pyplot.magnitude_spectrum() 绘制幅度频谱图;pyplot.phase_spectrum() 绘制相角频谱图;pyplot.angle_spectrum() 绘制相位频谱图。
Fs表示采样频率。