avatar


1.matplotlib

matplotlib是一款Python的绘图库,用于做数据的可视化图表。

基础用法

我们从一个最简单的图开始。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
# 导入pyplot
from matplotlib import pyplot as plt

# x轴,从1到9
x = range(1,10,1)
# y轴
y = [3,1,4,1,5,9,2,6,5]
# 传入x 和 y,绘制折线图
plt.plot(x,y)
# 展示图形
plt.show()

运行结果:
最简单图形

当然,除了这些,还有更多的方法,我们介绍几个常用的方法。

设置图片大小

1
plt.figure(figsize=(20,20),dpi=80)

参数:

  • figsize:长和宽
  • dpi:清晰度

保存图片

1
plt.savefig('test.png')

特别注意:保存图片的方法必须在plt.plot(x,y)之后,同时在plt.show()之前。

  1. 肯定要先画图,所以要在plt.plot()之后。
  2. plt.show()后,实际上已经创建了一个新的空白的图片,这时候plt.savefig()就会保存这个新生成的空白图片。所以要在plt.show()之前。

或者,我们也可以用plt.gcf()方法先保存到一个变量,例如fig

1
2
3
4
5
6
# 传入x 和 y
plt.plot(x,y)
# gcf: Get Current Figure
fig = plt.gcf()
plt.show()
fig.savefig('test.png')

除了png外,还可以保存为svg等多种格式。

设置X或者Y轴上的刻度

设置刻度的范围

1
2
plt.xticks(range(1,100))
plt.yticks(range(-100,100))
1
2
3
x_ticks = [ i/2 for i in range(1,20)]
plt.xticks(x_ticks)
plt.yticks(range(min(y),max(y) + 1))

更多的刻度操作

  1. 添加别名
  2. 设置步长
  3. 标签旋转

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from matplotlib import pyplot as plt
import random

x = range(0,120)
y = [random.randint(10,20) for i in range(120)]
plt.plot(x,y)
# 别名
x_ticks_label = ['No '+ format(i) for i in x]
# 设置步长:x[::10],x_ticks_label[::10]
# 旋转:rotation
plt.xticks(x[::10],x_ticks_label[::10],rotation=90)
plt.yticks(range(min(y),max(y)))
plt.plot(x,y)
plt.show()

运行结果:
运行结果

显示中文的方法

无法显示中文的原因

matplotlib的默认字体不支持中文。

所以,想让其显示中文,方法是选择一个支持中文的字体。

选择支持中文的字体

有两种方法

  1. matplotlib.rc()
  2. font_manager

matplotlib.rc

示例代码:

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

font = {'family' : 'Microsoft YaHei',
'weight' : 'bold',
'size' : 'larger'}
matplotlib.rc(font)

x = range(0,120)
y = [random.randint(10,20) for i in range(120)]
plt.plot(x,y)
x_ticks_label = ['编号 '+ format(i) for i in x]
plt.xticks(x[::10],x_ticks_label[::10],rotation=90)
plt.yticks(range(min(y),max(y)))
plt.plot(x,y)
plt.show()

运行结果:
运行结果

对于MacOS,可以参考如下的配置:

1
2
plt.rcParams['font.sans-serif'] = ['Songti SC']
plt.rcParams['axes.unicode_minus'] = False

font_manager

示例代码:

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

font = font_manager.FontProperties(fname="/System/Library/Fonts/PingFang.ttc",size=12)

x = range(0,120)
y = [random.randint(10,20) for i in range(120)]
plt.plot(x,y)
x_ticks_label = ['编号 '+ format(i) for i in x]
# 注意 fontproperties
plt.xticks(x[::10],x_ticks_label[::10],rotation=90,fontproperties=font)
plt.yticks(range(min(y),max(y)))
plt.plot(x,y)
plt.show()

运行结果略。

补充:macOS系统查看字体的方法

命令如下:

1
fc-list

还可以添加参数查看支持中文的字体

1
fc-list :lang=zh

添加描述信息

1
2
3
plt.xlabel('横轴')
plt.ylabel('纵轴')
plt.title('标题')

绘制网格

1
2
# alpha用以控制网格的透明度
plt.grid(alpha=0.2)

画两个折线图

画两个折线图,再用一次plot即可。

1
2
z = [random.randint(10,20) for i in range(120)]
plt.plot(x,z,c='blue')

标记标签

同时,我们还可以用label标签来标记线条名称,并用legend方法贴上标签

1
2
3
4
5
6
7
# 通过label配置标签
plt.plot(x,y,c='red',label = '红线')
plt.plot(x,z,c='blue',label = '蓝线')

# 贴上标签
# loc 控制位置
plt.legend(loc = 'upper right')

控制线条

控制线条形状

通过参数linestyle控制线条形状

1
plt.plot(x,y,c='red',label = '红线',linestyle='--')

linestyle的取值如下:

字符 描述
- 实线
-- 虚线
-. 带点的虚线
: 点线

在画网格的时候,也可以用linestyle控制线条形状。

控制线条的粗细

通过参数linewdith控制线条粗细。

控制线条的颜色

