机器学习 Day02,matplotlib库绘图
1.matplotlib图像结构
- 容器层:画板,画布,坐标系
- 辅助层:刻度,标题,网格,图例等
- 图像层:折线图(主讲),饼图,直方图,柱状图等等
2.基本画图框架
matplotlib.pyplot
模块。这是 Python 中一个用于数据可视化的强大模块,其中的函数与 Matlab 的绘图函数类似,方便易用,一般通过 import matplotlib.pyplot as plt
导入。
以下是使用 matplotlib.pyplot
绘图的标准流程:
创建画布:使用 plt.figure()
函数创建一个空白画布,如需自定义画布大小和分辨率,可这样写:
import matplotlib.pyplot as plt
# 创建一个宽为8英寸,高为6英寸,分辨率为100dpi的画布
fig = plt.figure(figsize=(8, 6), dpi=100)
绘制图像:以折线图为例,假设我们有一组数据,使用 plt.plot()
函数进行绘制:
显示图像:使用 plt.show()
函数展示绘制好的图像
比如要展示上海一周的天气温度,代码如下:
import matplotlib.pyplot as plt
# 创建画布,宽和高都设为10英寸,分辨率100dpi
plt.figure(figsize=(10, 10), dpi=100)
# 横坐标表示周一到周日
week_days = [1, 2, 3, 4, 5, 6 ,7]
# 纵坐标表示对应每天的温度
temperatures = [17,17,18,15,11,11,13]
# 绘制折线图
plt.plot(week_days, temperatures)
# 显示图像
plt.show()
3.基本修饰
3.1图的刻度
3.1.1准备数据并绘制初始折线图:如第二张图代码所示,先导入matplotlib.pyplot
和random
模块。通过range(60)
生成表示 60 分钟的横坐标数据x
,使用random.uniform(15, 18)
生成 15 到 18 度之间的随机温度数据y_shanghai
作为纵坐标。接着创建一个宽 20 英寸、高 8 英寸、分辨率 100dpi 的画布,再用plt.plot(x, y_shanghai)
绘制折线图。
import matplotlib.pyplot as plt
import random
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
plt.figure(figsize=(20, 8), dpi=100)
plt.plot(x, y_shanghai)
3.1.2添加 x,y 轴刻度
3.1.2.1生成刻度标签数据:如第三张图代码,对于 x 轴刻度标签,使用列表推导式["11点{}分".format(i) for i in x]
生成从 “11 点 0 分” 到 “11 点 59 分” 的标签列表x_ticks_label
;对于 y 轴刻度,简单使用range(40)
生成从 0 到 39 的刻度值y_ticks
。
x_ticks_label = ["11点{}分".format(i) for i in x]
y_ticks = range(40)
3.1.2.2设置刻度显示 :在 Matplotlib 中不能直接用字符串修改坐标刻度,需同时传入刻度位置和对应的标签。plt.xticks(x[::5], x_ticks_label[::5])
表示每隔 5 个数据点设置一个 x 轴刻度标签,这样能避免刻度标签过于密集;plt.yticks(y_ticks[::5])
表示每隔 5 个刻度值显示一个 y 轴刻度。
可以理解为第一个参数表示隔多少取一个刻度,而第二个参数表示显示什么和第一个参数意义对应。
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])
3.1.3显示图像
plt.show()
注意,这个库中想要显示中文字体要进行如下操作
from pylab import mpl # 设置显示中文字体为黑体 mpl.rcParams["font.sans-serif"] = ["SimHei"] # 设置正常显示符号 mpl.rcParams["axes.unicode_minus"] = False
3.2 添加网格线和标题坐标轴
3.2.1. 添加网格显示
使用plt.grid()
函数可以为图形添加网格,方便更清晰地观察图形对应的值。以下是示例代码:
import matplotlib.pyplot as plt
import random
# 准备数据
x = range(60)
y = [random.uniform(15, 18) for _ in x]
# 创建画布
plt.figure(figsize=(10, 6), dpi=100)
# 绘制折线图
plt.plot(x, y)
# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)
# True表示显示网格;linestyle='--'设置网格线为虚线;alpha=0.5设置网格线透明度为0.5
# 显示图像
plt.show()
在上述代码中,首先导入必要的模块,然后生成模拟的时间和温度数据。创建画布并绘制折线图后,通过plt.grid()
函数添加网格,按照第一张图中的参数设置,让网格以虚线形式、50% 的透明度显示在图形上。
3.2.2. 添加描述信息
使用plt.xlabel()
、plt.ylabel()
和plt.title()
函数分别为图形添加 x 轴标签、y 轴标签和标题,同时可以通过fontsize
参数调整字体大小。示例代码如下:
import matplotlib.pyplot as plt
import random
# 准备数据
x = range(60)
y = [random.uniform(15, 18) for _ in x]
# 创建画布
plt.figure(figsize=(10, 6), dpi=100)
# 绘制折线图
plt.plot(x, y)
# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)
# 添加描述信息
plt.xlabel("时间", fontsize=12) # 添加x轴标签并设置字体大小为12
plt.ylabel("温度", fontsize=12) # 添加y轴标签并设置字体大小为12
plt.title("中午11点0分到12点之间的温度变化图示", fontsize=20)
# 添加标题并设置字体大小为20
# 显示图像
plt.show()
3.3 图片保存
import matplotlib.pyplot as plt
import random
# 准备数据
x = range(60)
y = [random.uniform(15, 18) for _ in x]
# 创建画布
plt.figure(figsize=(10, 6), dpi=100)
# 绘制折线图
plt.plot(x, y)
# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)
# 添加描述信息
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点到12点温度变化图")
# 保存图像,指定保存路径和文件名,这里保存在当前目录下为test.png
plt.savefig("test.png")
# 显示图像
plt.show()
- 保存图像的方法:使用
plt.savefig()
函数可以将绘制好的图像保存到指定路径。如代码plt.savefig("test.png")
,表示将图像以test.png
文件名保存,文件格式为 PNG。你可以根据需要修改文件名和路径,如plt.savefig("C:/images/weather_chart.jpg")
,将图像保存到 C 盘的 images 文件夹下,格式为 JPEG。 - 注意事项:
plt.show()
会释放figure
资源,如果先执行plt.show()
再保存图片,保存的将是一张空图片。因此,建议在调用plt.show()
之前先调用plt.savefig()
保存图像。
4.一张图绘制多个图像,添加图例
import matplotlib.pyplot as plt
import random
# 准备横坐标数据,表示11点到12点的60分钟
x = range(60)
# 准备上海的温度数据,在15到18度之间随机取值
y_shanghai = [random.uniform(15, 18) for _ in x]
# 准备北京的温度数据,在1到3度之间随机取值
y_beijing = [random.uniform(1, 3) for _ in x]
# 创建画布
plt.figure(figsize=(10, 6), dpi=100)
# 绘制上海的温度变化折线图
plt.plot(x, y_shanghai, label='上海')
# 绘制北京的温度变化折线图,设置颜色为红色,线条样式为虚线
plt.plot(x, y_beijing, color='r', linestyle='--', label='北京')
# 添加网格显示,方便观察数据
plt.grid(True, linestyle='--', alpha=0.5)
# 添加x轴、y轴标签和标题
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点到12点城市温度变化图")
# 添加图例,显示每条折线对应的城市名称
plt.legend()
# 保存图像
plt.savefig("city_temperature.png")
# 显示图像
plt.show()
- 导入模块:开头导入
matplotlib.pyplot
用于绘图,random
用于生成随机温度数据。 - 数据准备:分别生成表示 60 分钟的横坐标数据
x
,以及上海和北京的温度数据y_shanghai
、y_beijing
,这些数据都是随机生成的模拟值。 - 创建画布:使用
plt.figure()
创建一个指定大小和分辨率的画布。 - 绘制图像:
- 第一次调用
plt.plot()
绘制上海的温度变化折线图,并通过label
参数设置标签为 “上海”。 - 第二次调用
plt.plot()
绘制北京的温度变化折线图,通过color
参数设置线条颜色为红色,linestyle
参数设置线条样式为虚线,同时也设置了label
为 “北京”,方便后续添加图例。
- 第一次调用
- 添加辅助元素:
- 使用
plt.grid()
添加网格,使图形数据更易观察。 - 使用
plt.xlabel()
、plt.ylabel()
和plt.title()
分别添加 x 轴标签、y 轴标签和标题。 - 使用
plt.legend()
添加图例,根据之前plot
函数中设置的label
,自动显示每条折线对应的城市名称。
- 使用
- 保存和显示图像:先使用
plt.savefig()
保存图像,再使用plt.show()
显示图像,注意保存要在显示之前,避免保存到空图。
显示图例函数
plt.legend()
函数,用于在 Matplotlib 绘制的图形中显示图例:
- 基本作用:当在一个坐标系中绘制多个图形时,
plt.legend()
能根据plt.plot()
等绘图函数中设置的label
参数,展示每个图形对应的标签说明,方便区分不同图形代表的数据 。 - 使用方法:
- 首先在绘图函数(如
plt.plot()
)中通过label
参数为图形设置标签,例如plt.plot(x, data1, label="数据1")
、plt.plot(x, data2, label="数据2")
。 - 然后调用
plt.legend()
显示图例。若仅写plt.legend()
,会使用默认设置显示图例;若要指定图例位置,可使用loc
参数,如plt.legend(loc="best")
让系统自动选最佳位置,loc
还支持多种取值,图片中的表格列出了位置字符串(如'upper right'
)和对应的位置代码(如1
)。
- 首先在绘图函数(如
- 注意事项:只在
plt.plot()
中设置label
不能直接显示图例,必须调用plt.legend()
才能将图例呈现在图形上。
至此画一个简单的图已经完善,这是完整代码:
import matplotlib.pyplot as plt
import random
# 0.准备数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
y_beijing = [random.uniform(1, 3) for i in x]
# 1.创建画布
plt.figure(figsize=(20, 8), dpi=100)
# 2.绘制图像
plt.plot(x, y_shanghai, label="上海")
plt.plot(x, y_beijing, color="r", linestyle="--", label="北京")
# 2.1 添加x,y轴刻度
# 构造x,y轴刻度标签
x_ticks_label = ["11点{}分".format(i) for i in x]
y_ticks = range(40)
# 刻度显示
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])
# 2.2 添加网格显示
plt.grid(True, linestyle="--", alpha=0.5)
# 2.3 添加描述信息
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点--12点某城市温度变化图", fontsize=20)
# 2.4 添加图例
plt.legend(loc=0)
# 2.5 图像保存
plt.savefig("./test.png")
# 3.图像显示
plt.show()
5.多个坐标系显示多个图
其实差不多,只不过是调用对象不一样,调用的方法有差别。
- 当需要将多个数据可视化结果展示在同一幅图的不同坐标系中时,可使用
plt.subplots
函数。如想同时展示上海和北京中午 11 点到 12 点的天气温度变化图,就可利用该函数。 - 函数介绍:
matplotlib.pyplot.subplots(nrows=1, ncols=1, **fig_kw)
,其中nrows
和ncols
用于设置子图的行数和列数,默认都为 1;该函数返回两个值,fig
代表整个图像对象,axes
返回相应数量的坐标系对象。所以需要两个变量去接收,之后可以用axes这个变量当做每个子图去使用,见代码。 - axes数组表示方法:
axes
数组的索引从 0 开始,通过axes[row_index, col_index]
来定位特定的子坐标系,其中row_index
是行索引,col_index
是列索引。例如:axes[0, 0]
:表示第 1 行第 1 列的子坐标系。axes[0, 1]
:表示第 1 行第 2 列的子坐标系。axes[1, 0]
:表示第 2 行第 1 列的子坐标系。axes[1, 1]
:表示第 2 行第 2 列的子坐标系。 - 设置方法差异:相比之前直接用
plt
的方式,面向对象的方法中设置坐标轴刻度、标签等需通过axes
对象的方法,如set_xticks
(设置 x 轴刻度)、set_xlabel
(设置 x 轴标签)等。 - 代码示例讲解:
- 创建画布:
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)
,创建了一个包含 1 行 2 列子图的画布,宽 20 英寸,高 8 英寸,分辨率 100dpi,fig
为整个图像对象,axes
是包含两个子坐标系对象的数组。 - 绘制图像:通过
axes[0].plot(x, y_shanghai, label="上海")
在第一个子坐标系绘制上海温度变化图 ;axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")
在第二个子坐标系绘制北京温度变化图。
- 创建画布:
import matplotlib.pyplot as plt
import random
# 准备数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
y_beijing = [random.uniform(1, 3) for i in x]
# 创建画布
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)
# 绘制图像
axes[0].plot(x, y_shanghai, label="上海")
axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")
# 为第一个子图添加辅助元素
axes[0].set_title("上海中午11点--12点温度变化图")
axes[0].set_xlabel("时间")
axes[0].set_ylabel("温度")
axes[0].grid(True, linestyle="--", alpha=0.5)
axes[0].legend()
# 为第二个子图添加辅助元素
axes[1].set_title("北京中午11点--12点温度变化图")
axes[1].set_xlabel("时间")
axes[1].set_ylabel("温度")
axes[1].grid(True, linestyle="--", alpha=0.5)
axes[1].legend()
# 显示图像
plt.show()
但是这里注意在显示刻度的时候有一个差别,它不能像唯一一个图一样用两个参数去做,而需要拆分为两个函数
这是一个图 这是多个图:
import matplotlib.pyplot as plt
import random
# 准备横坐标数据,表示11点到12点的60分钟
x = range(60)
# 准备上海的温度数据,在15到18度之间随机取值
y_shanghai = [random.uniform(15, 18) for _ in x]
# 准备北京的温度数据,在1到3度之间随机取值
y_beijing = [random.uniform(1, 3) for _ in x]
# 创建2×1的子图布局
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(10, 8))
# 绘制图像
axes[0].plot(x, y_shanghai, label="上海")
axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")
# 2.1 添加x,y轴刻度
# 设置x,y轴刻度
x_ticks_label = ["11点{}分".format(i) for i in x]
y_ticks = range(40)
# 修改x,y轴坐标刻度显示
axes[0].set_xticks(x[::5]) # 为第一个子坐标系的x轴每隔5个数据点设置一个刻度
axes[0].set_yticks(y_ticks[::5]) # 为第一个子坐标系的y轴每隔5个刻度值设置一个刻度
axes[0].set_xticklabels(x_ticks_label[::5]) # 为第一个子坐标系的x轴刻度设置对应标签,每隔5个刻度显示一个
axes[1].set_xticks(x[::5]) # 为第二个子坐标系的x轴每隔5个数据点设置一个刻度
axes[1].set_yticks(y_ticks[::5]) # 为第二个子坐标系的y轴每隔5个刻度值设置一个刻度
axes[1].set_xticklabels(x_ticks_label[::5]) # 为第二个子坐标系的x轴刻度设置对应标签,每隔5个刻度显示一个
# 显示图像
plt.show()
- 对于第一个子坐标系(
axes[0]
):axes[0].set_xticks(x[::5])
:设置 x 轴刻度位置,每隔 5 个数据点显示一个刻度 ,x[::5]
表示从x
中每隔 5 个元素取一个。axes[0].set_yticks(y_ticks[::5])
:设置 y 轴刻度位置,每隔 5 个刻度值显示一个刻度 ,y_ticks[::5]
表示从y_ticks
中每隔 5 个元素取一个。axes[0].set_xticklabels(x_ticks_label[::5])
:设置 x 轴刻度标签,与set_xticks
配合,每隔 5 个刻度显示对应的标签。
- 对于第二个子坐标系(
axes[1]
):axes[1].set_xticks(x[::5])
、axes[1].set_yticks(y_ticks[::5])
、axes[1].set_xticklabels(x_ticks_label[::5])
:作用与在axes[0]
中的设置类似,分别设置第二个子坐标系的 x 轴刻度位置、y 轴刻度位置以及 x 轴刻度标签 。
这是整体代码:
import matplotlib.pyplot as plt
import random
# 0. 准备数据
# 生成表示60分钟的时间序列,作为横坐标数据
x = range(60)
# 生成上海的温度数据,每个数据在15到18度之间随机取值
y_shanghai = [random.uniform(15, 18) for i in x]
# 生成北京的温度数据,每个数据在1到3度之间随机取值
y_beijing = [random.uniform(1, 3) for i in x]
# 1. 创建画布
# 创建一个1行2列的子图布局,设置画布大小为宽20英寸,高8英寸,分辨率为100dpi
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)
# 2. 绘制图像
# 在第一个子坐标系中绘制上海的温度变化折线图,并添加标签
axes[0].plot(x, y_shanghai, label="上海")
# 在第二个子坐标系中绘制北京的温度变化折线图,设置颜色为红色,线条样式为虚线,并添加标签
axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")
# 2.1 添加x,y轴刻度
# 构造x轴刻度标签,格式为“11点几分”
x_ticks_label = ["11点{}分".format(i) for i in x]
# 生成y轴刻度值,范围是0到39
y_ticks = range(40)
# 修改x,y轴坐标刻度显示
# 为第一个子坐标系的x轴每隔5个数据点设置一个刻度
axes[0].set_xticks(x[::5])
# 为第一个子坐标系的y轴每隔5个刻度值设置一个刻度
axes[0].set_yticks(y_ticks[::5])
# 为第一个子坐标系的x轴刻度设置对应标签,每隔5个刻度显示一个
axes[0].set_xticklabels(x_ticks_label[::5])
# 为第二个子坐标系的x轴每隔5个数据点设置一个刻度
axes[1].set_xticks(x[::5])
# 为第二个子坐标系的y轴每隔5个刻度值设置一个刻度
axes[1].set_yticks(y_ticks[::5])
# 为第二个子坐标系的x轴刻度设置对应标签,每隔5个刻度显示一个
axes[1].set_xticklabels(x_ticks_label[::5])
# 2.2 添加网格显示
# 为第一个子坐标系添加虚线网格,不透明度为1(完全不透明)
axes[0].grid(True, linestyle="--", alpha=1)
# 为第二个子坐标系添加虚线网格,不透明度为1(完全不透明)
axes[1].grid(True, linestyle="--", alpha=1)
# 2.3 添加描述信息
# 为第一个子坐标系设置x轴标签为“时间”
axes[0].set_xlabel("时间")
# 为第一个子坐标系设置y轴标签为“温度”
axes[0].set_ylabel("温度")
# 为第一个子坐标系设置标题为“中午11点-12点某城市温度变化图”,字体大小为20
axes[0].set_title("中午11点-12点某城市温度变化图", fontsize=20)
# 为第二个子坐标系设置x轴标签为“时间”
axes[1].set_xlabel("时间")
# 为第二个子坐标系设置y轴标签为“温度”
axes[1].set_ylabel("温度")
# 为第二个子坐标系设置标题为“中午11点-12点某城市温度变化图”,字体大小为20
axes[1].set_title("中午11点-12点某城市温度变化图", fontsize=20)
# 2.4 显示图例
# 在第一个子坐标系中显示图例,位置自动选择最佳
axes[0].legend(loc=0)
# 在第二个子坐标系中显示图例,位置自动选择最佳
axes[1].legend(loc=0)
# 2.5 图像保存
# 将绘制好的图像保存为当前目录下的test.png文件
plt.savefig("./test.png")
# 3. 图像显示
# 显示绘制好的图形
plt.show()
6.对于其他图只是创建时把plot改一下并且后面参数对应即可,自己可查
记一下:
plt.figure(figsize=(长,宽),dpi=清晰度)创建画布
plt.plot(x,y)
plt.x/yticks()掌控刻度,不可直接中文
plt.x/ylable()掌握坐标标题
plt.title()掌握标题
plt.grid(True,linestyle="样式",alpha=透明度)掌握网格线
plt.legend(loc="")掌握图例,在plot里加lable
plt.show()展示