您的位置:首页 > 编程语言 > Python开发

Python 数据分析微专业课程--项目05 多场景下的图表可视化表达

2018-09-03 21:49 831 查看

1.项目说明

分析2016年奥运运动员数据,使用多种图表方式对多个指标进行可视化展示并进行分析

2.项目具体要求

1、分男女分别分析运动员的身高分布,并制作图表,数据为“奥运运动员数据.xlsx,sheet → 运动员信息”
要求:
① 制作分布密度图
② 计算出男女平均身高,并绘制辅助线表示
2、综合指标判断运动员的身材,并找到TOP8的运动员,并制作图表,数据为“奥运运动员数据.xlsx,sheet → 运动员信息”
要求:
① 针对不同指标,绘制面积堆叠图
② TOP8的运动员,绘制雷达图表示
3、根据运动员CP数据,分析出CP综合热度,通过python处理数据并导出,在Gephi中绘制图表,数据为“奥运运动员数据.xlsx,sheet → 运动员CP热度”
要求:
① 用python计算出综合热度指标
② 用Gephi绘制关系可视化图表

3.实现思路:

1.根据性别筛选男女运动员数据,并制作分布密度图,这里可使用plt.hist()或者sns.distplot()来绘制男女运动员身高分布密度图,
使用plt.axvline()来绘制男女平均身高辅助线。
2.判断运动员身材的指标可以使用以下四个指标:
a. BMI 指数(BMI =体重kg ÷ 身高m**2)→ 越接近22分数越高
b. 腿长/身高 指数 → 越大分数越高
c. 臂展/身高 指数 → 比值越接近1分数越高
d. 年龄 指数 → 年龄越小分数越高
综合指标:finalscore = (n1 + n2 + n3 + n4)/4
因此首先需要筛选出运动员的年龄,体重,身高,臂展,腿长数据,然后计算各个指标,对各个指标进行O-1标准化
然后计算综合指标绘制堆叠图,方法:data.plot.area();
用不同指标评价某一事物可以使用雷达图表示,这里需要筛选数TOP8的运动员个指标数据,然后循环绘制子雷达图,
绘制雷达图方法:plt.polar(),用颜色递减表示排名递减,颜色生成方法:plt.cm.BuPu_r(np.linspace())
3.根据’运动员CP热度’表格可以使用以下三个指标评判运动员CP综合热度
a. cp微博数量 → 数量越多分数越高
b. cp微博话题阅读量 → 阅读量越多分数越高
c. B站cp视频播放量 → 播放量越大分数越高
首先读取’运动员CP热度’表格数据,然后对进行0-1标准化,并作加权平均作为最后评分:finalscore = n1*0.5 + n2*0.3 + n3*0.2
将数据保存为固定格式csv文件,用于Gephi做关系可视化分析。

4.实现过程:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

sns.set_style('whitegrid')
sns.set_context('paper')
import warnings
warnings.filterwarnings('ignore')
sns.set_style({"font.sans-serif":['simhei','Droid Sans Fallback']})

#读取运动员信息sheet数据,并对数据进行整理和清洗
df = pd.read_excel(r'D:\IT\python数据分析师\项目6\奥运运动员数据.xlsx',sheet_name = '运动员信息')
sg_data = df[['name','gender','height']]  #获取运动员姓名,性别,身高数据
print(sg_data.dtypes)
print(sg_data.info())

#制作分布密度图 seaborn
plt.figure(figsize = (12,8))  #设置绘图大小
f_sg = sg_data[sg_data['gender'] == '女']['height']  #女运动员身高数据
m_sg = sg_data[sg_data['gender'] == '男']['height']  #男运动员身高数据
sns.distplot(f_sg,hist = False,kde = True, rug = True,norm_hist=True,label = 'female_height',
kde_kws={'linestyle':'--','color':'r','alpha':0.6})
#绘制女运动员身高分布密度图

sns.distplot(m_sg,hist = False,kde = True, rug = True,norm_hist=True,label = 'male_height',
kde_kws = {'linestyle':'--','color':'b','alpha':0.6},
rug_kws={'height':0.1})
#绘制男运动员身高分布密度图

plt.axvline(x = f_sg.mean(),linestyle = '--',color = 'r',linewidth = 2,alpha = 0.7)
plt.text(f_sg.mean()+3, 0.005,'female_height_mean:%.2f' % f_sg.mean(),fontsize = 12,color = 'red')
#绘制女运动员平均身高线

