Matplotlib库

Matplotlib是一个python的2D绘图库,通过它可以生成绘图,直方图,功率谱,条形图,错误图,散点图等。可以让数据可视化,使数据更加客观,具体。

安装matplotlib库

1
pip install matplotlib

基本绘制

使用matplotlib绘制图形使,画点和画线是最常用的两个场景。

pyplot基本方法

image-20210408160923468

绘制直线

1.导入模块pyplot,在模块pyplot中包含很多用于生产图表的函数。

2.将绘制的直线坐标传递给函数plot().

3.通过函数plt.show()打开Matplotlib查看器,显示绘制的图形。

例:根据两点绘制一条直线

1
2
3
4
5
6
7
8
9
10
# 导入matplotlib模块
import matplotlib.pyplot as plt

# 准备绘制的点
x = [1, 2, 3, 4, 5]
y = [1, 3, 5, 7, 9]
# 调用绘制方法
plt.plot(x, y)
# 显示绘制图形
plt.show()

设置标签文字和线条粗细

开发者可以设置线条的粗细,设置文字等。

例:绘制折线图并设置样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 导入matplotlib模块
import matplotlib.pyplot as plt

# 准备绘制的点x,y
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]
# 调用绘制方法绘制折线图
# linewidth属性设置线条宽度
plt.plot(x, y, linewidth=5)
# 添加x,y轴名称
plt.xlabel("x")
plt.ylabel("y=x^2")
plt.rcParams["font.sans-serif"] = ["SimHei"] # 用来正常显示中文标签
# 给图表添加标题
plt.title("多个点绘制折线图")
# 显示绘制图形
plt.show()

matplotlib默认不支持中文,可以使用方法来解决显示中文:

1
plt.rcParams["font.sans-serif"] = ["SimHei"] 

绘制一元二次方程的曲线y=x^2

Matplotlib中plot函数用来绘制曲,需要将200个点的x坐标和y坐标分别以序列的形式传入plot函数,然后调用show函数显示绘制图形。

例:一元二次方程的曲线

1
2
3
4
5
6
7
8
9
10
11
12
# 导入matplotlib模块
import matplotlib.pyplot as plt

# 准备绘制的200个点x坐标
x = range(-100, 100)
y = [i**2 for i in x]
# 绘制一元二次方程
plt.plot(x, y)
# 将图形保存图片
plt.savefig("result") # 默认的格式png,result是图片名
# 显示绘制图形
plt.show()

绘制正弦曲线和余弦曲线

使用plt函数绘制任何曲线都是生成若干个坐标点(x,y),理论上坐标点越多越好。本例取0到10之间100个等差数作为x的坐标,将这100个x坐标值一起传入Mumpy的sin和cos函数,就会得到100个y坐标值,然后可以使用plot函数绘制正弦曲线和余弦曲线。

例:绘制正弦曲线和余弦曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 生成0-10之间 100个等差数
x =np.linspace(0, 10, 100) # 等差数方法
# 绘制正弦曲线
sin_y = np.sin(x)
plt.plot(x, sin_y)
# 绘制余弦曲线
cos_y = np.cos(x)
plt.plot(x, cos_y) # plot两次,两曲线绘画到同一个画布上
# 显示绘制图形
plt.show()

将画布分区

如果想绘制到两张画布中,可以调用subplot()函数将画布分区。

例:将画布分为区域,将图画绘制到画布指定区域

1
2
# 对画布进行分区,将画布分为2行2列,图像绘制到区1
plt.subplot(2, 2, 1)

修改x,y轴坐标大小

1
2
plt.xlim(-5, 15)	# 修改x轴坐标为-5~15
plt.ylim(-2, 2) # 修改y轴坐标为-2~2

绘制散点图

使用scatter函数可以绘制随机点,该函数需要接收x坐标和y坐标的序列。

例:sin函数的散点图

1
2
3
4
5
6
7
8
9
10
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 生成0-10之间 100个等差数
x =np.linspace(0, 10, 100) # 等差数方法
# 生成散点图
plt.scatter(x, np.sin(x))
# 显示绘制图形
plt.show()

使用plot()也可以绘制散点图,最后加字符串o。

1
plt.plot(x, sin_y, "o")	# o表示使用点状

使用plot()绘制图形速度优于scatter(),所以如果画点没有形式差别,可以使用plot画,而如果画点有形式差别(如点的大小或颜色不同)则必须使用scatter()来画。

