首先祝大家元宵节快乐呀!这篇文章呢主要就是介绍如何绘制常见的数据分析图表,更多地是讲如何利用python的matplotlib库来绘制,也会提及一些现成的工具。


2023.11.13 参加了几次数模后想着来更新一波内容(主要是美化一下,之前的有点小丑……

Python

Python绘制数据分析图表主要用到的是matplotlib这个库,使用前先安装这个库

1
pip install matplotlib

然后导入子模块pyplot

1
import matplotlib.pyplot as plt

对于图表中可能会出现中文显示不了的问题,一般要在开始前加上以下语句

1
2
3
# 解决中文显示问题 
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

折线图

折线图(Line Chart)是一种将数据点按照顺序连接起来的图形,也可以看作是将散点图按照X轴坐标顺序链接起来的图形。折线图的主要功能是查看因变量y随着自变量x改变的趋势,最适合用于显示随时间(根据常用比例设置)而改变的连续数据。同时,还可以看出数量的差异,python画折线图主要利用plot方法

实例代码

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Times New Romen', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False

# x轴的数据
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# x对应的y值
data1 = np.random.randint(50, size=10)
data2 = np.random.randint(50, size=10)
data3 = np.random.randint(50, size=10)

# plot绘制折线图
# 1.前两个参数是对应x轴y轴数据,marker是数据点样式,linewidth是线宽,linestyle是线条样式,color是线条颜色
# 2.linestyle常用属性值:
# '-' 实线 '--' 虚线 '-.' 虚点线 ':' 点线
# 3.color常用属性值缩写:(也可使用十六进制颜色表示法)
# 'b' 蓝色 'g' 绿色 'r' 红色 'c' 青色 'm' 品红 'y' 黄色 'k' 黑色 'w' 白色
# 4.mfc数据点的填充颜色
# 5.ms数据点的大小
plt.plot(seq, data1, marker='o', linewidth=1, linestyle='-', color='#6562FF', label='数据一', mfc='white', ms=5)
plt.plot(seq, data2, marker='o', linewidth=1, linestyle='-', color='m', label='数据二', mfc='white', ms=5)
plt.plot(seq, data3, marker='o', linewidth=1, linestyle='-', color='g', label='数据三', mfc='white', ms=5)

# 设置标题及字体大小
# plt.title(label='Test Chart', fontsize=18)
plt.xlabel(xlabel='x轴', fontsize=14)
plt.ylabel(ylabel='y轴', fontsize=14)

for tick in plt.gca().get_yticklabels():
plt.axhline(y=tick.get_position()[1], color='#b8bcbf', linestyle='--', linewidth=1, zorder=-1)

# 设置图例
# 参数loc可以设置图例在图表中的位置
# 'best'
# 'upper right':右上角
# 'upper left': 左上角
# 'lower left': 左下角
# 'lower right': 右下角
# 'center left': 左侧中央
# 'center right': 右侧中间
# 'lower center': 底部正中
# 'upper center': 顶部正中
# 将图例放在图表外loc设置为best,通过添加bbox_to_anchor属性设置锚点即图例位置:在图表内,左下角位置为(0,0),右上角位置为(1,1)
plt.legend(loc='best')

# 去掉上边框和有边框
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)

# savefig保存图片
plt.savefig('test.jpg', bbox_inches='tight') # bbox_inches='tight'将图表的多余空间删除
plt.show()

效果图:

散点图

散点图(Scatter Diagram)又称为散点分布图,是以一个特征为横坐标,另一个特征为纵坐标,使用坐标点(散点)的分布形态反映特征间统计关系的一种图形。值时由点在图表中的位置表示,类别是由图表中的不同标记表示 ,通常用于比较跨类别的数据,python画散点图主要利用scatter方法

scatter方法主要参数

1
matplotlib.pyplot.scatter(x,y,s=None,c=None,marker=None,alpha=None)

scatter方法主要参数说明

实例代码

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
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# label属性是设置图例名称
# # 绘制一组数据散点图
# x = np.arange(1, 30)
# y = np.sin(x)
# plt.scatter(x,y,c='orange',s=100,label='orange',marker='o',alpha=0.5)
# 绘制多组数据散点图
for color in ['red', 'green', 'blue']:
x, y = np.random.randn(2, 500)
plt.scatter(x, y, c=color, label=color, alpha=0.3)

# 设置标题和横纵坐标
plt.title('散点图')
plt.xlabel('X')
plt.ylabel('Y')

# 显示图例
plt.legend()

# savefig保存图片
plt.savefig('test.jpg', bbox_inches='tight') # bbox_inches='tight'将图表的多余空间删除
plt.show()

效果图

饼图