通过c控制颜色。
除了用颜色的名称(形如c='red')来控制颜色,还可以用十六进制的颜色。

更多图形

上述都是以折线图为例,matplotlib除了可以绘制折线图,还可以绘制更多的图形。

散点图

散点图,基于plt.scatter

示例代码:

1
2
3
4
5
6
7
8
from matplotlib import pyplot as plt
import random

x = range(0,10)
y = [random.randint(10,20) for i in x]
plt.scatter(x,y,marker='*')

plt.show()

运行结果略。

可以通过参数marker控制点的形状。

条形图

绘制普通的条形图

普通的条形图,基于plt.bar

示例代码:

1
2
3
4
5
6
7
8
9
10
from matplotlib import pyplot as plt
import random

x = range(0,4)
x_lalel = ['类别 '+ format(i) for i in x]
y = [random.randint(10,20) for i in x]
z = [random.randint(10,20) for i in x]
plt.bar(x_lalel,y)

plt.show()

运行结果略。

绘制横着的条形图

横着的条形图,基于plt.barh

h的含义是"horizontal",水平的。

1
plt.barh(x_lalel,y)

绘制多次条形图

核心思想是:用x控制位移。
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
from matplotlib import pyplot as plt
import random

x = range(0,4)
x_2 = [i + 0.2 for i in range(0,4)]
x_lalel = ['类别 '+ format(i) for i in x]
y = [random.randint(10,20) for i in x]
z = [random.randint(10,20) for i in x]
plt.bar(x,y,width=0.2)
plt.bar(x_2,z,width=0.2)
plt.xticks(x,x_lalel)

plt.show()

运行结果:
绘制多次条形图

直方图

绘制直方图,基于plt.hist

示例代码:

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

a=[131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]

#计算组数
d = 3 #组距
num_bins = (max(a)-min(a))//d
print(max(a),min(a),max(a)-min(a))
print(num_bins)

#设置图形的大小
plt.figure(figsize=(20,8),dpi=80)
plt.hist(a,num_bins)

#设置x轴的刻度
plt.xticks(range(min(a),max(a)+d,d))

plt.show()

运行结果略。

绘制多个图形

分别绘制多个图形

1
plt.subplot(2, 2, 1)

第一个参数是nrows(行),第二个参数是ncols(列),第三个参数是index(序号)。

示例代码:

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

# x轴,从1到9
x = range(1,10,1)
y = [3,1,4,1,5,9,2,6,5]
z = [1,3,5,7,9,5,4,3,2]
# 传入x 和 y,绘制折线图
plt.subplot(2, 2, 1)
plt.plot(x,y)
plt.subplot(2, 2, 2)
plt.scatter(x,z)
plt.subplot(2, 2, 3)
plt.bar(x,y)
plt.subplot(2, 2, 4)
plt.hist(z)
# 展示图形
plt.show()

运行结果:
分别绘制多个图形

同时绘制多个图形

用相同的坐标轴

这种情况,只需要再用plt画一次图即可。
示例代码:

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

# x轴,从1到9
x = range(1,10,1)
y = [3,1,4,1,5,9,2,6,5]
z = [1,3,5,7,9,5,4,3,2]
# 传入x 和 y,绘制折线图
plt.plot(x,y)
plt.scatter(x,z)
# 展示图形
plt.show()

运行结果略。

用不同的y轴

这种情况需要用不同的Axes

1
ax2 = ax1.twinx()

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
from scipy import stats
from matplotlib import pyplot as plt

x = np.linspace(-40,50,100000)
# 密度函数
y = stats.norm.pdf(x,5,10)

mu ,sigma = 5, 10
sampleNo = 1000
s = np.random.normal(mu, sigma, sampleNo)

fig = plt.figure()
ax1 = fig.add_subplot()
ax1.hist(s,bins=100)
ax2 = ax1.twinx()
ax2.plot(x,y,c='red')
plt.show()

运行结果:
用不同的y轴

解释说明:ax2=ax1.twinx()的作用是创建一个和ax1共享X轴的ax2,并将其绑定到同一个图表。这样做是为了将两个不同的图形组合在一起展示,让我们更直观地观察样本数据和理论曲线之间的差距。

以下是一个关于twinx()的具体的例子。

示例代码:

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

x = np.linspace(0, 10, 100)
y1 = 2 * x
y2 = 3 * x ** 2

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

ax1.plot(x, y1, 'b-')
ax2.plot(x, y2, 'r-')

ax1.set_xlabel('X data')
ax1.set_ylabel('Y1 data', color='b')
ax2.set_ylabel('Y2 data', color='r')

plt.show()
运行结果:

twinx()

有一些资料,还会介绍matplotlib中有专门用来画金融图表的模块matplotlib.finance,实际上这个模块在2.2.0及以上版本中已经被移除了。
当然,该模块有替代品,mpl_finance,这里不介绍。

文章作者: Kaka Wan Yifan
文章链接: https://kakawanyifan.com/10301
版权声明: 本博客所有文章版权为文章作者所有,未经书面许可,任何机构和个人不得以任何形式转载、摘编或复制。

评论区