0.摘要
本教程主要介绍使用python第三方库matplotlib绘制各种统计图表,教程从简单到复杂,逐步递进。
本章主要介绍常见图表的绘制方法,并以尽可能简单的方式实现,主要以突出函数功能为目的,防止读者被复杂的参数分散了注意力。鉴于函数的参数的相似性,读者只需要知道参数的含义并结合help命令即可掌握。常用参数将在后续章节中进行统一介绍,帮助读者记忆。
附官网教程链接:https://matplotlib.org/
1.线形图
首先绘制一条y = x 的直线,利用numpy.linspace()可以在给定区间上生成一定数量的等距点:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-10,10,200)
y = x
plt.plot(x,y)
plt.show() #显示图像
x在[-10,10]上均匀地取了200个点,点的数量直接影响曲线的精确度和图像的圆滑程度,这里用y = x ** 2进行举例:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-10,10,5)
y = x ** 2
plt.plot(x,y)
plt.show()
当点阵密度不足的时候,图像会出现明显的棱角,从而产生失真现象。
多次调用plt.plot()方法即可在一张图表中绘制出多条曲线。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3,3,100)
y1 = x ** 2 - 1
y2 = x + 1
plt.plot(x,y1)
plt.plot(x,y2)
plt.show()
2.条形图
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(10)
y = np.random.randint(1,10,10)
plt.bar(x,y)
plt.show()
与线形图一样,多次调用plt.bar()可以在一张图中绘制出多组数据:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(10)
y1 = np.random.randint(1,10,10)
y2 = np.random.randint(-10,-1,10)
plt.bar(x,y1)
plt.bar(x,y2)
plt.show()
需要注意的是,如果y1,y2共用x轴,那么就可能出现重合的情况:
这种情况可以通过设置不同的x轴进行分离:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.arange(0,30,3)
x2 = np.arange(1,30,3)
y1 = np.random.randint(1,10,10)
y2 = np.random.randint(1,10,10)
plt.bar(x1,y1)
plt.bar(x2,y2)
plt.show()
3.直方图
先介绍一下直方图与条形图的区别:(内容转自:https://blog.csdn.net/hohaizx/article/details/79101322)
首先需要区分清楚概念:直方图和条形图。
- 条形图:条形图用长条形表示每一个类别,长条形的长度表示类别的频数,宽度表示表示类别。
- 直方图:直方图是一种统计报告图,形式上也是一个个的长条形,但是直方图用长条形的面积表示频数,所以长条形的高度表示频数组距频数组距,宽度表示组距,其长度和宽度均有意义。当宽度相同时,一般就用长条形长度表示频数。
直方图一般用来描述等距数据,柱状图一般用来描述名称(类别)数据或顺序数据。直观上,直方图各个长条形是衔接在一起的,表示数据间的数学关系;条形图各长条形之间留有空隙,区分不同的类。
区别 | 频数分布直方图 | 条形图 |
---|---|---|
横轴上的数据 | 连续的,是一个范围 | 孤立的,代表一个类别 |
长条形之间 | 没有空隙 | 有空隙 |
频数的表示 | 一般用长条形面积表示;当宽度相同时,用长度表示 | 长条形的长度 |
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randn(1000)
plt.hist(data)
plt.show()
4.散点图
import matplotlib.pyplot as plt
import random
x = [random.randint(1,100) for _ in range(100)]
y = [random.randint(1,100) for _ in range(100)]
plt.scatter(x, y)
plt.show()
同样,多组数据亦可以同时绘制在一张图中:
import matplotlib.pyplot as plt
import random
x1 = [random.randint(1,50) for _ in range(100)]
y1 = [random.randint(1,50) for _ in range(100)]
x2 = [random.randint(50,100) for _ in range(100)]
y2 = [random.randint(50,100) for _ in range(100)]
plt.scatter(x1, y1)
plt.scatter(x2, y2)
plt.show()
5.饼状图
matplotlib会根据数据自动计算比例,这里只需要给出数据列表即可:
import matplotlib.pyplot as plt
share = [256, 512, 32, 1024, 512]
plt.pie(share)
plt.show()
由于饼图比较特殊,这里详细介绍一下它的参数:
import matplotlib.pyplot as plt
labels = ['Java', 'Python', 'JavaScript', 'C++', 'C#', 'PHP', 'Perl']
users = [68, 46, 38, 31, 27, 15, 14 ]
explode = [0, 0.3, 0, 0, 0, 0, 0] # 设置Python突出显示
colors = ['b', 'c', 'g', 'grey', 'm', 'r', 'y'] #设置每一块的颜色
plt.axes(aspect=1) # 设置饼图形状为圆形,默认为椭圆形
plt.pie(x=users, labels=labels, explode=explode, autopct='%3.1f %%',colors=colors,
shadow=True, labeldistance=1.1, startangle=0, pctdistance=0.6)
plt.show()
autopct:设置每一块百分比数据的显示格式;
labeldistance:设置label的显示位置,0代表位于圆心,1代表位于边线;
startangle:起始的绘图角度;
pctdistance:百分比的形式位置。
6. 等高线图
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3, 3, 101)
y = np.linspace(-3, 3, 101)
#构建二维坐标点
X, Y = np.meshgrid(x, y)
height = (2 * np.pi) * np.exp((-1)/2 * (X ** 2 + Y ** 2)) + np.abs(X) + np.abs(Y)
#为等高线填充颜色
plt.contourf(X, Y, height)
# 绘制等高线
C = plt.contour(X, Y, height)
# 添加等高线标注
plt.clabel(C, inline=True, fontsize=16)
plt.show()
7.立体(3D)数据图
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(-3, 3, 1001)
y = np.linspace(-3, 3, 1001)
X, Y = np.meshgrid(x, y)
Z = (2 * np.pi) * np.exp((-1)/2 * (X ** 2 + Y ** 2))
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X, Y, Z,cmap=plt.get_cmap('rainbow'))
plt.show()
8.二维矩阵以灰度图像显示
import matplotlib.pyplot as plt
data = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18, 18, 18, 126, 136, 175, 26, 166, 255, 247, 127, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 30, 36, 94, 154, 170, 253, 253, 253, 253, 253, 225, 172, 253, 242, 195, 64, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 49, 238, 253, 253, 253, 253, 253, 253, 253, 253, 251, 93, 82, 82, 56, 39, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 18, 219, 253, 253, 253, 253, 253, 198, 182, 247, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 80, 156, 107, 253, 253, 205, 11, 0, 43, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 1, 154, 253, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 253, 190, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 190, 253, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 241, 225, 160, 108, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 240, 253, 253, 119, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 186, 253, 253, 150, 27, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 93, 252, 253, 187, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 253, 249, 64, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 130, 183, 253, 253, 207, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 148, 229, 253, 253, 253, 250, 182, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 114, 221, 253, 253, 253, 253, 201, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 23, 66, 213, 253, 253, 253, 253, 198, 81, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 18, 171, 219, 253, 253, 253, 253, 195, 80, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 55, 172, 226, 253, 253, 253, 253, 244, 133, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 136, 253, 253, 253, 212, 135, 132, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
plt.imshow(data)
plt.show()