python基础教程之Matplotlib 画图

心动时间很短,心碎却要很长时间

Posted by yishuifengxiao on 2021-05-26

image-20210527150842305

Matplotlib图像结构

一 基本使用

1.创建画布 — plt.figure()

1
2
3
4
plt.figure(figsize=(), dpi=) 
figsize:指定图的长宽
dpi:图像的清晰度
返回:fig对象

2.绘制图像 — plt.plot(x, y)

以折线图为例

3.显示图像 — plt.show()

1.1 绘制折线图

示例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt
import matplotlib as mpl

# 创建画布为非必须
# 1 创建画布
plt.figure(figsize=(20, 20), dpi=100)
# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 2 绘制折线图
plt.plot([1, 2, 3, 4, 5, 6, 7], [17, 17, 18, 15, 11, 11, 13])

# 显示图像
plt.show()

运行结果如下

image-20210527150652061

取消创建画布步骤,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt
import matplotlib as mpl

# 创建画布为非必须
# 1 创建画布
# plt.figure(figsize=(20, 20), dpi=100)
# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 2 绘制折线图
plt.plot([1, 2, 3, 4, 5, 6, 7], [17, 17, 18, 15, 11, 11, 13])

# 显示图像
plt.show()

结果如下

image-20210527150758249

1.2 绘制正弦图

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

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 0.准备数据
x = np.linspace(-10, 10, 1000)
y = np.sin(x)

# 1.创建画布 plt.figure(figsize=(20, 8), dpi=100)

# 2.绘制函数图像
plt.plot(x, y)

# 2.1 添加网格显示
plt.grid()

# 3.显示图像
plt.show()

image-20210527154157169

二 添加辅助功能

为了更好地理解所有基础绘图功能,我们通过天气温度变化的绘图来融合所有的基础API使用

需求:画出某城市11点到121小时内每分钟的温度变化折线图,温度范围在15~18

效果:

image-20210527151134739

2.1 画出初始折线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib as mpl
import matplotlib.pyplot as plt
import random

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 画出温度变化图 # 0.准备x, y坐标的数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
# 1.创建画布
# plt.figure(figsize=(20, 8), dpi=80)
# 2.绘制折线图
plt.plot(x, y_shanghai)
# 3.显示图像
plt.show()

image-20210527151432250

2.2 添加自定义刻度

API如下

1
2
3
plt.xticks(x, **kwargs)     #x:要显示的刻度值 

plt.yticks(y, **kwargs) #y:要显示的刻度值

修改后的代码如下

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 matplotlib as mpl
import matplotlib.pyplot as plt
import random

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 画出温度变化图 # 0.准备x, y坐标的数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
# 1.创建画布
# plt.figure(figsize=(20, 8), dpi=80)
# 2.绘制折线图
plt.plot(x, y_shanghai)

# 构造x轴刻度标签
x_ticks_label = ["11点{}分".format(i) for i in x]
# 构造y轴刻度
y_ticks = range(40)

# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])

# 3.显示图像
plt.show()

image-20210527151828538

2.3 添加网格显示

为了更加清楚地观察图形对应的值

1
plt.grid(True, linestyle='--', alpha=0.5)

代码如下

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 as mpl
import matplotlib.pyplot as plt
import random

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 画出温度变化图 # 0.准备x, y坐标的数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
# 1.创建画布
# plt.figure(figsize=(20, 8), dpi=80)
# 2.绘制折线图
plt.plot(x, y_shanghai)

# 构造x轴刻度标签
x_ticks_label = ["11点{}分".format(i) for i in x]
# 构造y轴刻度
y_ticks = range(40)

# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])

# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)

# 3.显示图像
plt.show()

image-20210527152039785

2.4 添加描述信息

添加x轴、y轴描述信息及标题

通过fontsize参数可以修改图像中字体的大小

1
2
3
plt.xlabel("时间") 
plt.ylabel("温度")
plt.title("中午11点0分到12点之间的温度变化图示", fontsize=20)

代码如下

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
31
32
33
34
35
import matplotlib as mpl
import matplotlib.pyplot as plt
import random

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 画出温度变化图 # 0.准备x, y坐标的数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
# 1.创建画布
# plt.figure(figsize=(20, 8), dpi=80)
# 2.绘制折线图
plt.plot(x, y_shanghai)

