Matplotlib详细教程(基础介绍,参数调整,绘图教程)
一、初识Matploblib
Matplotlib是Python中的绘图库,类似于MATLAB,可以用来绘制各种静态,动态,交互式的图表。
1.1 安装 Matplotlib
首先需要安装 Matplotlib 库:
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
1.2、Matplotlib 的两种接口风格
Matplotlib 提供了两种主要使用方式,适用于不同场景:
pyplot 接口(类似 MATLAB 风格)
这种方式通过 plt
模块直接调用函数,自动管理图形和子图状态,适合快速绘图和简单场景。
示例:
import matplotlib.pyplot as plt
import numpy as npx = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x)) # 自动创建figure和axes
plt.title("pyplot接口示例")
plt.show()
面向对象接口(OO 风格)
显式创建 Figure
(画布)和 Axes
(子图)对象,通过对象方法操作,适合复杂绘图(如多子图、定制化布局)。
示例:
import matplotlib.pyplot as plt
import numpy as npfig, ax = plt.subplots() # 显式创建figure和axes
ax.plot(x, np.sin(x))
ax.set_title("面向对象接口示例")
fig.show()
区别与选择:简单绘图用 pyplot 更简洁;复杂场景(如多子图联动、自定义坐标轴)必须用 OO 接口,可控性更强。
1.3、Figure 和 Axes 的深度理解
Figure(画布)
- 整个绘图窗口,是所有元素的容器。
- 可通过
figsize=(width, height)
控制大小(单位:英寸),dpi
控制分辨率(默认 100)。
Axes(子图)
一个 Figure 可包含多个 Axes(如 2×2 网格的子图),每个 Axes 是一个独立的绘图区域。
1.4 设置画布大小
在使用matplotlib作图时,会遇到图片显示不全或者图片大小不是我们想要的,这个时候就需要调整画布大小。下例左图为500*500像素,右图为1000*1000像素。
import matplotlib.pyplot as plt# 500 x 500 像素(先宽度 后高度)
# 注意这里的宽度和高度的单位是英寸,1英寸=100像素
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111)
plt.show()
1.5 设置网格线
通过 axes 对象提供的 grid() 方法可以开启或者关闭画布中的网格以及网格的主/次刻度。除此之外,grid() 函数还可以设置网格的颜色、线型以及线宽等属性。
grid(color='b', ls = '-.', lw = 0.25)
grid() 的函数使用格式如下
参数含义如下:
- color:表示网格线的颜色;
- ls:表示网格线的样式;
- lw:表示网格线的宽度;
网格在默认状态下是关闭的,通过调用上述函数,网格会被自动开启,如果只是想开启不带任何样式的网格,可以通过 grid(True) 来实现。
实例如下:
import matplotlib.pyplot as plt
import numpy as np# fig画布;axes子图区域
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
x = np.arange(1, 11)
axes[0].plot(x, x ** 3, 'g', lw=2)
# 开启网格
axes[0].grid(True)
axes[0].set_title('default grid')
axes[1].plot(x, np.exp(x), 'r')
# 设置网格的颜色,线型,线宽
axes[1].grid(color='b', ls='-.', lw=0.25)
axes[1].set_title('custom grid')
axes[2].plot(x, x)
axes[2].set_title('no grid')
fig.tight_layout()
plt.show()
1.6 设置坐标轴
set_xlabel
用字符串列表来设置坐标轴的标签,fontsize
设置轴标签的字体和字号等参数。
import matplotlib.pyplot as plt
import numpy as npfontdict = {'weight': 'normal', 'family': 'Times New Roman', 'size': 20}fig, axes = plt.subplots(1, 1)
x = np.arange(1, 5)
axes.plot(x, np.exp(x))
axes.plot(x, x ** 2)# 设置标题
axes.set_title("Normal scale", fontdict=fontdict)# 设置x、y轴标签
axes.set_xlabel("x axis", fontdict=fontdict)
axes.set_ylabel("y axis", fontdict=fontdict)plt.show()
Matplotlib 可以根据自变量与因变量的取值范围,自动设置 x 轴与 y 轴的数值大小。当然,您也可以用自定义的方式,通过 set_xlim() 和 set_ylim() 对 x、y 轴的数值范围进行设置。
import matplotlib.pyplot as plt
import numpy as npfig, a1 = plt.subplots(1, 1)x = np.arange(1, 10)
a1.plot(x, np.exp(x), 'r')
a1.set_title('exp')
# 设置y轴
a1.set_ylim(0, 4000)
# 设置x轴
a1.set_xlim(0, 8)
plt.show()
1.7 设置刻度和标签
刻度指的是轴上数据点的标记,Matplotlib 能够自动的在 x 、y 轴上绘制出刻度。这一功能的实现得益于 Matplotlib 内置的刻度定位器和格式化器(两个内建类)。在大多数情况下,这两个内建类完全能够满足我们的绘图需求,但是在某些情况下,刻度标签或刻度也需要满足特定的要求,比如将刻度设置为“英文数字形式”或者“大写阿拉伯数字”,此时就需要对它们重新设置。
xticks() 和 yticks() 函数接受一个列表对象作为参数,列表中的元素表示对应数轴上要显示的刻度。如下所示:
ax.set_xticks([2,4,6,8,10])
x 轴上的刻度标记,依次为 2,4,6,8,10。也可以分别通过 set_xticklabels() 和 set_yticklabels() 函数设置与刻度线相对应的刻度标签。
下面示例介绍了刻度和标签的使用方法,其中对标签逆时针旋转了90°:
import matplotlib.pyplot as plt
import numpy as np
import mathx = np.arange(0, math.pi * 2, 0.05)fig, ax = plt.subplots(1, 1, figsize=(10, 6))y = np.sin(x)
ax.plot(x, y)
# 设置x轴标签
ax.set_xlabel('angle')
# ax.set_title('sine')
ax.set_xticks([0, 2, 4, 6])
# 设置x轴刻度标签,并旋转90°
ax.set_xticklabels(['zero', 'two', 'four', 'six'], rotation=90)
# 设置y轴刻度
ax.set_yticks([-1, 0, 1])
plt.show()
1.8 添加图例和标题
图例通过ax.legend或者plt.legend()实现,标题通过ax.set_title()或者plt.title()实现,基本用法如下例所示。
import matplotlib as mplmpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = Falseimport matplotlib.pyplot as plt
import numpy as npfig = plt.figure()
ax = fig.add_subplot(111)
x = np.linspace(-2 * np.pi, 2 * np.pi, 200)
y = np.sin(x)
y1 = np.cos(x)ax.plot(x, y, label=r"$\sin(x)$")
ax.plot(x, y1, label=r"$\cos(x)$")ax.legend(loc="best")
ax.set_title("正弦函数和余弦函数的折线图")plt.show()
调整图例
对于图例,我们还可以通过改变legend()的参数来改变图例的显示位置,展示样式(包括图例的外边框、图例中的文本标签的排列位置和图例的投影效果等方面)。
import matplotlib.pyplot as plt
import numpy as npx = np.arange(0, 2.1, 0.1)
y = np.power(x, 3)
y1 = np.power(x, 2)
y2 = np.power(x, 1)plt.plot(x, y, ls="-", lw=2, label="$x^{3}$")
plt.plot(x, y1, c="r", ls="-", lw=2, label="$x^{2}$")
plt.plot(x, y2, c="y", ls="-", lw=2, label="$x^{1}$")plt.legend(loc="upper left", bbox_to_anchor=(0.05, 0.95),ncol=3, title="power function", shadow=True,fancybox=True)
plt.show()
loc="upper left"
:指定图例的大致位置为左上角。这是一个初始参考位置,实际位置会结合bbox_to_anchor
参数进行调整。
bbox_to_anchor=(0.05, 0.95)
:这是一个关键参数,用于精确调整图例的位置。它接收一个元组(x, y)
,其中的坐标是相对于图表的整个绘图区域(默认是 axes 坐标系,即左下角为 (0,0),右上角为 (1,1))。这里(0.05, 0.95)
表示图例的左上角顶点位于绘图区域水平方向 0.05(5%)、垂直方向 0.95(95%)的位置。
ncol=3
:设置图例中标签的列数为 3 列。如果图例包含多个条目,它们会按 3 列的形式排列,使布局更合理。
title="power function"
:为图例添加标题,标题内容为 “power function”,会显示在图例的上方。
shadow=True
:使图例添加阴影效果,增强图例的立体感和视觉层次感。
fancybox=True
:设置图例的边框为圆角矩形,而默认的是直角矩形。
plt.legend()的位置参数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.9 设置中文显示
Matplotlib 默认不支持中文字体,只支持 ASCII 字符,但中文标注更加符合中国人的阅读习惯。
当直接使用中文时,Matplotlib 绘制的图像会出现中文乱码,如左图所示。通过临时重写配置文件的方法,可以解决 Matplotlib 显示中文乱码的问题,代码如下所示:
import matplotlib.pyplot as pltplt.rcParams["font.sans-serif"] = ["SimHei"] # 设置字体
plt.rcParams["axes.unicode_minus"] = False # 正常显示负号
year = [2017, 2018, 2019, 2020]
people = [20, 40, 60, 70]
# 生成图表
plt.plot(year, people)
plt.xlabel('年份')
plt.ylabel('人口')
plt.title('人口增长')
# 设置纵坐标刻度
plt.yticks([0, 20, 40, 60, 80])
# 设置填充选项:参数分别对应横坐标,纵坐标,纵坐标填充起始值,填充颜色
plt.fill_between(year, people, 20, color='green')
# 显示图表
plt.show()
Windows字体中英文名称对照
中文名称 | 英文名称 |
黑体 | SimHei |
微软雅黑 | Microsoft YaHei |
微软雅黑 | Microsoft YaHei |
新宋体 | NSimSun |
新细明体 | PMingLiU |
细明体 | MingLiU |
标楷体 | DFKai-SB |
仿宋 | FangSong |
楷体 | KaiTi |
仿宋_GB2312 | FangSong_GB2312 |
楷体_GB2312 | KaiTi_GB2312 |
1.10 调整子图布局
在pyplot模块中,调整子图布局的函数主要用subplots_adjust
subplots_adjust函数的功能为调整子图的布局参数。对于没有设置的参数保持不变
用法:
matplotlib.pyplot.subplots_adjust(left=None, bottom=None, \
right=None, top=None, wspace=None, hspace=None)
参数:
left:所有子图整体相对于图像的左外边距,距离单位为图像宽度的比例(小数)。可选参数。浮点数。默认值为0.125。
right:所有子图整体相对于图像的右外边距,距离单位为图像宽度的比例(小数)。可选参数。浮点数。默认值为0.0。
bottom:所有子图整体相对于图像的下外边距,距离单位为图像高度的比例(小数)。可选参数。浮点数。默认值为0.11。
top:所有子图整体相对于图像的上外边距,距离单位为图像高度的比例(小数)。可选参数。浮点数。默认值为0.88。
wspace:子图间宽度内边距,距离单位为子图平均宽度的比例(小数)。浮点数。默认值为0.2。
hspace:子图间高度内边距,距离单位为子图平均高度的比例(小数)。可选参数。浮点数。默认值为0.2。
示例代码:
import matplotlib.pyplot as plt# 原始间距配置
fig, ax = plt.subplots(3, 3)
print(vars(fig.subplotpars))
# 通过subplots_adjust()设置间距配置
plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=0.5, hspace=0.5)
print(vars(fig.subplotpars))
plt.show()
原始
修改间距后(wspace=0.5, hspace=0.5):
二、常用绘图教程
2.1 折线图
plot()函数画出一系列的点,并且用线将它们连接起来。
格式:
# 基础折线图代码格式
plt.plot(x, # x轴数据(数组或列表)y, # y轴数据(数组或列表,与x长度相同)label='曲线名称', # 曲线标签,用于图例显示color='blue', # 线条颜色(支持名称、十六进制码等)linestyle='-', # 线型('-'实线、'--'虚线、':'点线等)linewidth=2, # 线条宽度(数值越大线越粗)marker='o', # 数据点标记('o'圆形、's'正方形等)markersize=5 # 数据点标记的大小
)
看下例子:
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.sans-serif"] = ["SimHei"] # 设置字体
plt.rcParams["axes.unicode_minus"] = False # 正常显示负号
# 生成数据
x = np.linspace(0, 10, 50) # 0到10之间的50个点
y = np.sin(x) # 计算正弦值# 绘制折线图
plt.plot(x, y, color='blue', linewidth=2)# 基本标签
plt.title('简单折线图')
plt.xlabel('X轴')
plt.ylabel('Y轴')# 显示图形
plt.show()
如果需要展示多条线,只需再添加一行plt.plot(x, 其他数据, ...)
即可。
2.2 散点图
只画点,不用线连接起来。
基本格式:
plt.scatter(x, # x轴数据(数组或列表)y, # y轴数据(数组或列表,与x长度相同)s=50, # 散点大小(数值越大点越大)c='blue', # 散点颜色(支持名称、数组映射等)marker='o', # 散点形状('o'圆形、'+'加号等)alpha=0.7, # 透明度(0-1之间,值越小越透明)edgecolors='black', # 散点边缘颜色label='数据点' # 数据标签,用于图例显示
)
示例:
import matplotlib.pyplot as plt
import numpy as npx = np.arange(10)
y = np.random.randn(10)
plt.scatter(x, y, color='red', marker='+')
plt.show()
2.3 直方图
直方图用于统计数据出现的次数或者频率,有多种参数可以调整,见下例:
import matplotlib.pyplot as plt
import numpy as np# 生成示例数据:1000个符合正态分布的随机数
data = np.random.randn(1000)# 绘制直方图
n, bins, patches = plt.hist(x=data, # 要绘制直方图的数据bins=30, # 直方图的分箱数量,越多越精细density=False, # 是否将直方图归一化为概率密度(总和为1)alpha=0.7, # 透明度,0-1之间color='skyblue', # 直方图颜色edgecolor='black' # 直方图边框颜色
)# 添加标题和标签
plt.title('正态分布数据直方图', fontsize=14)
plt.xlabel('数值', fontsize=12)
plt.ylabel('频数', fontsize=12)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
2.4 饼图
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.sans-serif"] = ["SimHei"] # 设置字体
plt.rcParams["axes.unicode_minus"] = False # 正常显示负号
labels = ['苹果', '香蕉', '橙子', '葡萄', '草莓'] # 各部分标签
sizes = [35, 25, 20, 15, 5] # 各部分占比
explode = (0.1, 0, 0, 0, 0) # 突出显示特定部分(这里突出显示第一个部分)# 绘制饼图
plt.pie(x=sizes, # 饼图各部分的数值(会自动计算占比)explode=explode, # 每个部分的偏移量,用于突出显示labels=labels, # 各部分的标签autopct='%1.1f%%', # 显示百分比的格式shadow=True, # 是否添加阴影效果startangle=90, # 饼图的起始角度(0表示从x轴正方向开始)colors=['red', 'yellow', 'orange', 'purple', 'pink'] # 各部分颜色
)# 设置饼图为正圆形(默认可能为椭圆形)
plt.axis('equal')
# 添加标题
plt.title('水果销售占比')
# 显示图形
plt.show()