饼图(Pie Graph)用于表示不同分类的占比情况,通过弧度大小来对比各种分类,饼图可以比较清楚的反映出部分与部分、部分与整体之间的比例关系,易于显示每组数据相对于总数的大小,而且显现的方式直观。python画饼图主要利用pie方法

pie方法主要参数

1
2
matplotlib.pyplot.pie(x,explode = None,labels = None,color = None,autopct = None,
pctdistance = 0.6,shadow=false,labeldistance=1.1,startangle=None,radius=None,...)

实例代码

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# x:指定绘图的数据;
# explode:指定饼图某些部分的突出显示,即呈现爆炸式;
# labels:为饼图添加标签说明,类似于图例说明;
# colors:指定饼图的填充色;
# autopct:自动添加百分比显示,可以采用格式化的方法显示;
# pctdistance:设置百分比标签与圆心的距离;
# shadow:是否添加饼图的阴影效果;
# labeldistance:设置各扇形标签(图例)与圆心的距离;
# startangle:设置饼图的初始摆放角度;
# radius:设置饼图的半径大小;
# counterclock:是否让饼图按逆时针顺序呈现;
# wedgeprops:设置饼图内外边界的属性,如边界线的粗细、颜色等;
# textprops:设置饼图中文本的属性,如字体大小、颜色等;
# center:指定饼图的中心点位置,默认为原点
# frame:是否要显示饼图背后的图框,如果设置为True的话,需要同时控制图框x轴、y轴的范围和饼图的中心位置
labels = ['30岁', '40岁', '50岁', '60岁']
x = [15, 30, 45, 10] # 各个标签的数量
explode = (0.05, 0.05, 0.05, 0.05) # 每个标签的扇形图距离圆心的距离
plt.pie(x=x,
autopct='%.2f%%',
colors=['#eab4ad', '#afc6d2', '#b0d1bb', '#87cefa'],
labels=labels,
pctdistance=0.6,
labeldistance=1.1,
explode=explode,
wedgeprops={'edgecolor': 'r',
'linestyle': '--'},
textprops={"fontsize": 13, "color": "black"},
shadow=True
)

# 设置标题和横纵坐标
plt.title('饼状图')

# savefig保存图片
plt.savefig('test.jpg', bbox_inches='tight')
plt.show()

效果图

直方图

直方图(Histogram)又称质量分布图,是统计报告图的一种,由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据所属类别,纵轴表示数量或者占比。用直方图可以比较直观地看出产品质量特性的分布状态,便于判断其总体质量分布情况。直方图可以发现分布表无法发现的数据模式、样本的频率分布和总体的分布。python画饼图主要利用bar方法

bar方法主要参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 参数说明
# x:传递数值序列,指定条形图中x轴上的刻度值。
# height:传递数值序列,指定条形图y轴上的高度。
# width:指定条形图的宽度,默认为0.8。 bottom:用于绘制堆叠条形图。
# color:指定条形图的填充色。
# edgecolor:指定条形图的边框色。
# linewidth:指定条形图边框的宽度,如果指定为0,表示不绘制边框。
# tick_label:指定条形图的刻度标签。
# xerr:如果参数不为None,表示在条形图的基础上添加误差棒。
# yerr:参数含义同xerr。
# label:指定条形图的标签,一般用以添加图例。
# ecolor:指定条形图误差棒的颜色。
# align:指定x轴刻度标签的对齐方式,默认为center,表示刻度标签居中对齐,如果设置为edge,则表示在每个条形的左下角呈现刻度标签。
# log:bool类型参数,是否对坐标轴进行log变换,默认为False。
# **kwargs:关键字参数,用于对条形图进行其他设置,如透明度等。
bar(x, height, width=0.8, bottom=None, color=None, edgecolor=None,
linewidth=None, tick_label=None, xerr=None, yerr=None,
label = None, ecolor=None, align, log=False, **kwargs)

水平交错条形图

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
28
29
30
31
32
33
34
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 设置绘图风格
plt.style.use('ggplot')
# 城市名称
Cities = ['北京', '上海', '香港', '深圳', '广州']
# 取出2016年各城市亿万资产家庭数
Counts2016 = [15600, 12700, 11300, 4270, 3820]
# 取出2017年各城市亿万资产家庭数
Counts2017 = [17400, 14800, 12000, 5200, 4020]
# 绘制水平交错条形图
bar_width = 0.4
plt.bar(x=np.arange(len(Cities)), height=Counts2016, label='2016', color='steelblue', width=bar_width)
plt.bar(x=np.arange(len(Cities)) + bar_width, height=Counts2017, label='2017', color='indianred', width=bar_width)
# 添加x轴刻度标签(向右偏移0.225)
plt.xticks(np.arange(5) + 0.2, Cities)
# 添加y轴标签
plt.ylabel('亿万资产家庭数')
# 添加图形标题
plt.title('近两年5个城市亿万资产家庭数比较')
# 添加图例
plt.legend()
# 为每个条形图添加数值标签
for x, y in enumerate(Counts2016):
plt.text(x, y + 200, "%s" % round(y, 1), ha='center') # round(y,1)是将y值四舍五入到一个小数位
for x, y in enumerate(Counts2017):
plt.text(x + bar_width, y + 200, "%s" % round(y, 1), ha='center')
# 保存图像
plt.savefig("test.jpg")
# 显示图形
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
import matplotlib.pyplot as plt

