目录
1. 概念与安装
1.1 概念
matplotlib是一款用于数据可视化的python软件包,它能根据NumPy ndarray数组类绘制2D图像。
组成:(1)Figure:相当于一张画布,包括了所有元素
(2)Axes:绘制图像的实际区域,即绘图区
(3)Axis:坐标轴(x轴、y轴)
(4)Artist:函数图像以及对应标题等文本对象
1.2 安装
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple/
1.3 导入软件包
from matplotlib import pyplot as plt
import numpy as np
2. 常用函数
2.1 plot函数
plot(x, y, format_string=None, **kwargs):一个用于绘制二维图形的函数,它根据提供的x和y数据绘制图形。
参数:(1)x:x轴数据,可为数组或列表
(2)y:y轴数据,可为数组或列表
(3)format_string:用于指定线条样式、颜色等(常用:颜色:b(蓝色)、g(绿色)、r(红色),线条:-(实线)、--(虚线)、:(点线))
x = np.linspace(0, 10, 100)
y = np.sin(x)
# plot():绘制图形-->参数:format_string:设置曲线颜色、线条样式
plt.plot(x, y, 'r--')
# 显示图形
plt.show()
2.2 figure函数
figure()函数用来实例化figure对象,即画布对象,通过设置参数来调整样式。
参数:
figsize | 指定画布的大小(宽高),单位为英寸 |
dpi | 绘图对象的分辨率,默认80 |
facecolor | 背景颜色 |
dgecolor | 边框颜色 |
frameon | 是否显示边框 |
2.2.1 add_axes()
add_axes():轴域对象,它指定了一个有数值范围限制的绘图区域。在一个画布(figure)中有多个绘图区域(axes),但同一个绘制区域(axes)只能在一个画布中使用。
参数:
add_axes([left, bottom, width, height])
left和bottom用于定位绘图区域,且取值范围在0~1之间,是使用的比例值。
width和height是区域的宽度和高度的比例值,范围在0~1之间,主要是用来适应具体画布大小。
# figure():生成画布-->参数:figsize:设置画布的宽高,数据格式为元组,单位:英寸
fig = plt.figure(figsize=(12, 8))
# add_axes():画布生成绘画区域-->参数:left、bottom、width、height:取值范围为0~1
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
x = np.linspace(-10, 10, 100)
y = x ** 2
# 通过绘图区域对象调用plot()绘制图形,使图形绘制在绘图区域中
ax.plot(x, y)
plt.show()
2.2.2 axes.legend()
legend()函数用于添加图例,以便识别图中的不同数据系列。
参数;
handles | 设置图形实例,参数数据格式为列表 |
labels | 设置图形实力的标签说明,数据格式为列表 |
loc | 设置图例显示的位置,如best、center、upper center等 |
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
x = np.linspace(-10, 10, 100)
y = x ** 2
# legend():设置图形的图例-->参数:handles:设置图形实例(列表)、
# labels:设置图形实例的标签说明(列表)、loc:设置图例显示的位置
# line = ax.plot(x, y)
# ax.legend(handles=line, labels=['x^2'], loc='best')
# 图例设置的第二种方式(常用)
# 1.在plot方法中添加label参数,设置图例说明
# 2.调用legend方法使图例生效,legend方法里可以不用设置handles和label
ax.plot(x, y, label='x^2 函数')
ax.legend(loc='upper center')
plt.show()
2.3 标题中文乱码
如果标题设置的是中文,会出现乱码。有两种处理方式。
(1)局部处理
# 局部处理中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
(2)全局处理
# 全局处理中文乱码
import matplotlib
print(matplotlib.matplotlib_fname())
运行上述代码后,获得matplotlib的配置文件。复制该地址后,在任意文件夹中粘贴该地址并回车,会打开该配置文件。
打开配置文件后,进行三步操作:
1.删除font.family前的#号
2.删除font.sans-serif前的#号,并在后面添加SimHei
3.删除axes.unicode_minus前的#号,并将其值改为False
2.4 subplot函数
subplot函数是较早的函数,因此现在大部分是使用add_subplot函数。它更具灵活性,用于向图像容器中添加子图,使得一个画布中有多个子图形。
缺陷是代码可读性差,需要手动计算子图的行列索引,并且不适用于复杂的子图布局,如嵌套子图或坐标轴共享。
# 准备数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
# 生成figure画布
fig = plt.figure(figsize=(12, 4))
# 添加第一个子图区域
# ax1 = fig.add_subplot(1, 3, 1)
ax1 = fig.add_subplot(131)
ax1.plot(x, y1, label='sin(x)')
plt.legend()
# 添加第二个子图区域
ax2 = fig.add_subplot(1, 3, 2)
ax2.plot(x, y2, label='cos(x)')
plt.legend()
# 添加第三个子图区域
ax3 = fig.add_subplot(1, 3, 3)
ax3.plot(x, y3, label='tan(x)')
# 使图例生效
plt.legend()
# 显示图形
plt.show()
2.5 subplots函数(使用最多)
subplots创建了一个包含多个子图的图形窗口,且它返回的是一个包含所有子图的数组,这样使得更方便地对每个子图进行操作,因此可以批量操作这些子图。
缺陷是灵活性较低,子图的数量和布局已经提前确定好,无法动态的添加子图。
# 准备数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
# 按照nrows和ncols生成多个子图区域,在每个子图区域中绘制图形
fig, axs = plt.subplots(1, 3, figsize=(12, 4))
axs[0].plot(x, y1)
axs[1].plot(x, y2)
axs[2].plot(x, y3)
plt.show()
而且subplots函数还可以在同一个绘图区域绘制多个子图图形。
# 准备数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
# 生成一个子图区域,并在这一个区域中绘制多个图形
fig, axs = plt.subplots()
axs.plot(x, y1, 'r')
axs.plot(x, y2, 'b')
axs.plot(x, y3, 'g')
plt.show()
2.6 subplot2grid函数
subplot2grid函数用于在网格中创建子图。它允许你更灵活地指定子图的位置和大小,以非等分的形式对画布进行切分,使得你可以创建复杂的布局。
语法:
plt.subplot2grid(shape, loc, rowspan=1, colspan=1)
参数:
shape | 网格的形状,参数格式为元组(rows, cols) |
loc | 子图的起始位置,格式为元组(row, col) |
rowspan | 子图占据的行数 |
colspan | 子图占据的列数 |
# 准备数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = np.exp(x)
# shape:将画布分为3x3的区域,loc:当前子图所在位置,colspan:所占列数,rowspan:所占行数
axs1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
axs2 = plt.subplot2grid((3, 3), (1, 0))
axs3 = plt.subplot2grid((3, 3), (2, 0))
axs4 = plt.subplot2grid((3, 3), (2, 2))
axs1.plot(x, y1)
axs2.plot(x, y2)
axs3.plot(x, y3)
axs4.plot(x, y4)
plt.show()
2.7 grid函数
grid是用于在图形中添加网格线的函数,帮助读者更清晰地理解数据地分布和趋势。
语法:
ax.grid(b=None, which='major', axis='both', **kwargs)
参数:
b | 是否显示网格线,默认是None |
which | 指定要显示的网格线类型:major主刻度、minor次刻度、both主刻度和次刻度 |
axis | 指定要显示网格线的轴:x(x轴)、y(y轴)、both(两个轴) |
**kwargs | 其他可选参数,如color(网格线颜色)、linestyle(线条样式)、linewidth(线条粗细)等 |
# 准备数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, axs = plt.subplots()
axs.plot(x, y)
# grid():在图形中添加网格线
# 参数:b-是否显示网格线、which-网格线类型、axis-显示哪个轴的网格线(x, y, both)、
# kwargs-设置color(网格线颜色)、linestyle(线条样式)、linewidth(线条粗细)
plt.grid(True, color='r', linewidth=2, axis='x')
plt.show()
2.8 对坐标轴的一些修改参数
2.8.1 xscale和yscale函数
xscale 和 yscale 函数用于设置坐标轴的刻度类型。默认情况下,坐标轴的刻度类型是线性的。
语法:
ax.set_xscale(value)
ax.set_yscale(value)
参数:
value:linear--线性刻度、log--对数刻度、symlog--对称对数刻度、logit--对数几率刻度等。
# 准备数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, axs = plt.subplots()
axs.plot(x, y)
# xscale、yscale:设置x、y轴的刻度类型
plt.xscale('symlog')
plt.yscale('linear')
plt.show()
2.8.2 set_xlim和set_ylim函数
set_xlim 和 set_ylim 函数用于设置坐标轴的范围。
语法:
ax.set_xlim(left, right)
ax.set_ylim(bottom, top)
参数:
left和right:x轴的范围,left是最小值,right是最大值。
bottom和top:y轴的范围,bottom是最小值,top是最大值。
若数据准备时已经确定了x、y的范围,则可以适当的调整范围。因为超出准备范围外的坐标轴是没有图像的,则超出范围就没有设置的必要了。
# 准备数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, axs = plt.subplots()
axs.plot(x, y)
# set_xlim、set_xlim:设置x、y轴的取值范围
axs.set_xlim(0, 5)
axs.set_ylim(0, 1)
plt.show()
2.8.3 set_xticks和set_yticks函数
set_xticks() 和 set_yticks() 函数可以手动指定刻度,接受一个列表对象作为参数,列表中的元素表示对应轴上要显示的刻度。
语法:
ax.set_xticks(ticks)
ax.set_yticks(ticks)
参数:
ticks:一个包含刻度位置的列表或数组。
# 准备数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, axs = plt.subplots()
axs.plot(x, y)
axs.set_ylim(0, 1)
# set_xticks、set_xticks:手动设置x、y轴的刻度列表
axs.set_xticks([0, 2, 4, 6])
axs.set_yticks([0, 0.4, 0.8, 1])
plt.show()
2.8.4 twinx和twiny函数
twinx 和 twiny 函数用于在同一个图形中创建共享 x 轴或 y 轴的多个子图。twinx 函数用于创建共享 Xx轴的子图,twiny 函数用于创建共享 y 轴的子图。
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
fig, axs = plt.subplots()
axs.plot(x, y1, 'r')
# 共享x轴
# axs1 = axs.twinx()
# axs1.plot(x, y2)
# 共享y轴
axs2 = axs.twiny()
axs2.plot(x, y2, 'g')
plt.show()
共享x轴:
共享y轴:
3. 多种图形
3.1 柱状图
语法:
ax.bar(x, height, width=0.8, bottom=None, align='center, **kwargs)
参数:
x | 柱状图的x轴位置,数据格式为list |
height | 柱状图高度,即y轴数据,数据格式为list |
width | 柱状图的宽度,默认为0.8 |
bottom | 柱状图的底部位置,默认为0 |
align | 柱状图的对齐方式:'center'居中对齐,'edge'边缘对齐 |
**kwargs | 其他可选参数,如color、edgecolor、lindwidth |
最常见的三种柱状图:
(1)基本柱状图
categories = ['A', 'B', 'C', 'D']
values = [20, 35, 30, 25]
fig, ax = plt.subplots()
# bar():柱状图-->参数:x:x轴的数据,格式是list
# height:y轴的数据,格式是list、width:柱子的宽度,在0~1之间
# align:柱子的对齐方式,center:中间对齐 edge:边缘对齐
ax.bar(categories, values)
plt.show()
(2)堆叠柱状图
categories = ['A', 'B', 'C', 'D']
value1 = [20, 35, 30, 25]
value2 = [10, 35, 3, 15]
fig, ax = plt.subplots()
ax.bar(categories, value1, color='skyblue')
# 通过添加bottom属性,使得第二个柱状图拼接到第一个柱状图上
ax.bar(categories, value2, bottom=value1, color='lightgreen')
plt.show()
(3)分组柱状图
categories = ['A', 'B', 'C', 'D']
values1 = [20, 35, 30, 25]
values2 = [15, 25, 20, 10]
# 创建图形和子图
fig, ax = plt.subplots()
# 计算柱状图的位置
x = np.arange(len(categories))
width = 0.35
# 绘制第一个数据集的柱状图
ax.bar(x - width / 2, values1, width, color='skyblue', label='Values 1')
# 绘制第二个数据集的柱状图
ax.bar(x + width / 2, values2, width, color='lightgreen', label='Values 2')
plt.show()
3.2 直方图
语法:
ax.hist(x, bins=None, range=None, destiny=False, weights=None, cumulative=False, **kwargs)
参数:
x | 数据数组 |
bins | 直方图的柱数,可以是整数或序列 |
range | 直方图的范围,格式:(min, max) |
destiny | 是否将直方图归一化,默认False |
weights | 每个数据点的权重 |
cumulative | 是否绘制累计直方图,默认False |
**kwargs | 可选参数,如color、edgecolor、lindwidth等 |
# 生成随机数据,生成均值为 0,标准差为 1 的标准正态分布的随机样本
data = np.random.randn(1000)
fig, ax = plt.subplots()
# hist():直方图
ax.hist(data, bins=50, color='skyblue', edgecolor='black')
plt.show()
3.3 饼图
语法:
ax.pie(x, explode=None, labels=None, colors=None, autopct=None, shadow=False, startangle=0, **kwargs)
参数:
x | 数据数组,表示每个扇区的占比 |
explode | 数组,表示每个扇区偏离圆心的距离,默认None |
labels | 每个扇区的标签 |
colors | 每个扇区的颜色 |
autopct | 控制显示每个扇区的占比,可以是格式化字符串或函数 |
shadow | 是否显示阴影 |
startangle | 饼图的起始角度,默认0 |
**kwargs | 可选参数,同上述直方图 |
labels = ['A', 'B', 'C', 'D']
sizes = [15, 30, 45, 15]
fig, ax = plt.subplots()
# pie():绘制饼图-->参数:x:数据数组、labels:数据对应的标签名称、autopct:控制显示数据占比
# startangle:饼图的起始位置
ax.pie(sizes, labels=labels, autopct='%1.1f%%')
plt.show()
3.4 散点图
语法:
ax.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors=None, **kwargs)
参数:
x | x轴数据 |
y | y轴数据 |
s | 点的大小,可以是标量或数组 |
c | 点的颜色,可以是标量、数组或颜色列表 |
marker | 点的形状,默认'o'圆圈 |
cmap | 颜色映射,用于将颜色映射到数据 |
norm | 归一化对象,用于数据映射到颜色映射 |
vmin、vmax | 颜色映射的最小值、最大值 |
alpha | 点的透明度,范围0~1 |
linewidths | 点的边框宽度 |
edgecolors | 点的边框颜色 |
x = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
data = [
[120, 132, 101, 134, 90, 230, 210],
[220, 182, 191, 234, 290, 330, 310],
]
y0 = data[0]
y1 = data[1]
fig, ax = plt.subplots()
# scatter():散点图,用于比较两个或多个数据集之间的关系
ax.scatter(x, y0, color='skyblue')
ax.scatter(x, y1, color='lightgreen')
plt.show()
4. 图片读取
plt.imread是Matplotlib库中的一个函数,用于读取图像文件并将其转换为NumPy数组。
语法:
plt.imread(fname, format)
参数:
fname | 图像文件的路径(字符串) |
format | 图像格式(可选)。未指定,会根据文件扩展名自动推断格式 |
返回值:
(1)灰度图像:返回一个二维数组(height, width),即(行,列)-- HW
(2)彩色图像:返回一个三维数组(height, width, channels),即(行,列,颜色),其中channels通常是3(RGB)或4(RGBA)-- HWC
# 获取文件所在文件夹
filepath = os.path.dirname(__file__)
print(filepath)
# 获取图像的绝对路径(这里是将图像放在了代码文件所在文件夹)
filepath = os.path.join(filepath, '1.png')
print(filepath)
# 转化为相对路径
filepath = os.path.realpath(filepath)
print(filepath)
# imread():读取图片,并生成多维数组
data = plt.imread(filepath)
print(data.shape)
print(data)
# imshow():将数组显示为图片
plt.imshow(data)
plt.show()
data1 = np.transpose(data, (2, 0, 1))
for i in data1:
plt.imshow(i)
plt.show()
# imsave():把数组保存为图片
# plt.imsave('2.png', i)