plt.axvline(x = m_sg.mean(),linestyle = '--',color = 'b',linewidth = 2,alpha = 0.7)
plt.text(m_sg.mean()+3, 0.007,'male_height_mean:%.2f'% m_sg.mean(),fontsize = 12,color = 'blue')
#绘制男运动员平均身高线

plt.grid(linestyle = '--') #设置网格线
plt.legend(fontsize = 12) #设置图例字体大小

说明:这里使用seaborn.distplot()来绘制密度图,相比使用matplotlib,该方法的设置更加丰富,可以绘制hist,kde,rug,
可以对着三个要素分别进行设置。男女平均身高线和文本标注使用matplotlib方法绘制。
seaborn是偏向于统计作图,少数几个方法就可以完成比较复杂的统计和作图,但是绘图方式有限,不够灵活。
matplotlib是python的基础图表可视化的库,绘制方式丰富,所以在进行数据可视化作图时可以根据不同情况使用seaborn和matplotlib.
由于seaborn是基于matploblib进行开发封装的,所以可以在一个绘图对象中同时使用。
根据对男女运动员的身高分布进行可视化分析可知男运动员整体身高都高于女性远动员,男运动员身高分布呈现正偏态分布,女性成负偏态分布。

#① 针对不同指标,绘制面积堆叠图
import datetime
n_df = df[['name','gender','birthday','height','weight','arm','leg']]
n_df.dropna(inplace=True)
#获取运动员基本数据,去除空值

n_df['age'] = datetime.date.today().year-n_df['birthday'].apply(lambda x:x.year) #计算运动员年龄
n_df['BMI'] = n_df['weight']/((n_df['height']/100)**2)  #计算BMI指数
n_df['leg/h'] = n_df['leg']/n_df['height']  #腿长/身高比值
n_df['arm/h'] = n_df['arm']/n_df['height'] #臂长/身高比值
re_df = n_df.loc[(n_df['leg/h'] <0.7)&(n_df['arm/h']>0.7),['name','gender','age','BMI','leg/h','arm/h']] #数据筛选 leg/h<0.7,arm/h>0.7

re_df['BMI'] = np.abs(n_df['BMI']-22) #BMI-22,越小分数越高
re_df['arm/h'] = np.abs(n_df['arm/h']-1) #arm/h-1绝对值,越小分数越高

re_df['age_nor'] = (re_df['age'].max()-re_df['age'])/(re_df['age'].max()-re_df['age'].min()) #年龄越小分数越高
re_df['BMI_nor'] = (re_df['BMI'].max()-re_df['BMI'])/(re_df['BMI'].max()-re_df['BMI'].min()) #BMI越接近22,分数越高
re_df['leg_nor'] = (re_df['leg/h']-re_df['leg/h'].min())/(re_df['leg/h'].max()-re_df['leg/h'].min())#leg/h越大,分数越高
re_df['arm_nor'] = (re_df['arm/h'].max()- re_df['arm/h'])/(re_df['arm/h'].max()-re_df['arm/h'].min())#arm/h 越接近1,分数越高

re_df['finalscore'] = (re_df['age_nor'] +re_df['BMI_nor']+re_df['leg_nor']+re_df['arm_nor'])/4 #最后评分

n_data = re_df.sort_values(by = 'finalscore',ascending=False)
n_data =n_data.iloc[:,6:10].reset_index(drop = True)
#作图数据

n_data.plot.area(colormap = 'GnBu',figsize = (14,8),alpha = 0.7,xlim = (0,200),ylim = (0,4.0))
plt.legend(fontsize = 12)
#df.plot.area() 作面积图

说明:
1.这里按运动员的身材指标标准化之后的值做面积图,标准化计算中要求值越小越好计算方法为(max-x)/(max-min),要求值越大越好计算方法为(x-min)/(max-min),若越接近某个值,可以先计算与该值相减后的绝对值,然后按越小越好来计算。
2.面积图最好用于研究随时间变化数量变化的趋势,在这里我们使用面积图来研究运动员综合得分排序情况下的各个指标的变化情况。
3.由图可知对综合得分影响较大的主要是年龄指标和BMI指标,其中年龄指标随着排名越来越低,BMI指标波动幅度较大,对综合得分影响相对较大。

#② TOP8的运动员,绘制雷达图表示
top_data = re_df.sort_values(by='finalscore',ascending=False).reset_index(drop = True)
top_data = top_data.loc[0:7,['name','leg_nor','BMI_nor','age_nor','arm_nor','finalscore']]