# 设置绘图风格
plt.style.use('ggplot')
# 处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 水平条形图一般具有一定顺序
Cities = ['广东', '江苏', '上海', '北京', '重庆', '天津']
GDP = [9, 8.6, 3, 2.8, 2, 1.9]
# 绘制条形图
plt.barh(y=range(len(Cities)), # 指定条形图y轴的刻度值
width=GDP, # 指定条形图x轴的数值
tick_label=Cities, # 指定条形图y轴的刻度标签
color=['#da7d61', '#3f3f5c', '#86af9d', '#467b9d', '#f0c986']
)
# 添加x轴的标签
plt.xlabel('GDP(万亿)')
plt.title('2017年度6个省份GDP分布')
# 为每个条形图添加数值标签
for y, x in enumerate(GDP):
plt.text(x + 0.1, y, "%s" % round(x, 1), va='center') # round(y,1)是将y值四舍五入到一个小数位

plt.savefig("test.jpg")
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
import matplotlib.pyplot as plt

# 设置绘图风格
plt.style.use('ggplot')
# 处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
Cities = ['广东', '江苏', '上海', '北京', '重庆', '天津']
GDP = [9, 8.6, 3, 2.8, 2, 1.9]
# 绘制条形图
plt.bar(x=range(len(Cities)), # 指定条形图x轴的刻度值(有的是用left,有的要用x)
height=GDP, # 指定条形图y轴的数值(python3.7不能用y,而应该用height)
tick_label=Cities, # 指定条形图x轴的刻度标签
color='steelblue', # 指定条形图的填充色
)
# 添加y轴的标签
plt.ylabel('GDP(万亿)')
# 添加条形图的标题
plt.title('2017年度6个省份GDP分布')
# 为每个条形图添加数值标签
for x, y in enumerate(GDP):
plt.text(x, y + 0.1, "%s" % round(y, 1), ha='center') # round(y,1)是将y值四舍五入到一个小数位
# 保存图片
plt.savefig("test.jpg")
# 显示图形
plt.show()

效果图

热力图

利用热力图可以看数据表里多个特征两两的相似度,在python种一般利用seaborn中的heatmap方法

heatmap方法常用参数

1
seaborn.heatmap(data, vmin=None, vmax=None,cmap=None, center=None, robust=False, annot=None, fmt=’.2g’, annot_kws=None,linewidths=0, linecolor=’white’, cbar=True, cbar_kws=None, cbar_ax=None,square=False, xticklabels=’auto’, yticklabels=’auto’, mask=None, ax=None,**kwargs)

实例代码

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

data = np.random.rand(5, 5) # 指定生成5x5的元素是0-1的二维数组
df = pd.DataFrame(data, columns=['a', 'b', 'c', 'd', 'e'], index=range(1, 6))

corr = df.corr()
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True

