Matplotlib绘图库的高级使用
- Matplotlib的三层结构
- 容器层
- 辅助显示层
- 图像层
- Matplotlib的绘图配置
- 设置画布属性
- 绘图保存
- 自定义x与y刻度
- 解决中文显示异常
- 网格显示
- 多次plot
- 绘图标记
- 显示图例
- 多个坐标系显示
Matplotlib的三层结构
Matplotlib从层次结构上分,可以分为三层:容器层、辅助显示层、图像层。
容器层
容器层主要由Canvas、Figure、Axes组成。
Canvas对象
Canvas对象是一个表示画布的类,用于渲染绘图元素。它是位于最底层的系统层,在绘图的过程中充当画板的角色,即放置画布(Figure)的工具。
Figure对象
它是Canvas上方的第一层容器,用于表示整个图像窗口,包含所绘制的所有元素。可以通过 plt.figure() 函数创建一个新的 Figure 对象。每个Figure对象包含了一个或多个Axes对象。
Axes对象
它是Canvas上方的第二层,是一个绘图区域,用于展示数据,它包含了所有的绘图元素,如:直线、曲线、文本、图像、坐标系等。每个Axes对象对应一个坐标系,使用fig.add_subplot()或plt.subplots() 函数创建Axes对象。
Axis是一个坐标轴,用于确定数据的范围和刻度。每个Axes对象都有两个Axis对象,分别对应x轴和y轴。可以使用 ax.set_xlim()和 ax.set_ylim() 函数设置坐标轴的范围,使用ax.set_xticks() 和 ax.set_yticks() 函数设置坐标轴的刻度。
注意:
当创建一个 Figure 对象时,它会自动创建一个 Axes 对象,并将其添加到 Figure 对象中。然后可以在 Axes 对象中绘制各种类型的图表。
创建Figure和Axes对象,并在Axes对象中绘制折线图:
import matplotlib.pyplot as plt
# 创建 Figure 对象
fig = plt.figure()
# 创建 Axes 对象
ax = fig.add_subplot(111)
# 绘制折线图
x = [1, 2, 3, 4, 5]
y = [10, 8, 6, 4, 2]
ax.plot(x, y)
# 显示图形
plt.show()
辅助显示层
辅助显示层为Axes(绘图区)内的除了根据数据绘制出的图像以外的内容,主要包括Axes外观(facecolor)、边框线(spines)、坐标轴(axis)、坐标轴名称(axis label)、坐标轴刻度(tick)、坐标轴刻度标签(tick label)、网格线(grid)、图例(legend)、标题(title)等内容。
简单的说就是用于添加特殊的文本、箭头、注释和图例等可视化元素。这些元素不像常规的数据展示元素那样直接反映数据本身,而是用于强调或解释数据以及提供更多信息。
这些辅助元素可帮助用户更好地理解图形,深入理解这些元素的使用,可以使数据可视化更加精确和友好。
Matplotlib中常用的辅助显示层:
Text:用于在图表中添加文本注释。可以使用 ax.text() 函数将文本添加到 Axes 对象中,或使用 fig.text() 函数将文本添加到 Figure 对象中。
Annotations:用于在图表中添加带有箭头的注释。可以使用 ax.annotate() 函数添加注释。
Legends:用于为图表中的数据系列添加说明。可以使用 ax.legend() 函数添加图例。
Colorbars:用于显示颜色映射和值范围。可以使用 fig.colorbar() 函数添加颜色条。
在 Matplotlib 图表中添加文本、注释、图例和颜色条:
import matplotlib.pyplot as plt
import numpy as np
# 使用np.linspace() 函数生成了一组正弦曲线数据
x = np.linspace(-np.pi, np.pi, 100)
y = np.sin(x)
# 创建 Figure 对象和 Axes 对象
fig, ax = plt.subplots()
# 绘制正弦曲线
ax.plot(x, y, label='sin')
# 添加标题和标签
ax.set_title('Sin Wave')
ax.set_xlabel('x')
ax.set_ylabel('y')
# 添加文本
ax.text(-3, 0.8, 'Peak Value', fontsize=12)
# 使用annotate() 函数添加了一个带箭头的注释
ax.annotate('Local Max', xy=(np.pi/2, 1), xytext=(2, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05))
# 添加图例
ax.legend()
# 添加颜色条
im = ax.imshow([[0, 1], [2, 3]], cmap='jet')
fig.colorbar(im)
# 显示图形
plt.show()
图像层
Matplotlib的图像层用于呈现和交互Matplotlib图像。Matplotlib的图像层指的是在Axes对象中绘制的各种图形元素,例如线图、散点图、柱状图等。
Matplotlib提供了丰富的图形元素来满足不同类型数据的可视化需求。
折线图:通常用于显示随时间、位置或其他连续值变化而变化的一些数据趋势。可以使用plot方法进行绘制。
散点图:用于显示多个变量之间的关系或在多个数据中的分布情况。可以使用scatter方法进行绘制。
柱状图:用于表示一组离散的数据,通常用于比较不同类别或组之间的数量或频率。可以使用bar方法进行绘制。
饼图:通常用于显示数据的相对大小,尤其适用于百分比或部分-整体关系。可以使用pie方法进行绘制。
直方图:用于表示连续变量的分布情况,显示变量的频率分布情况。可以使用hist方法进行绘制。
Matplotlib的绘图配置
Matplotlib文档:https://matplotlib.org/stable/tutorials/index.html
设置画布属性
属性 | 示例 |
---|---|
设置画布大小 | plt.figure(figsize=(8,6)) |
设置画布标题 | plt.title(“My Title”) |
设置横轴和纵轴标签 | plt.xlabel(“X Label”) plt.ylabel(“Y Label”) |
设置坐标轴刻度范围 | plt.xlim(0, 10) # 横轴 plt.ylim(0, 20) # 纵轴 |
设置坐标轴刻度 | plt.xticks(range(0, 11, 2)) # 横轴刻度范围为 0 到 10,步长为 2 plt.yticks(range(0, 21, 5)) # 纵轴刻度范围为 0 到 20,步长为 5 |
设置坐标轴显示和隐藏 | plt.axis(‘on’) # 显示坐标轴 plt.axis(‘off’) # 隐藏坐标轴 |
设置图例 | plt.legend([‘line1’, ‘line2’]) # 图例文本为 ‘line1’ 和 ‘line2’ |
设置网格线 | plt.grid(True) # 显示网格线 plt.grid(False) # 隐藏网格线 |
设置图像清晰度 | plt.figure(dpi=80) 默认是 dpi=100 |
设置文本注释 | plt.text(3,8, ‘坐标(3,8)’) |
设置图例 | plt.legend([‘图例1’]) |
# 创建画布,并设置画布属性
plt.figure(figsize=(20, 8), dpi=80)
import matplotlib.pyplot as plt
# 创建画布,并设置画布属性
plt.figure(figsize=(20, 8), dpi=80)
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]
plt.plot(x, y)
# 添加标题
plt.title("价格与销量的变化示意图")
# 添加 x 轴和 y 轴标签
plt.xlabel("价格")
plt.ylabel("销量")
# 添加文本注释
plt.text(3,8, '坐标(3,8)')
plt.show()
绘图保存
Matplotlib允许用户将图形保存为各种格式的图片,例如 PNG、PDF、SVG 和 EPS。
使用savefig()函数保存当前活动图形。在调用 savefig()函数之前,必须先创建一个图形
格式 | 示例 |
---|---|
PNG格式 | plt.savefig(‘myplot.png’) |
PDF格式 | plt.savefig(‘myplot.pdf’) |
SVG格式 | plt.savefig(‘myplot.svg’) |
EPS格式 | plt.savefig(‘myplot.eps’) |
PNG格式 | |
PNG格式 |
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
# 保存图片到指定路径
plt.savefig('myplot.png', dpi=200)
注意:
1.plt.show()
会释放figure
资源,如果在显示图像之后保存图片将只能保存空图片。
2.绘制出大尺寸的图像时可以设置更高的分辨率,从而得到更清晰的输出
自定义x与y刻度
Matplotlib允许用户自定义 x 轴和 y 轴的刻度范围、步长以及标签。使用xticks和yticks方法来自定义X轴和Y轴的刻度值和文本
属性 | 示例 |
---|---|
设置刻度范围 | plt.xlim(0, 10) # x 轴范围为 0 到 10 plt.ylim(0, 20) # y 轴范围为 0 到 20 |
设置刻度步长 | plt.xticks(range(0, 11, 2)) # x 轴刻度范围为 0 到 10,步长为 2 plt.yticks(range(0, 21, 5)) # y 轴刻度范围为 0 到 20,步长为 5 |
自定义刻度标签 | plt.xticks([1, 2, 3], [‘One’, ‘Two’, ‘Three’]) # 自定义 x 轴刻度标签 plt.yticks([-1, 0, 1], [‘Low’, ‘Mid’, ‘High’]) # 自定义 y 轴刻度标签 |
对数刻度 | plt.xscale(‘log’) # 使用对数刻度绘制 x 轴 plt.yscale(‘log’) # 使用对数刻度绘制 y 轴 |
# xticks方法第一个参数指定要更改的刻度位置,第二个参数指定更改后的刻度文本
plt.xticks(x, **kwargs)
# yticks方法的参数和xticks类似
plt.yticks(y, **kwargs)
# 导入matplotlib
import matplotlib.pyplot as plt
# 创建画布 figsize:画布大小 dpi:像素密度
plt.figure(figsize=(10,5), dpi=100)
# 绘制图像
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 4, 6]
plt.plot(x, y)
# 构造x轴刻度标签
x_ticks_label = ["{}组".format(i) for i in x]
# 构造y轴刻度
y_ticks = range(10)
# 修改x,y轴坐标的刻度显示
# 将X轴刻度从[1, 2, 3, 4, 5]更改为['1组', '2组', '3组', '4组', '5组']
plt.xticks(x, x_ticks_label)
# 将y轴刻度位置从[2, 4, 6, 4, 6]更改为[0,1,2...9]
plt.yticks(y_ticks)
# 显示图像
plt.show()
解决中文显示异常
1.下载 SimHei 字体
https://www.zitijia.com/i/281258939050380345.html
2.安装字体
a.Linux:拷贝字体到 usr/share/fonts 下
sudo cp ~/SimHei.ttf /usr/share/fonts/SimHei.ttf
b.windows和mac下:双击安装
3.删除缓存文件
a.Linux
cd ~/.matplotlib
rm -r *
b.windows
C:\Users\用户名\.matplotlib
4.修改配置文件matplotlibrc
a.Linux
vi ~/.matplotlib/matplotlibrc
b.windows
C:\Users\用户名\.matplotlib\matplotlibrc
将文件内容修改为:
font.family : sans-serif
font.sans-serif : SimHei
axes.unicode_minus : False
5.重启Jupyter Notebook
jupyter notebook
网格显示
Matplotlib 可以通过 grid() 方法控制网格线的显示方式,以增强图像的易读性和美观性。
属性 | 示例 |
---|---|
显示网格 | plt.grid(True) # 显示网格线 |
隐藏网格 | plt.grid(False) # 隐藏网格线 |
自定义网格样式 | plt.grid(True, linestyle=‘–’, linewidth=0.5, color=‘gray’) # 设置网格为虚线,线宽为 0.5,颜色为灰色 |
仅显示垂直或水平网格 | plt.grid(axis=‘x’) # 仅显示垂直网格 plt.grid(axis=‘y’) # 仅显示水平网格 |
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]
plt.plot(x, y)
# 添加的网格线样式为虚线,线宽为0.5,颜色为灰色
plt.grid(True, linestyle='--', linewidth=0.5, color='gray')
plt.show()
多次plot
使用多个plot()函数调用来绘制多条曲线,它们将会出现在同一个图表上。
import matplotlib.pyplot as plt
# 创建数据
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]
x2 = [1, 2, 3, 4, 5]
y2 = [2, 4, 6, 4, 6]
# 绘制图表
plt.plot(x, y, label="一部")
plt.plot(x2, y2, label="二部")
# 添加标签和标题
plt.xlabel('价格')
plt.ylabel('销量')
plt.title("价格与销量的变化示意图")
# 添加图例
plt.legend()
# 显示图表
plt.show()
绘图标记
点(Markers)
可以使用不同的符号来表示数据点
标记 | 描述 |
---|---|
“.” | 点 |
“,” | 像素点 |
“o” | 实心圆 |
“v” | 下三角 |
“^” | 上三角 |
“<” | 左三角 |
“>” | 右三角 |
“1” | 下三叉 |
“2” | 上三叉 |
“3” | 左三叉 |
“4” | 右三叉 |
“8” | 八角形 |
“s” | 正方形 |
“p” | 五边形 |
“P” | 加号(填充) |
“*” | 星号 |
“h” | 六边形 1 |
“H” | 六边形 2 |
“+” | 加号 |
“x” | 乘号 x |
“X” | 乘号 x (填充) |
“D” | 菱形 |
“d” | 瘦菱形 |
" | " |
“_” | 横线 |
0 | 左横线 |
1 | 右横线 |
2 | 上竖线 |
3 | 下竖线 |
4 | 左箭头 |
5 | 右箭头 |
6 | 上箭头 |
7 | 下箭头 |
8 | 左箭头 (中间点为基准) |
9 | 右箭头 (中间点为基准) |
10 | 上箭头 (中间点为基准) |
11 | 下箭头 (中间点为基准) |
“None”, " " or “” | 没有任何标记 |
‘ . . . ... ...’ | 渲染指定的字符。例如 “ f f f” 以字母 f 为标记。 |
线型(Linestyles)
线条的样式可以通过不同的线型来表示
线类型标记 | 描述 |
---|---|
- | 实线 |
-- | 虚线 |
-. | 点划线 |
: | 点虚线 |
颜色(Colors)
可以使用不同的颜色来标记数据点或线条
颜色标记 | 描述 |
---|---|
r | 红色 |
g | 绿色 |
b | 蓝色 |
c | 青色 |
m | 品红 |
y | 黄色 |
k' | 黑色 |
w | 白色 |
import matplotlib.pyplot as plt
x = [1, 2, 3, 4]
y = [1, 4, 2, 3]
plt.plot(x, y, linestyle="-.", marker="o", color='g')
plt.title('My Chart')
plt.xlabel('X Label')
plt.ylabel('Y Label')
plt.legend(['Data'])
plt.show()
显示图例
如果只在plt.plot()中设置label还不能最终显示出图例,还需要通过plt.legend()将图例显示出
一定要在plt.plot()里面设置一个label,否则不显示图例
图例显示位置可选参数:
字符串 | 数字 |
---|---|
‘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 |
import matplotlib.pyplot as plt
x1 = [1, 2, 3]
y1 = [4, 5, 6]
x2 = [4, 5, 6]
y2 = [1, 3, 5]
# 绘制折线图
plt.plot(x1, y1, label='Line 1')
# 使用多次plot可以画多个折线
plt.plot(x2, y2, label='Line 2', color='r', linestyle='--')
# 显示图例
plt.legend(loc="best")
# plt.legend(loc=2)
plt.show()
多个坐标系显示
Matplotlib可以通过 subplot 函数来添加多个坐标系。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.array(['A', 'B', 'C', 'D', 'E'])
y1 = np.array([3, 8, 1, 10, 5])
y2 = np.array([4, 6, 12, 2, 9])
# 创建画板和坐标系
# plt.figure(figsize=(20, 8), dpi=100)
# 创建一个包含 1 行、2 列的子图,返回一个由画板和两个坐标系组成的元组。将这个元组拆分为 fig、axis1 和 axis2 三个变量
fig, (axis1, axis2) = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)
# fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)
# 在第一个坐标系中显示第一个数据集的折线图
axis1.plot(x, y1, label="图1", linestyle="--", color="r")
axis1.set_title('Dataset 1')
# axes[0].plot(x, y1, label="图1", linestyle="--", color="r")
# axes[1].bar(x, y2, label="图2")
# 在第二个坐标系中显示第二个数据集的条形图
axis2.bar(x, y2, label="图2")
axis2.set_title('Dataset 2')
# 添加x,y轴刻度
x_ticks_label = ["{}组".format(i) for i in x]
y_ticks = range(15)
axis1.set_xticks(x,x_ticks_label)
axis1.set_yticks(y_ticks)
# 添加网格显示
axis1.grid(True, linestyle="--", alpha=0.5)
# 添加x,y轴描述和标题
axis1.set_xlabel("分组")
axis1.set_ylabel("数量")
axis1.set_title("分组与数量间的示意图", fontsize=25)
# 显示图例
axis1.legend(loc=0)
axis2.legend(loc=0)
# 显示图像
plt.show()