plt.figure(figsize =(16,8))
plt.subplots_adjust(wspace = 0.4,hspace =0.4)

labels = np.array(['腿长/身高','BMI','年龄','臂长/身高'])
angles = np.linspace(0,2*np.pi,4,endpoint = False)
color = plt.cm.BuPu_r(np.linspace(0, 0.7,10))
t = 0

for i in top_data['name'].tolist():
t +=1
ax = plt.subplot(2,4,t,projection = 'polar')
datai = top_data[['leg_nor','BMI_nor','age_nor','arm_nor']][top_data['name'] ==i].T
finalscore_i = top_data['finalscore'][top_data['name'] ==i]
plt.polar(angles,datai,'o-',linewidth = 1,color = color[t-1])
ax.fill(angles,datai,color = color[t-1],alpha = 0.4)
ax.set_thetagrids(np.arange(0.0,360.0,90,),labels)
ax.set_rgrids(np.arange(0.2,1.5,0.2),'--')
plt.title('Top%i %s: %.3f' % (t,i,finalscore_i),pad = 20)

说明:
1.雷达图比较适用于多维度分析某个事物,这里使用雷达图从四个维度来展现一个远动员的身材,使用子图循环绘制top8运动员的身材雷达图。
2.雷达图的绘图两个主要的参数是坐标角度和数值,角度个数和数值个数要一致,除此之外还需要设置极坐标网格线,标签,角度偏移方向(顺时针或逆时针),网格线范围,极值范围等,雷达图填充颜色是坐标角度和数值连个参数必须可对应的雷达图一致。
3.通过雷达图可知综合得分高的运动员的各项指标的得分都比较高,随着综合得分降低可以看到指标中出现明显的短板,或者各项平均但是没有长处。

#用python计算出综合热度指标
rd_data = pd.read_excel(r'D:\IT\python数据分析师\项目6\奥运运动员数据.xlsx',sheet_name = '运动员CP热度')
rd_data.dropna(inplace = True)
rd_data.replace('无数据',0,inplace= True)
rd_data['wb_nor'] = (rd_data['cp微博数量']-rd_data['cp微博数量'].min())/(rd_data['cp微博数量'].max()-rd_data['cp微博数量'].min())
rd_data['yd_nor'] = (rd_data['cp微博话题阅读量']-rd_data['cp微博话题阅读量'].min())/(rd_data['cp微博话题阅读量'].max()-rd_data['cp微博话题阅读量'].min())
rd_data['B_nor'] = (rd_data['B站cp视频播放量']-rd_data['B站cp视频播放量'].min())/(rd_data['B站cp视频播放量'].max()-rd_data['B站cp视频播放量'].min())
rd_data['finalscore'] = rd_data['wb_nor']*0.5+rd_data['yd_nor']*0.3+rd_data['B_nor']*0.2
rd_data_save = rd_data[['p1','p2','finalscore']]
rd_data_save.to_csv(r'D:\IT\python数据分析师\项目6\cp.csv',index = False,encoding = 'gbk')

说明:
1.这里使用Gephi来做关系可视化绘图和分析,用’cp微博数量’,’cp微博话题阅读量’,’B站cp视频播放量’三个指标做标准化后进行加权平均,用最后的结果作为运动员关系热度的综合指标,保存为’p1’,’p2’,’finalscore’格式CSV文件上传Gephi.
2.Gephi中布局模式选择“ForceAtlas2”,然后Gephi中通过模块化计算,给关联结果做分组,并且以此分组设定点颜色,按照连接度和综合热度进行排序,设置点大小和标签大小。设置完成后可以直观看到运动员之间关系情况,可以得到以下几点:
a.同一运动项目的运动员形成一个关系群,不同项目运动员连接度很弱。
b.明星运动员的热度越高,连接度也高。其中游泳队队员的模块相对较大,热度较高。

5.总结

  • 该项目主要是对数据可视化的运用,不仅包括python的可视化库,还包括其他做可视化分析的软件,这里运用的是Gephi做关系数据可视化。
  • 除了Gephi之外还有echarts做空间可视化,QGIS做地理空间分析可视化,bokeh基于网页的画图工具库。
  • 通过该项目的完成对使用多种可视化工具对实际问题进行分析有了一个清晰的认识,可视化是分析的重要手段,从各种图表中获得相应的结论才是目的。
    只有通过完成各种分析项目才能逐步工具使用的熟练度和深度。
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