当我们进行数据分析的时候,如果单纯的只有一堆数据摆在你面前,你看起来肯定不舒服。最好能将数据的变化,通过图形呈现出来,在实现数据可视化后,我们就能够更快、更容易、更清晰地看懂数据所要呈现、传达的信息。
Python 在数据展示方面,有非常多好用的工具,比如 Matplotlib、Seaborn、Pygal等,都是颇受欢迎的功能包。我们接下来看看,怎么去实现展示本地的数据,还有从网络中获取到的数据。
可视化视图,大致上我们可以分为 4 大类,分别是:
- 相互比较:比如折线图,可以进行比较数据间各个类别之间的关系,包括数据随着时间的变化趋势;
- 相互联系:比如散点图,可以观察到两个或两个以上实例间的关系;
- 构成占比:比如饼图,可以很直观看到每个部分所占的比例、份额大小,包括其随着时间的比例变化;
- 分布情况:比如直方图,可以观察单个或多个变量的具体分布情况。
常用的 10 种视图:散点图、折线图、直方图、条形图、饼图、热力图、箱型图、蜘蛛图、二元变量分布图、成对关系。
1、安装 Matplotlib
打开终端,输入 pip install matplotlib 即可自动安装。
如果你想要查看 Matplotlib 开发者文档,输入 python -m pydoc -p 8899 即可,启动之后再访问 http://localhost:8899 ,在 .../site-packages 栏下找到 matplotlib(package)就是了。
2、折线图
最近大家是不是又看到标题上写着「史上最惨毕业季」的文章啊?其实,每年都是这么写的,每年都是最难、最惨的。
其实,我们可以找到对应的数据,把它画成折线图,你看看就知道毕业生人数的趋势了。
这是 2010 年~2022 年大学毕业生数据(单位:万):
年份 | 大学毕业生人数(单位:万) | 研究生人数 |
---|
2022 | 1076 | 120 | 2021 | 909 | 117.65 | 2020 | 874 | 110.66 | 2019 | 834 | 91.65 | 2018 | 821 | 85.8 | 2017 | 795 | 80.61 | 2016 | 765 | 66.71 | 2015 | 749 | 64.51 | 2014 | 700 | 62.13 | 2013 | 699 | 61.14 | 2012 | 680 | 58.97 | 2011 | 660 | 56.02 | 2010 | 631 | 53.82 |
2.1 2010 年~2022 年大学毕业生数据
根据上面给出的数据,我们先来绘制一幅折线图,看看从 2010 年到 2022 年之间的大学毕业生人数的变化趋势。其中,我们 X 轴为年份,Y 轴为人数,代码如下:
xData = [2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022]
yData = [631,660,680,699,700,749,765,795,821,834,874,909,1076]
plt.plot(xData, yData, xData, yData2)
plt.show()
运行结果,如图所示:
2.2 2010 年~2022 年研究生数据
那如果说,我想看看研究生人数是否也这么大的增长幅度,也这么夸张?其实也不难,传入多个代表 X 轴、Y 轴的数据的列表就行了,就可以得到一张复合折线图了。
代码如下:
xData = [2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022]
yData = [631,660,680,699,700,749,765,795,821,834,874,909,1076]
yData2 = [53.82,56.02,58.97,61.14,62.13,64.51,66.71,80.61,85.8,91.65,110.66,117.65,120]
plt.plot(xData, yData, xData, yData2)
plt.show()
运行结果,如图所示:
2.3 修改颜色、线条粗细
甚至,你还可以改折线的颜色、粗细,也很简单。比如,通过 color 可以指定对应的颜色,通过 linewidth 可以指定折线的粗细,代码如下:
plt.plot(xData, yData, color='orange', linewidth=5.0)
plt.plot(xData, yData2, color='green', linewidth=5.0)
plt.show()
运行结果,如图所示:
2.4 折线的 4 种样式
如果你不喜欢「实线」的线条,你也可以通过 linestyle 来更改,常用的四种类型,分别是:
第一种,- 表示实线(默认值);
第二种:-- 表示虚线;
第三种:: 表示虚点;
第四种:-. 表示短线、点的结合。
代码如下:
plt.plot(xData, yData, color='orange', linewidth=5.0, linestyle='--')
plt.plot(xData, yData2, color='green', linewidth=5.0, linestyle='-.')
plt.show()
运行结果,如图所示:
3、饼图
3.1 普通饼图
通过饼图,你可以很容易的看到,每个部分的数据所占大小与总体数据之间的比例。在 Matplotlib 中,我们通过 pie(x, labels=None) 函数来绘制饼图,其中 x 代表饼图中的数据,且可以指定多个不同的份额,labels 用来指定饼图的标题。
假设,我们来统计一家水果店的种类份额,很简单的,代码如下:
import matplotlib.pyplot as plt
datas = [22, 30, 35, 8, 15]
labs = ['apple', 'pear', 'peach', 'grape', 'cherry']
plt.pie(x = datas, labels = labs)
plt.show()
运行结果,如图所示:
3.2 分离饼图
如果说,你想特别去突出某一块儿,让它更显眼的话,咱也可以办到。在 pie() 函数中,再指定 explode 就好了。
datas = [22, 30, 35, 8, 15]
labs = ['apple', 'pear', 'peach', 'grape', 'cherry']
exp = [0,0,0,0,0.15]
plt.pie(x = datas, labels = labs, explode = exp)
plt.show()
运行结果,如图所示:
3.3 饼图的更多设置
当然,你还有很多可以指定的显示方式,比如你可以自定义饼图的颜色、百分比的格式、标签与圆心的距离、饼图的初始角度、圆心、饼图的半径、逆/顺时针方向、圆圈实线、标题等等,大家都可以去多尝试。
代码如下:
import matplotlib.pyplot as plt
datas = [22, 30, 35, 8, 15]
labs = ['apple', 'pear', 'peach', 'grape', 'cherry']
exp = [0,0,0,0,0.15]
cols = ['orange', 'green', 'blue', 'red', 'purple']
plt.pie(x = datas,
labels = labs,
explode = exp,
colors = cols,
autopct = '%.2f%%',
textprops = {'fontsize':12, 'color':'black'},
)
plt.title('Fruit Shop')
plt.show()
运行结果,如图所示:
4、柱状图
4.1 普通柱状图
柱状图,能够让我们更清晰地查看类别的特征。可以通过 bar(x, height) 函数来绘制柱状图,其中 x 代表的是 x 轴的位置序列,height 代表的是 y 轴的数值序列。
比如,我们从本地读取一份学生成绩的 excel 数据,然后将其用柱状图的方式绘制出来。
在 Excel 中,我们有一份简单的数据,如图所示:
具体代码如下:
import pandas as pd
import matplotlib.pyplot as plt
users = pd.read_excel('../../user.xlsx')
users.sort_values(by='score', inplace=True, ascending=False)
plt.bar(users.name, users.score, color='orange')
plt.title('Student Score', fontsize=16)
plt.xlabel('Name')
plt.ylabel('Score')
plt.tight_layout()
plt.show()
运行结果,如图所示:
如果你想要把 X 轴和 Y 轴名称改成中文的,通过添加中文支持就可以了。
import pandas as pd
import matplotlib.pyplot as plt
users = pd.read_excel('../../user.xlsx')
users.sort_values(by='score', inplace=True, ascending=False)
plt.bar(users.name, users.score, color='orange')
from matplotlib.font_manager import FontProperties
font = FontProperties(frame="SimSun.ttc", size=16)
plt.title('学生分数', fontproper=font)
plt.xlabel('名字', fontproperties=font, fontsize=14)
plt.ylabel('分数', fontproperties=font, fontsize=14)
plt.xticks(users.name, rotation='90')
plt.tight_layout()
plt.show()
4.2 叠加柱状图
假设,咱学生的三科考试成绩都出来了,包括语文、数学、英语,那咱想叠加展示的话,就直接使用 stacked 来实现叠加形式。
一样,我们也是需要先去读取 Excel 中的数据,再去绘制。
具体代码如下:
import pandas as pd
import matplotlib.pyplot as plt
users = pd.read_excel('../../user2.xlsx')
users['Total'] = users['chinese'] + users['english'] + users['math']
users.sort_values(by='Total', inplace=True)
users.plot.barh(x='name', y=['chinese', 'english', 'math'], stacked=True)
plt.tight_layout()
plt.show()
运行结果,如图所示:
(1)垂直方向的效果:
(2)水平方向的效果:
5、散点图
散点图描述的是 两个变量之间的关系,将两个变量的值展示在一个二维坐标系中,它跟折线图有点儿相似,区别是散点图只描述数据点,不会将他们练成一根线。
我们可以指定一个范围,通过随机数来绘制一张散点图,感受一下。
非常简单的,具体代码如下:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
N = 1000
x = np.random.randn(N)
y = np.random.randn(N)
plt.scatter(x, y, marker='*')
plt.show()
运行结果,如图所示:
其中,我们绘制散点图时,用到了 scatter() 函数,除了上面我们用过的参数以外,还有好几个也是比较常见的,下面统一再说明一下:
-
x:指定 X 轴数据; -
y:指定 Y 轴数据; -
s:指定散点的大小; -
c:指定散点的颜色; -
alpha:指定散点的透明度; -
linewidths:指定散点边框的粗细; -
edgecolors:指定散点边框的颜色; -
marker:指定散点的图形样式(有很多)
标记 | 说明 | 标记 | 说明 |
---|
. | 点 | s | 正方形 | , | 像素 | p | 五边形 | o | 圆形 | * | 星型 | v | 向下三角 | h | 八边形 | ^ | 向上三角 | H | 八边形2 | < | 向左三角 | + | 加号 | > | 向右三角 | x | 乘号 | 1 | 向下三叉 | D | 菱形 | 2 | 向上三叉 | d | 小菱形 | 3 | 向左三叉 | | | 竖线 | 4 | 向右三叉 | _ | 横线 |
-
camp:指定散点颜色的映射。
6、直方图
直方图,也叫质量分布图,它主要由一系列高度不等的纵向条纹或线段来表示数据分布的情况。其中,横轴用来表示数据类型,纵轴用来表示分布情况。
在横坐标上,等分成了一定数量的小区间,每个小区间用高矮不一的矩形条来展示区间中的 y 值,此时我们即可观察到数据集的直方图分布的情况。
具体代码如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
a = np.random.randn(100)
s = pd.Series(a)
plt.hist(s)
plt.show()
运行结果,如图所示:
7、箱线图
箱线图,可以用来分析数据的差异性、离散程度、异常值等。它由五个部分组成,分别是最大值 (max)、最小值 (min)、中位数 (median) 和上下四分位数 (Q3, Q1)。
通过使用 boxplot(x, labels=None) 函数即可实现,其中,x 指的是要绘制箱线图的数据,labels 用来设置箱线图的标签。
具体代码如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = np.random.normal(size=(10,5))
lables = ['A','B','C','D','E']
plt.boxplot(data,labels=lables)
plt.show()
运行结果,如图所示:
8、雷达图
这是我做了一个项目管理能力的评估效果图,所呈现的图示叫雷达图,也叫蜘蛛图。
它是一种显示一对多关系的方式。在图中,我们可以观察到一个变量相对于另一个变量的显著性是很清晰的。
在设置数据的时候,我们需要指定对应标签的统计数据,也就是 labels 和 stats。
另外,它本质上是一个圆形,需要我们根据标签的个数,来计算出其坐标的角度,再去设置对应的值。
具体代码如下:
![雷达图](../%E9%9B%B7%E8%BE%BE%E5%9B%BE.png)import numpy as np
import matplotlib.pyplot as plt
labels = np.array(["Chinese","Math","English","Pysics","Cemistry","Sport"])
stats = [85, 60, 90, 77, 86, 85]
angles = np.linspace(0, 2*np.pi, len(labels), endpoint=False)
stats = np.concatenate((stats,[stats[0]]))
angles = np.concatenate((angles,[angles[0]]))
labels=np.concatenate((labels,[labels[0]]))
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
ax.plot(angles, stats, 'o-', color='r', linewidth=2)
ax.fill(angles, stats, facecolor='r', alpha=0.25)
ax.set_thetagrids(angles * 180/np.pi, labels)
plt.show()
运行结果,如图所示:
9、等高线图
先看下面这张图,它是「等高线地图」,是一种利用已有的数据,画出地理位置分布图的方式。
等高线地图,就是将地表高度相同的点,连成一环线,直接投影到平面形成水平曲线。不同高度的环线不会相合,除非地表显示悬崖或峭壁,才能使某处线条太密集,而出现重叠现象。若地表出现平坦开阔的山坡,曲线间之距离就相当宽。
在我们数据分析中,我们除了地理数据以外,还有很多其他数据也要做「等高线图」展示,它需要的是三维数据,其中 X、Y 轴数据用来确定坐标点,Z 轴数据则是不同坐标点所对应的高度。
当拿到所有数据之后,可以使用 contour() 函数来进行绘制,如果你想要填充颜色的话,可以使用 contourf() 函数来实现。
常用的参数有:
- X:用于指定 X 轴数据;
- Y:用于指定 Y 轴数据;
- Z:用于指定 X、Y 轴坐标的所对应的高度数据;
- colors:用于指定不同高度的等高线的颜色;
- alpha:用于指定等高线的透明度;
- cmap:用于指定等高线的颜色映射;
- linewidths:用于指定等高线的宽度;
- linesytles:用于指定等高线的样式。
那我们就来画一张吧,很简单的,具体代码如下:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 5)
y = np.linspace(-3, 3, 5)
X, Y = np.meshgrid(x, y)
def f(x, y):
return x * (y * 0.2)
plt.contourf(X, Y, f(X,Y), 10, alpha = 0.75, cmap = 'rainbow')
con = plt.contour(X, Y, f(X,Y), 10, colors = 'black', linewidth = 0.5)
plt.clabel(con, inline = True, fontsize = 10)
plt.xticks(())
plt.yticks(())
plt.show()
运行结果,如图所示:
10、3D 图
画 3D 图,是很好玩儿的,它需要的数据跟上面的等高线图基本一样,先通过 X、Y 轴来指定坐标点,然后再通过 Z 轴来指定坐标点的对应高度。
我们可以使用 Matplotlib 的 scatter3D() 方法来实现;也可以使用 Axes3D 对象的 plot_surface() 方法来实现,我们都拿来玩一下。
先来看看 Matplotlib 的 scatter3D() 方法,具体代码如下:
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
ax = plt.axes(projection='3d')
zd = 10 * np.random.random(100)
xd = 3 * np.sin(zd)
yd = 4 * np.cos(zd)
ax.scatter3D(xd, yd, zd,
c = 'red')
plt.show()
运行结果,如图所示:
再来看看 Axes3D 对象的 plot_surface() 方法,具体代码如下:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize = (10, 8))
ax = Axes3D(fig)
x = np.arange(-8,8,0.25)
y = np.arange(-8,8,0.25)
x,y = np.meshgrid(x,y)
r = np.sqrt(x**2 + y**2)
z = np.sin(r)/2
ax.plot_surface(x, y, z,
rstride = 1,
cstride = 1,
cmap = plt.get_cmap('rainbow'))
ax.contourf(x, y, z,
zdir = 'z',
offset = -2)
plt.show()
运行结果,如图所示:
|