# 参数解释:
# data:矩阵数据集,可以是numpy的数组(array),也可以是pandas的DataFrame。如果是DataFrame,则df的index/column信息会分别对应到heatmap的columns和rows,即df.index是热力图的行标,df.columns是热力图的列标
# vmax,vmin:分别是热力图的颜色取值最大和最小范围,默认是根据data数据表里的取值确定
# cmap:从数字到色彩空间的映射,取值是matplotlib包里的colormap名称或颜色对象,或者表示颜色的列表;一般有‘YlGnBu’和‘BuPu_r’
# center:数据表取值有差异时,设置热力图的色彩中心对齐值;通过设置center值,可以调整生成的图像颜色的整体深浅;设置center数据时,如果有数据溢出,则手动设置的vmax、vmin会自动改变
# robust:默认取值False;如果是False,且没设定vmin和vmax的值,热力图的颜色映射范围根据具有鲁棒性的分位数设定,而不是用极值设定
# annot(annotate的缩写):默认取值False;如果是True,在热力图每个方格写入数据;如果是矩阵,在热力图每个方格写入该矩阵对应位置数据
# fmt:字符串格式代码,矩阵上标识数字的数据格式,比如保留小数点后几位数字
# annot_kws:默认取值False;如果是True,设置热力图矩阵上数字的大小颜色字体,matplotlib包text类下的字体设置;
# linewidths:定义热力图里“表示两两特征关系的矩阵小块”之间的间隔大小
# linecolor:切分热力图上每个矩阵小块的线的颜色,默认值是’white’
# cbar:是否在热力图侧边绘制颜色刻度条,默认值是True
# cbar_kws:热力图侧边绘制颜色刻度条时,相关字体设置,默认值是None
# cbar_ax:热力图侧边绘制颜色刻度条时,刻度条位置设置,默认值是None
# xticklabels, yticklabels:xticklabels控制每列标签名的输出;yticklabels控制每行标签名的输出。默认值是auto:
# 如果是True,则以DataFrame的列名作为标签名。如果是False,则不添加行标签名。如果是列表,则标签名改为列表中给的内容。如果是整数K,则在图上每隔K个标签进行一次标注。
# 如果是auto,则自动选择标签的标注间距,将标签名不重叠的部分(或全部)输出
# mask:控制某个矩阵块是否显示出来。默认值是None。如果是布尔型的DataFrame,则将DataFrame里True的位置用白色覆盖掉
# ax:设置作图的坐标轴,一般画多个子图时需要修改不同的子图的该值
sns.heatmap(corr, vmax=1, vmin=0, cmap='RdBu_r', annot=True, fmt='.3f',
annot_kws={'size': 9, 'weight': 'bold', 'color': 'white'}, cbar=True,
xticklabels=['a', 'b', 'c', 'd', 'e'], yticklabels=['a', 'b', 'c', 'd', 'e'], square=True)

# sns.heatmap(corr, vmax=1, vmin=0, cmap='RdBu_r', annot=True, fmt='.3f', mask=mask,
# annot_kws={'size': 9, 'weight': 'bold', 'color': 'white'}, cbar=True,
# xticklabels=['a', 'b', 'c', 'd', 'e'], yticklabels=['a', 'b', 'c', 'd', 'e'], square=True)

plt.savefig("test.jpg")
plt.show()

效果图

subplot

有些时候, 我们希望把一组数据分析图表放在一起进行比较,这时候matplotlib 中提供的subplot就可以解决这个问题

subplot函数的参数

matplotlib下, 一个 Figure 对象可以包含多个子图(Axes), 可以使用 subplot() 快速绘制

1
2
3
4
subplot(numRows,numCols,plotNum)
# 图表将整个绘图区域分成numRows行和numCols列
# 按从左到右,从上到下的顺序对每个子区域进行编号,左上的子区域编号为1
# plotNum参数指定创建的axes对象所在的区域

实例代码

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
28
29
30
31
32
33
34
35
36
37
38
39
40
import numpy as np
import matplotlib.pyplot as plt
import warnings

# 取消警告的输出
warnings.filterwarnings("ignore")

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure() # 创建一个Figure图表对象

plt.subplot(2, 2, 1, facecolor='#B0C4DE') # facecolor设置背景颜色
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
data = np.random.randint(50, size=10)
plt.plot(seq, data, marker='o', linewidth=1, linestyle=':', color='#6562FF')

plt.subplot(2, 2, 2, facecolor='#B0C4DE')
for color in ['red', 'green', 'blue']:
x, y = np.random.randn(2, 500)
plt.scatter(x, y, c=color, label=color, alpha=0.3)

plt.subplot(2, 1, 2, facecolor='white')
Cities = ['北京', '上海', '香港', '深圳', '广州']
Counts2016 = [15600, 12700, 11300, 4270, 3820]
Counts2017 = [17400, 14800, 12000, 5200, 4020]
bar_width = 0.4
plt.bar(x=np.arange(len(Cities)), height=Counts2016, label='2016', color='steelblue', width=bar_width)
plt.bar(x=np.arange(len(Cities)) + bar_width, height=Counts2017, label='2017', color='indianred', width=bar_width)
# 添加x轴刻度标签(向右偏移0.225)
plt.xticks(np.arange(5) + 0.2, Cities)
plt.ylabel('亿万资产家庭数')
plt.legend()
for x, y in enumerate(Counts2016):
plt.text(x, y + 200, "%s" % round(y, 1), ha='center')
for x, y in enumerate(Counts2017):
plt.text(x + bar_width, y + 200, "%s" % round(y, 1), ha='center')

plt.savefig("test.jpg")
plt.show()

绘制图表网站

图表秀:http://www.tubiaoxiu.com/

参考文章

https://www.jb51.net/article/252383.htm

https://blog.csdn.net/weixin_48615832/article/details/108028198

https://blog.csdn.net/chumingqian/article/details/126063755

https://blog.csdn.net/weixin_39541558/article/details/79813936