# 构造x轴刻度标签
x_ticks_label = ["11点{}分".format(i) for i in x]
# 构造y轴刻度
y_ticks = range(40)

# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])

# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)

# 添加x轴、y轴描述信息及标题
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点0分到12点之间的温度变化图示", fontsize=20)

# 3.显示图像
plt.show()

image-20210527152254848

2.5 图像保存

1
2
# 保存图片到指定路径
plt.savefig("test.png")

注意:plt.show()会释放figure资源,如果在显示图像之后保存图片将只能保存空图片

三 在一个坐标系中绘制多个图像

3.1 多次plot

需求:再添加一个城市的温度变化

收集到北京当天温度变化情况,温度在1度到3度。怎么去添加另一个在同一坐标系当中的不同图形,其实很简单只需要再次plot即可,但是需

要区分线条,如下显示

image-20210527152610585

1
2
3
4
5
6
# 增加北京的温度数据 
y_beijing = [random.uniform(1, 3) for i in x]
# 绘制折线图
plt.plot(x, y_shanghai)
# 使用多次plot可以画多个折线
plt.plot(x, y_beijing, color='r', linestyle='--')

代码如下

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
31
32
33
34
35
36
37
38
39
40
41
import matplotlib as mpl
import matplotlib.pyplot as plt
import random

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 画出温度变化图 # 0.准备x, y坐标的数据
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=80)
# 2.绘制折线图

# 绘制折线图
plt.plot(x, y_shanghai)
# 使用多次plot可以画多个折线
plt.plot(x, y_beijing, color='r', linestyle='--')

# 构造x轴刻度标签
x_ticks_label = ["11点{}分".format(i) for i in x]
# 构造y轴刻度
y_ticks = range(40)

# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])

# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)

# 添加x轴、y轴描述信息及标题
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点0分到12点之间的温度变化图示", fontsize=20)

# 3.显示图像
plt.show()

image-20210527152814951

3.2 设置图形风格

我们仔细观察,用到了两个新的地方,一个是对于不同的折线展示效果,一个是添加图例。

颜色字符 风格字符
r 红色 - 实线
g 绿色 - - 虚线
b 蓝色 -. 点划线
w 白色 : 点虚线
c 青色 ‘ ‘ 留空、空格
m 洋红
y 黄色
k 黑色

3.3 显示图例

如果只在plt.plot()中设置label还不能最终显示出图例,还需要通过plt.legend()将图例显示出来

1
2
3
4
5
6
# 绘制折线图 
plt.plot(x, y_shanghai, label="上海")
# 使用多次plot可以画多个折线
plt.plot(x, y_beijing, color='r', linestyle='--', label="北京")
# 显示图例
plt.legend(loc="best")
Location String Location Code
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
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
31
32
33
34
35
36
37
38
39
40
41
42
43
import matplotlib as mpl
import matplotlib.pyplot as plt
import random

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 画出温度变化图 # 0.准备x, y坐标的数据
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=80)
# 2.绘制折线图

# 绘制折线图
plt.plot(x, y_shanghai, label="上海")
# 使用多次plot可以画多个折线
plt.plot(x, y_beijing, color='r', linestyle='--', label="北京")
# 显示图例
plt.legend(loc="best")

# 构造x轴刻度标签
x_ticks_label = ["11点{}分".format(i) for i in x]
# 构造y轴刻度
y_ticks = range(40)

# 修改x,y轴坐标的刻度显示
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])

# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)

# 添加x轴、y轴描述信息及标题
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点0分到12点之间的温度变化图示", fontsize=20)

# 3.显示图像
plt.show()

image-20210527153816176

四 常见图形绘制

4.1 折线图

折线图:以折线的上升或下降来表示统计数量的增减变化的统计图

特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)

1
plt.plot(x, y)

4.2 散点图

用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。

特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)

1
plt.scatter(x, y)

需求:探究房屋面积和房屋价格的关系

房屋面积数据:

x = [225.98, 247.07, 253.14, 457.85, 241.58, 301.01, 20.67, 288.64,

163.56, 120.06, 207.83, 342.75, 147.9 , 53.06, 224.72, 29.51,

21.61, 483.21, 245.25, 399.25, 343.35]