绘制大小不同颜色不同的散点图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 生成10种大小,100种颜色的散点图
np.random.seed(0) # 使执行多次每次获取的随机数都是一样的
x = np.random.rand(100) # 生成随机100个点
y = np.random.rand(100)
size = np.random.rand(100)*1000
# 生成随机颜色
color = np.random.rand(100)
# 绘制散点图
# scatter中的s数要和x,y标量一样
plt.scatter(x, y, s=size, c=color, alpha=0.7)
# s表示点的大小,c表示点的颜色,alpha表示透明度
# 显示绘制图形
plt.show()

注意:点的个数和颜色的个数要相同;点的个数和点大小的个数可以不同,如果点的个数大于大小的个数,则超出点大小个数的会循环获取大小。

绘制不同样式不同颜色的线条

1
2
3
4
5
6
7
8
9
10
11
12
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 生成0-10之间 100个等差数的x
x =np.linspace(0, 10, 100)
plt.plot(x, x+0, "--r") # --使样式为虚线,r为红色
plt.plot(x, x+1, "-.b")
plt.plot(x, x+2, ":g")
plt.plot(x, x+3, ",k")
plt.plot(x, x+4, "*c")
plt.show()

增加图例:

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

# 生成0-10之间 100个等差数的x
x =np.linspace(0, 10, 100)
# 使用legend()添加图例,给plot方法添加参数label
plt.plot(x, x+0, "--r", label="--r") # --使样式为虚线,r为红色
plt.plot(x, x+1, "-.b", label="-.b")
plt.plot(x, x+2, ":g", label=":g")
plt.plot(x, x+3, ",k", label=",k")
plt.plot(x, x+4, "*c", label="*c")

plt.legend(loc="upper left", fancybox=True, framealpha=0.8, shadow=True, borderpad=1)
# 图例默认位于左上角,可以通过loc进行修改
plt.show()
  • lengend参数:loc图例位置,fancybox边框,framealpha透明度,shadow阴影,borderpad边框宽度

绘制柱状图

可以使用bar函数绘制柱状图,柱状图需要水平的x坐标值,和每个x对应的y坐标值,形成柱状图。柱状图主要用来纵向对比和横向对比。

例:使用bar绘制柱状图,并设置柱的宽度

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

# 创建x,y,x表示年份,y表示年份对应的数量
x = [1990, 1995, 2000, 2005]
y = [1000, 2000, 3000, 4000]
x_label = ["1990年", "1995年", "2000年", "2005年"]
# 调用bar()绘制柱状图
plt.bar(x, y, width=3) # 设置柱体宽度
# 修正中文乱码问题
plt.rcParams["font.sans-serif"] = ["SimHei"]
# 修改x坐标的显示值
plt.xticks(x,x_label)
# 给x坐标,y坐标添加名称
plt.xlabel("年份")
plt.ylabel("数量")
# 给柱状图加标题
plt.title("根据年份数量对比表")
plt.show()

注意:bar函数的宽度不是像素宽度,bar函数会根据二维坐标系的尺寸,以及x坐标值的多少,自动确定每个柱的宽度,width指定的宽度就是这个标准柱宽度的倍数。该参数可以是浮点数或整数。

bar绘制垂直方向柱状图和barh绘制水平方向柱状图

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

# 生成x,y
np.random.seed(0)
x = np.arange(5)
y = np.random.randint(-5, 5, 5)
#将画布分为一行两列,第一区bar画
plt.subplot(1, 2, 1)
plt.bar(x, y, color="blue")
# 在0的位置水平方向添加颜色分界线条
plt.axhline(0, color="blue", linewidth=1)

# 第二个区barh画
# barh 将y和x进行了对换,竖着方向为x轴
plt.subplot(1, 2, 2)
plt.barh(x, y, color="red")
# 在0的位置垂直方向添加颜色分界线条
plt.axvline(0, color="red", linewidth=1)
plt.show()

柱状图正负数值设置不同颜色柱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 生成x,y
np.random.seed(0)
x = np.arange(5)
y = np.random.randint(-5, 5, 5)
#将画布分为一行两列,第一区bar画
plt.subplot(1, 2, 1)
v_bar = plt.bar(x, y, color="blue")

for bar, height in zip(v_bar, y): # zip()使括号内两个属性对应起来
if height > 0:
bar.set(color="green") # set()设置bar属性
# 在0的位置水平方向添加颜色分界线条
plt.axhline(0, color="blue", linewidth=1)
plt.show()

