手摸手教你数据可视化!(附实例讲解)
Datawhale
共 6992字,需浏览 14分钟
·
2020-08-31 01:25
前言
本文对课程数据集及泰坦尼克号数据集进行了实例讲解,一步一步带你绘制数据可视化中常用的五种图形,并对数据间可能存在的相关性做出了阐述。
绘制常用图形
常用图形有:
plt.scatter() 散点图 plt.plot() 折线图 plt.bar() 直方图 plt.pie() 饼图 plt.boxplot() 箱型图
#导入相应的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
#图可以显示中文和负号
plt.rcParams['font.sans-serif']='SimHei'
plt.rcParams['axes.unicode_minus']=False
data = pd.read_excel("D:\data\student-score\student-score.xlsx")
data.head()
![](https://filescdn.proginn.com/903d3507f27a6d424834175bae1c39aa/56125366f665e777d0dffbfa80af916d.webp)
data = data.drop(columns = ["序号","品德","科学"],axis = 1) #由于品德和科学的总分与其他学科不一致,为了图片显示效果,删除这两个学科成绩
data.loc[:,"总分"] = data.loc[:,"语文"] + data.loc[:,"数学"] + data.loc[:,"英语"] #重新计算总分成绩
data.head()
![](https://filescdn.proginn.com/8918bc8a3435b1c64785009a1c2d40a2/c997ff88b5ad32abf05aab239c22c7c9.webp)
接着我们还可以查看其数据结构:
data.shape #查看数据结构
# 输出
(629, 6)
以及查看各学科的缺失值情况:
data.isnull().sum() #查看缺失值情况
'''
姓名 0
学校 0
语文 1
数学 0
英语 0
总分 1
dtype: int64
'''
对于这些缺失值,我们可以选择使用dropna()
函数删除:
data = data.dropna() #删除缺失值
data.shape # (628, 6)
再使用describe()
函数进行简单的统计描述:
data.describe() #简单统计描述
![](https://filescdn.proginn.com/70582428cd268f48e1c42a6884fea0de/c787b8f7810b6f7bddb328f110c5821a.webp)
散点图
gp = data.groupby(by = "学校",as_index=False) #以学校为分组依据进行分组
data1=gp.mean() #分组后的聚合运算为计算均值
data1.head()
得到结果:
![](https://filescdn.proginn.com/9e03d0f88af34db18d2c53ea76e3c761/55bfbd2c6cdc8c9e65496cba694f7380.webp)
# 绘制各学科成绩散点图
plt.figure(figsize=(6,4))
plt.scatter(data1["总分"],data1["语文"],marker='v')
plt.scatter(data1["总分"],data1["数学"],marker='o')
plt.scatter(data1["总分"],data1["英语"],marker='*')
plt.title("各学校成绩散点图",fontsize = 14)
plt.xlabel("总成绩")
plt.ylabel("各学科成绩")
plt.legend(["语文","数学","英语"]);
![](https://filescdn.proginn.com/7d93e8b800ca80cfa20f3ed74df31fff/36682bfba16daac97d2e72c8e499f737.webp)
# 绘制各学科成绩散点图
plt.figure(figsize=(6,4))
plt.scatter(data1["总分"],data1["语文"],marker='v')
plt.title("各学校语文与总分成绩散点图",fontsize = 14)
plt.xlabel("总成绩")
plt.ylabel("各学科成绩")
plt.legend(["语文"])
#
![](https://filescdn.proginn.com/72186079e67d9fb05bf755a80dfef132/914e3668b3fec9e01b5ee985f084942e.webp)
# 绘制各学科成绩散点图
data1.plot.scatter(x = "总分", y = "语文")
plt.title("语文与总分成绩散点图")
data1.plot.scatter(x = "总分", y = "数学")
plt.title("数学与总分成绩散点图")
data1.plot.scatter(x = "总分", y = "英语")
plt.title("英语与总分成绩散点图")
# plt.show()
得到Text(0.5, 1.0, '英语与总分成绩散点图')
,且散点图结果如下:
![](https://filescdn.proginn.com/6c4ca2a65c745ac4b8aa719e263c96e0/c7cb3a5f40c4b0594d1fc4ccfdbd64b0.webp)
![](https://filescdn.proginn.com/411c2d8c2afb4b7cd2d785ccde781ed0/9c6c4a1b7336fd440112a0fa6aa66e25.webp)
![](https://filescdn.proginn.com/825018fd9cb8e041a3101dce1900ef2d/490e9d65133979294cddd4d33d79d1a2.webp)
折线图
data1.head()
![](https://filescdn.proginn.com/79e6058b15707c6a6f1fa98650f16cd0/9400bdcf4630803e628341e88424eb62.webp)
data1["序号"]=data1.学校.str.extract('(\d+)')
data1
![](https://filescdn.proginn.com/1d5287ac62da9415769ba0edf2271a0e/8ad7081ffd89da8fccf69a1dfab05cb5.webp)
![](https://filescdn.proginn.com/9606b00a60ec5c213889e80f133e077b/e33e7461be8cdb61b69880aaff63dc97.webp)
ser1 = data1.序号
ser1
得到输出:
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
10 1
11 20
12 21
13 2
14 3
15 4
16 5
17 6
18 7
19 8
20 9
Name: 序号, dtype: object
接着:
ser1 = ser1.astype("int")
ser1
得到输出:
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
10 1
11 20
12 21
13 2
14 3
15 4
16 5
17 6
18 7
19 8
20 9
Name: 序号, dtype: int32
可以尝试删除序号列,并且重设索引列:
del data1["序号"]
data1.index = ser1
data1
![](https://filescdn.proginn.com/2cde8e0d6b518bab3ad4322c03e61918/a4037c65a1b4cda7646018d5cc2d7315.webp)
![](https://filescdn.proginn.com/af66e06b3870fcf75dfd50da0dc8d27f/e1226161b1e4b4ad6f91065f946703b9.webp)
再按照索引排序,可得到相应结果:
data1=data1.sort_index()
data1
![](https://filescdn.proginn.com/99a05226ba60ac7f128cb5f3577e336d/f7dc2ae6aa6f209ed9d22270f1b30bc9.webp)
![](https://filescdn.proginn.com/b0ed2c368c8483019a8707040e3ac4f4/f916a5548fe9a62a0062adabb65328aa.webp)
接着查看一共有多少行数据作为x轴数据
len(data1) # 21
再将各科成绩数据进行绘图,得到折线图结果:
plt.figure(figsize=(10,4))
plt.plot(range(21),data1.iloc[:,1],'-*') #选取语文成绩数据
plt.plot(range(21),data1.iloc[:,2],'-o') #选取数学成绩数据
plt.plot(range(21),data1.iloc[:,3],'-v') #选取英语成绩数据
plt.title('各学科成绩变化走势图')
plt.xlabel('各学校')
plt.ylabel('学科成绩')
plt.xticks(range(21),data1["学校"],rotation=30) #rotation=30控制文字倾斜角度
plt.legend(['语文','数学','英语']);
![](https://filescdn.proginn.com/82144bef3c6a7828fb4e920799c544bb/49f58ee369c565e5b0fbf9c93c8fe904.webp)
直方图
yw = data1.loc[:,"学校":"语文"] #提取数据绘制直方图,直方图原理,每个需要被画图的标签对应一个数值
yw = yw.T
yw
![](https://filescdn.proginn.com/4986329d4f87eadf49cbff43156d50c1/6ec1ee13dcb04b4262816f91af0a8444.webp)
yw.columns = yw.iloc[0] #将学校字段转换成列索引
yw1 = yw.drop("学校",axis=0) #删多余的行信息
yw1
![](https://filescdn.proginn.com/adfa5ab60ed95c31478895770fb1bdd7/2e8b506cd80a8952642d888af5858352.webp)
再将语文成绩数据进行绘图,得到直方图结果:
# 每个学校语文平均成绩的直方图
plt.figure(figsize=(12,4))
plt.bar(range(21),yw.loc["语文",:],width=0.5)
plt.title("语文成绩直方图",fontsize = 14)
plt.ylabel("语文成绩",fontsize = 14)
plt.xticks(range(21),yw.iloc[0],rotation=30,fontsize = 12); #x轴刻度为各学校名称
![](https://filescdn.proginn.com/2ec8b94a5e4b0970df128443cdc37831/902d1ae5b7c8066f0894c0871319387f.webp)
sx = data1.loc[:,["学校","数学"]]
sx = sx.T
sx
![](https://filescdn.proginn.com/e19345861558e01cb8991c46db3fc8ff/5ef9c0560fabe5e13ebe4964b0f58e7f.webp)
sx.columns = sx.iloc[0]
sx = sx.drop("学校",axis=0)
sx
![](https://filescdn.proginn.com/e93fca4ed5e1f44071cbc5d5a4e2c1aa/3cd9bf3da01b096f0b051277d194ab78.webp)
再将数学平均成绩数据进行绘图,得到直方图结果:
# 每个学校数学平均成绩的直方图
plt.figure(figsize=(12,4))
plt.bar(range(21),sx.loc["数学",:],width=0.5)
plt.title("数学成绩直方图",fontsize = 14)
plt.ylabel("数学成绩",fontsize = 14)
plt.xticks(range(21),yw.iloc[0],rotation=30,fontsize = 12); #x轴刻度为各学校名称
![](https://filescdn.proginn.com/e61e79218c9bd13fa69d35dc72059964/bb160f5fc02ce0345a6be349fe54b344.webp)
将多个学科成绩画到一副图中
data1
![](https://filescdn.proginn.com/94d87a8c810bfd1fe289458efe6da0d9/d6b13320a573df3143efb8ed4ecf4cd1.webp)
![](https://filescdn.proginn.com/f2fed6ae341d5fd2b2edf0b3debeef02/2fb5b0ea16cb2639bf53ebff0f023202.webp)
data2 = data1.drop("总分",axis = 1) #新建一个dataframe,删掉总分列,因为总分和单科成绩相差太多,影响绘图效果
data2.head()
![](https://filescdn.proginn.com/d4ad7ec9547f0425975e1c51dae7f7d5/0d85ab9ea2e5835c3653f3637c97de60.webp)
# 将多个学科成绩画到一张图中 #截取前十
data2.plot.bar(x = '学校',y = ['语文','数学','英语'],figsize=(16,6),width=0.7,rot = 30,title = "各学科成绩直方图"); #rot空值标签倾斜程度
![](https://filescdn.proginn.com/b4bad64e16d90eb040fed71d381ff802/9630c8c394f7a028368f5b8ee201e308.webp)
饼图
data2.head()
![](https://filescdn.proginn.com/3251bb1fcfb9cd061e72007128f85737/334a1f08372f52a39e4a93ab476532fa.webp)
plt.figure(figsize=(4,4),dpi=80)
plt.pie(data2.iloc[0,1:] #选取数据源
,labels=['语文','数学','英语']
,autopct='%1.2f') #设置百分比经度
# ,explode=[0.1,0.02,0.02] #设置饼图各个扇区之间的间隙
# ,colors=['r','g','b']) #设置饼图各个扇区的颜色
plt.title('第1小学各学科成绩占比',fontsize=12);
#fontsize设定字体的大小,xlabel,ylabel,title里面都可以设定
![](https://filescdn.proginn.com/8d09426de7de3a68afeb47aabccf042c/6a8a4ad41eb2e6ae53eae57fdbb354c1.webp)
pic2 = plt.figure(figsize=(8,8),dpi=80)
fig1 = pic2.add_subplot(2,2,1) #第一个子图
plt.pie(data2.iloc[0,1:] #选取数据源 第10小学各学科成绩
,labels=['语文','数学','英语']
,autopct='%1.2f') #设置百分比经度
# ,explode=[0.1,0.02,0.02] #设置饼图各个扇区之间的间隙
# ,colors=['r','g','b']) #设置饼图各个扇区的颜色
plt.title('第1小学各学科成绩占比',fontsize=12)
fig2 = pic2.add_subplot(2,2,2) #第二个字图
plt.pie(data2.iloc[1,1:] #选取数据源,第11小学各学科成绩
,labels=['语文','数学','英语']
,autopct='%1.2f') #设置百分比经度
# ,explode=[0.1,0.02,0.02] #设置饼图各个扇区之间的间隙
# ,colors=['r','g','b']) #设置饼图各个扇区的颜色
plt.title('第2小学各学科成绩占比',fontsize=12)
fig3 = pic2.add_subplot(2,2,3) #第二个字图
plt.pie(data2.iloc[2,1:] #选取数据源,第12小学各学科成绩
,labels=['语文','数学','英语']
,autopct='%1.2f') #设置百分比经度
# ,explode=[0.1,0.02,0.02] #设置饼图各个扇区之间的间隙
# ,colors=['r','g','b']) #设置饼图各个扇区的颜色
plt.title('第3小学各学科成绩占比',fontsize=12)
fig4 = pic2.add_subplot(2,2,4) #第二个字图
plt.pie(data2.iloc[3,1:] #选取数据源,第13小学各学科成绩
,labels=['语文','数学','英语']
,autopct='%1.2f') #设置百分比经度
# ,explode=[0.1,0.02,0.02] #设置饼图各个扇区之间的间隙
# ,colors=['r','g','b']) #设置饼图各个扇区的颜色
plt.title('第4小学各学科成绩占比',fontsize=12);
![](https://filescdn.proginn.com/6602a869b9b1964eb14f88d5d95da6ad/f6e1644ef273c8789223b26a5c5660f1.webp)
箱型图
data.head()
![](https://filescdn.proginn.com/e20078f52a1d8d55b76fbc31e83e648a/5a9fb052449ee783cb704ba5d607f42e.webp)
data_1 = data.loc[data['学校'] =="第1小学"] #提取第一小学的所有信息
score = (list(data_1.iloc[:,2]),list(data_1.iloc[:,3]),list(data_1.iloc[:,4]))
plt.figure(figsize=(8,6))
plt.boxplot(score
,labels=['语文','数学','英语']
,notch=True #缺口中位数位置
,sym='*'#设定异常值的形状
,whis=1.5); #设定几倍标准差之外的数据算是异常值,默认是1.5
![](https://filescdn.proginn.com/11a09dca0a434ecf326ecbac543057d4/e577ffd7be0cda19b81c6ce70dac80d5.webp)
泰坦尼克号数据
text = pd.read_csv(r'result.csv')
text.head()
![](https://filescdn.proginn.com/42dd24fd117f0e8e83522273930b53fc/bd47cadc2dce10b2cb42d6c6b9db702a.webp)
男女中生存人数分布情况
sex = text.groupby('Sex')['Survived'].sum()
sex.plot.bar(color='chocolate')
plt.title('survived_count')
plt.show()
![](https://filescdn.proginn.com/7663410d1f478efb756670b108d707b5/ab32cd84addf7fffb2de506784bd1082.webp)
女性比男性生存人数多。
男女中生存人与死亡人数的比例
text.groupby(['Sex','Survived'])['Survived'].count().unstack().plot(kind='bar',stacked='True')
plt.title('survived_count')
plt.ylabel('count')
# Text(0, 0.5, 'count')
![](https://filescdn.proginn.com/13521d3685b2cea9d3c5bf58a50b16e6/94e78b6e2a4cd95f8f236281702ee3ae.webp)
男女性生存与死亡人数的占比偏差比较大。
不同票价的人生存和死亡人数分布情况
# 排序后绘折线图
fare_sur = text.groupby(['Fare'])['Survived'].value_counts().sort_values(ascending=False)
fig = plt.figure(figsize=(20, 18))
fare_sur.plot(grid=True)
plt.legend()
plt.show()
![](https://filescdn.proginn.com/d3c9bae3b6fe7e41f8fcf989bbd19257/f5310e94594f0ac3de4f228afa791c10.webp)
不同的票价所反映出来的生存人数是非常明显的,票价低的人死亡数量高是因为离甲板远,且逃生机会大大降低。
# 排序前绘折线图
fare_sur1 = text.groupby(['Fare'])['Survived'].value_counts()
fig = plt.figure(figsize=(20, 18))
fare_sur1.plot(grid=True)
plt.legend()
plt.show()
![](https://filescdn.proginn.com/90be3fc92311ed75be638c1b1dec3373/e225204456c327792bf71b36e80082da.webp)
不同仓位等级的人生存和死亡人员的分布情况
# 1表示生存,0表示死亡
pclass_sur = text.groupby(['Pclass'])['Survived'].value_counts()
import seaborn as sns
sns.countplot(x="Pclass", hue="Survived", data=text)
#
![](https://filescdn.proginn.com/a48eedad842918ff44d3d74270a1efd9/ccc89a7bd47725cc3a2b554ad4cc0088.webp)
facet = sns.FacetGrid(text, hue="Survived",aspect=3)
facet.map(sns.kdeplot,'Age',shade= True)
facet.set(xlim=(0, text['Age'].max()))
facet.add_legend()
#
![](https://filescdn.proginn.com/c60913f924598833857975590d3d82a9/81ff20edc7c50449648503cbb17e06ba.webp)
text.Age[text.Pclass == 1].plot(kind='kde')
text.Age[text.Pclass == 2].plot(kind='kde')
text.Age[text.Pclass == 3].plot(kind='kde')
plt.xlabel("age")
plt.legend((1,2,3),loc="best")
#
![](https://filescdn.proginn.com/b6124b377053e015a81addad865dadd7/5ca2f320d43cf383eb12e8289d8b2dcd.webp)
评论