Python 基于 Matplotlib 实现数据可视化

当我们进行数据分析的时候,如果单纯的只有一堆数据摆在你面前,你看起来肯定不舒服。最好能将数据的变化,通过图形呈现出来,在实现数据可视化后,我们就能够更快、更容易、更清晰地看懂数据所要呈现、传达的信息。

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 轴为人数,代码如下:

# 定义 X 轴和 Y 轴数据
# 其中,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]

# 参数 1,设置横坐标的值
# 参数 2,设置纵坐标的值
plt.plot(xData, yData, xData, yData2)

# 展示图像
plt.show()

运行结果,如图所示:

在这里插入图片描述

2.2 2010 年~2022 年研究生数据

那如果说,我想看看研究生人数是否也这么大的增长幅度,也这么夸张?其实也不难,传入多个代表 X 轴、Y 轴的数据的列表就行了,就可以得到一张复合折线图了。

代码如下:

# 定义 X 轴和 Y 轴数据
# 其中,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]

# 参数 1,设置横坐标的值
# 参数 2,设置纵坐标的值
# 参数 3,设置第二条折线的横坐标的值
# 参数 4,设置第二条折线的纵坐标的值
plt.plot(xData, yData, xData, yData2)

# 展示图像
plt.show()

运行结果,如图所示:

在这里插入图片描述

2.3 修改颜色、线条粗细

甚至,你还可以改折线的颜色、粗细,也很简单。比如,通过 color可以指定对应的颜色,通过 linewidth可以指定折线的粗细,代码如下:

# 通过 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']

# 分离,将 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']

# 分离,将 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')
# sort_values 排序,inplace 原地修改,ascending False 从大到小
users.sort_values(by='score', inplace=True, ascending=False)

# 直接使用 plt.bar() 绘制柱状图
plt.bar(users.name, users.score, color='orange')

# 设置标题、x 轴名称与 y 轴名称,fontsize 设置字号
plt.title('Student Score', fontsize=16)
plt.xlabel('Name')
plt.ylabel('Score')

# 如果 x 轴字体太长,利用 rotation 将其旋转 90 度,方便显示
# plt.xticks(users.name, rotation='90')

# 紧凑型布局(因为 x 轴文字较长,为了让其显示全,使用紧凑型布局)
plt.tight_layout()
plt.show()

运行结果,如图所示:

在这里插入图片描述

如果你想要把 X 轴和 Y 轴名称改成中文的,通过添加中文支持就可以了。

import pandas as pd 
import matplotlib.pyplot as plt

users = pd.read_excel('../../user.xlsx')
# sort_values 排序,inplace 原地修改,ascending False 从大到小
users.sort_values(by='score', inplace=True, ascending=False)

# 直接使用 plt.bar() 绘制柱状图
plt.bar(users.name, users.score, color='orange')

# 添加中文字体支持
from matplotlib.font_manager import FontProperties

# SimSun.ttc 简体字
font = FontProperties(frame="SimSun.ttc", size=16)

# 设置标题、x 轴名称与 y 轴名称,fontsize 设置字号
plt.title('学生分数', fontproper=font)
plt.xlabel('名字', fontproperties=font, fontsize=14)
plt.ylabel('分数', fontproperties=font, fontsize=14)

# 因为 x 轴字体太长,利用 rotation 将其旋转 90 度,方便显示
plt.xticks(users.name, rotation='90')

# 紧凑型布局(因为 x 轴文字较长,为了让其显示全,使用紧凑型布局)
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']

# sort_values 排序,inplace 原地修改
users.sort_values(by='Total', inplace=True)

# 直接使用 plt.bar() 绘制柱状图
# plt.bar(users.name, users.score, color='orange')

# 水平的叠加柱状图,barh 中而 h 表示 horizontal 水平的
# 利用 stacked 就可以实现叠加形式
# users.plot.bar(x='name', y=['chinese', 'english', 'math'], stacked=True)
users.plot.barh(x='name', y=['chinese', 'english', 'math'], stacked=True)

# 紧凑型布局(因为 x 轴文字较长,为了让其显示全,使用紧凑型布局)
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)

# x:指定 X 轴数据  
# y:指定 Y 轴数据
# market:指定散点的图形样式
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']

# 用Matplotlib画箱线图
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
# import seaborn as sns
# from matplotlib.font_manager import FontProperties 

# 准备数据
# 语文,数学,英语,物理,化学,体育
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()
# 将图分成 1 行 1 列,画出位置 1 的图
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)

# 设置中文字体
# font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=14)  
# ax.set_thetagrids(angles * 180/np.pi, labels, FontProperties=font)
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,Y 轴数据
# 从左边取值为从 -6 到 6
# 各取 5 个点,一共取 5*5 = 25 个点
x = np.linspace(-3, 3, 5)
y = np.linspace(-3, 3, 5)

# 将 X,Y 数据进行网格化
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')

# 指定 X、Y、Z 三个坐标轴
zd = 10 * np.random.random(100)
xd = 3 * np.sin(zd)
yd = 4 * np.cos(zd)

# 绘制散点图
# 基本上是 matplotlib 画图的属性设置
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、Y 数据
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 数据
z = np.sin(r)/2                 

# 调用 plot_surface() 函数进行绘制
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()

运行结果,如图所示:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41340258/article/details/125567812