房屋价格数据:

y = [196.63, 203.88, 210.75, 372.74, 202.41, 247.61, 24.9 , 239.34,

140.32, 104.15, 176.84, 288.23, 128.79, 49.64, 191.74, 33.1 ,

30.74, 400.02, 205.35, 330.64, 283.45]

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

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 1 准备数据
x = [225.98, 247.07, 253.14, 457.85, 241.58, 301.01, 20.67, 288.64, 163.56, 120.06, 207.83, 342.75, 147.9, 53.06,
224.72, 29.51, 21.61, 483.21, 245.25, 399.25, 343.35]
y = [196.63, 203.88, 210.75, 372.74, 202.41, 247.61, 24.9, 239.34, 140.32, 104.15, 176.84, 288.23, 128.79, 49.64,
191.74, 33.1, 30.74, 400.02, 205.35, 330.64, 283.45]

# 2 绘制散点图
plt.scatter(x, y)

# 2.1 添加网格显示
plt.grid()

# 3.显示图像
plt.show()

image-20210527154958075

4.3 柱状图

柱状图:排列在工作表的列或行中的数据可以绘制到柱状图中。

特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计/对比)

1
2
3
4
5
6
plt.bar(x, width, align='center', **kwargs) 

x : 需要传递的数据
width : 柱状图的宽度
align : 每个柱状图的位置对齐方式 {‘center’, ‘edge’}, optional, default: ‘center’
**kwargs : color:选择柱状图的颜色

需求-对比每部电影的票房收入

image-20210527155032213

电影数据如下图所示:

image-20210527155106944

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

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

# 1 准备数据
# 电影名字
movie_name = ['雷神3:诸神黄昏', '正义联盟', '东方快车谋杀案', '寻梦环游记', '全球风暴', '降魔传', '追捕', '七十七天', '密战', '狂兽', '其它']
# 横坐标
x = range(len(movie_name))
# 票房数据
y = [73853, 57767, 22354, 15969, 14839, 8725, 8716, 8318, 7916, 6764, 52222]

# 2.绘制柱状图
plt.bar(x, y, width=0.5, color=['b', 'r', 'g', 'y', 'c', 'm', 'y', 'k', 'c', 'g', 'b'])

# 2.1b修改x轴的刻度显示
plt.xticks(x, movie_name)

# 2.1 添加网格显示
plt.grid()

# 3.显示图像
plt.show()

image-20210527155317167

4.4 直方图

由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据范围,纵轴表示分布情况。

特点:绘制连续性的数据展示一组或者多组数据的分布状况(统计)

1
2
3
4
matplotlib.pyplot.hist(x, bins=None) 

x : 需要传递的数据
bins : 组距

4.5 饼图

用于表示不同分类的占比情况,通过弧度大小来对比各种分类。

特点:分类数据的占比情况(占比)

1
2
3
4
5
6
api:plt.pie(x, labels=,autopct=,colors) 

x:数量,自动算百分比
labels:每部分名称
autopct:占比显示指定%1.2f%%
colors:每部分颜色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

label = ['第一', '第二', '第三'] # 定义饼图的标签,标签是列表
explode = [0.01, 0.01, 0.01] # 设定各项距离圆心n个半径
# plt.pie(values[-1,3:6],explode=explode,labels=label,autopct='%1.1f%%')#绘制饼图
values = [4, 7, 9]
plt.pie(values, explode=explode, labels=label, autopct='%1.1f%%') # 绘制饼图
plt.title('2018年饼图') # 绘制标题

# 3.显示图像
plt.show()

image-20210527155735291

explode作为一个难理解的指标,我们改变一下,看一下有什么变化

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

# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False

label = ['第一', '第二', '第三'] # 定义饼图的标签,标签是列表
explode = [0.01, 0.2, 0.01] # 设定各项距离圆心n个半径
# plt.pie(values[-1,3:6],explode=explode,labels=label,autopct='%1.1f%%')#绘制饼图
values = [4, 7, 9]
plt.pie(values, explode=explode, labels=label, autopct='%1.1f%%') # 绘制饼图
plt.title('2018年饼图')
plt.savefig('./2018年饼图')
plt.show()

image-20210527155719206