柱状图使用实例

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
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 准备数据
real_names = ["我的姐姐", "哥斯拉大战金刚", "第十一回"]
# 3天内票房数
real_num1 = [2947, 1562, 189]
real_num2 = [2150, 1140, 225]
real_num3 = [2602, 1290, 243]
x = np.arange(len(real_names))
# 绘制柱状图
width = 0.3
plt.bar(x, real_num1, alpha=0.5, width=width, label=real_names[0])
plt.bar([i+width for i in x], real_num2, alpha=0.5, width=width, label=real_names[1])
plt.bar([i+width*2 for i in x], real_num3, alpha=0.5, width=width, label=real_names[2])
# 设置x坐标显示值
plt.rcParams["font.sans-serif"]=["SimHei"]
x_label = ["第{}天".format(i+1) for i in x]
plt.xticks([i+width for i in x], x_label)
# 给y坐标添加名称
plt.ylabel("票房数")
# 添加图例
plt.legend(loc="upper right", fancybox=True, framealpha=0.8, shadow=True, borderpad=1)
plt.show()

绘制饼状图

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
# 导入matplotlib模块
import matplotlib.pyplot as plt

# 准备数据
man = 1733
woman = 1566
man_perc = man/(woman+man)
woman_perc = woman/(woman+man)
# 解决中文乱码,正常显示中文
plt.rcParams["font.sans-serif"]=["SimHei"]
# 添加名称
labels = ["男", "女"]
# 添加颜色
colors = ["blue", 'pink']
# 绘制饼状图
paches, texts, autotexts = plt.pie([man_perc, woman_perc], labels=labels, colors=colors, explode=(0, 0.03), autopct="%0.2f%%")
# 数据要用序列括起来,labels名称,explode分割饼状图,autopct显示百分比
# 设置饼状图中百分比字体颜色
for text in autotexts:
text.set_color("white")
# 设置名称字体颜色
for text in texts:
text.set_color("green")
# 设置字体大小
for text in texts+autotexts:
text.set_fontsize(16)
plt.show()

绘制直方图

直方图与柱状图的分格类似,都是由若干个柱组成,但直方图和柱状图的含义不同,直方图使用来观察分布状态的,而柱状图是用来查看每个x坐标对应的y坐标值的。直方图关注的是分布,不关心具体的值,而柱状图关心的是具体的某个值。

例:使用randn函数生成1000个正太分布的随机数,使用hist函数绘制这1000个随机数的分布状态

1
2
3
4
5
6
7
8
9
10
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 频次直方图,均匀分布,正态分布
# 生成1000个标准的正态分布随机数
x = np.random.randn(1000)
# hist生成直方图,bins修改柱的宽度
plt.hist(x, bins=100)
plt.show()

使用narmal()也可以生成正态分布直方图

1
2
3
4
5
6
7
8
9
10
11
12
13
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 使用np.random.normal()指定期望和均值的正态分布
x = np.random.normal(0, 0.8, 1000) # (期望,均值,个数)
y = np.random.normal(-2, 1, 1000)
z = np.random.normal(3, 2, 1000)
kwargs=dict(bins=100, alpha=0.5) # bins设置柱体宽度,alpha设置透明度(0-1)
plt.hist(x, **kwargs)
plt.hist(y, **kwargs)
plt.hist(z, **kwargs)
plt.show()

绘制等高线图

例:使用pylot绘制等高线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 导入matplotlib模块
import matplotlib.pyplot as plt
import numpy as np

# 创建x,y
x = np.linspace(-10, 10, 100) # 生成等差数
y = np.linspace(-10, 10, 100)
# 计算x,y相交的点(x,y)
X, Y = np.meshgrid(x, y) # meshgrid生成相交点
# 计算Z的坐标
Z = np.sqrt(X**2+Y**2)
plt.contour(X, Y, Z) # 绘制线条的等高线图
plt.contourf(X,Y, Z) # 绘制填充的等高线图
plt.show()

绘制三维图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 导入模块
import matplotlib.pyplot as plt
# 导入3D包
from mpl_toolkits.mplot3d import Axes3D

# 创建X,Y,Z
X = [1, 1, 2, 2]
Y = [3, 4, 4, 3]
Z = [1, 100, 1, 1]
fig = plt.figure() # 返回fig对象
# 创建Axes3D对象
ax = Axes3D(fig)
ax.plot_trisurf(X, Y, Z) # 输入坐标
plt.show()