基于Python对奥运历史运动员和成绩的数据分析

一、数据说明

1、背景介绍

       该数据集是现代奥运会的历史数据集,包括从1896年雅典奥运会到2016年里约奥运会的所有奥运会。

       需要注意的是,冬季和夏季奥运会在同一年举行,直到1992年。在那之后,他们错开了它们,以便冬季奥运会以四年为周期举行,从1994年开始,然后是1996年的夏季,然后是1998年的冬季,依此类推。人们在分析这些数据时常犯的一个错误是假设夏季和冬季奥运会一直是错开的。

       本篇主要是基于120年的奥运历史:运动员和成绩这个数据集去进行探索,对数据进行清洗分析,然后对数据进行可视化分析,通过作图来展现这份数据的不同方面。如,奥运会参赛人数的变化、运动选手男女的比例、运动选手的年龄身高体重等等。

2、数据内容

文件athlete_events.csv包含 271116 行和 15 列。每排对应一名参加个人奥运项目(运动员项目)的运动员。这些列是:

  1. ID - 每个运动员的唯一编号
  2. 姓名 - 运动员姓名
  3. 性别 - M 或 F
  4. 年龄 - 整数
  5. 高度 - 以厘米为单位
  6. 重量 - 以公斤为单位
  7. 团队 - 团队名称
  8. NOC - 国家奥委会 3 个字母代码
  9. 游戏 - 年份和季节
  10. 年份 - 整数
  11. 季节 - 夏季或冬季
  12. 城市 - 主办城市
  13. 体育 - 运动
  14. 事件 - 事件
  15. 奖牌 - 金牌、银牌、铜牌或 NA

3、数据来源

该数据集包含两个文件,分别为athlete_events.cdv(参赛运动员基本数据)、noc_regions.csv(国家奥委会3个字母的代码与对应国家信息)

来源于kaggle*台用户的分享

具体信息内容源自:奥运120年历史:运动员与成绩 |卡格尔 (kaggle.com)

 二、数据可视化分析

首先将数据进行导入并分别读取打印出两个表格的前五排

#读取文件并打印出前五排
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from pyecharts.charts import *
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode

plt.style.use('ggplot')

athlete_data = pd.read_csv('C:/Users/Ethereal/python文本/athlete_events.csv')
noc_data = pd.read_csv('C:/Users/Ethereal/python文本/noc_regions.csv')
athlete_data.head(5)

 

#读取noc_data数据前五排
noc_data.head(5)

 为了对数据更好的进行可视化,将athlete_data和noc_data两个文件中的数据进行合并,并打印出前五行,结果如下:

#合并两个文件中的数据
data=pd.merge(athlete_data,noc_data,on='NOC',how='left')
data.head(5)

#查看athlete_data中是否有缺失值
data.info()

 通过上面输出结果可以得知,合并后的新数据并没有缺失值,所以无需进行缺失值处理。

#重复值处理
#设置保留最后一个值
data.drop_duplicates()

接下来开始对数据进行分析

#奥运会参赛人数变化
plt.figure(figsize=(16,5))
sns.countplot('Year',data=data,hue='Season',palette='Set2')
plt.xticks(np.arange(0,len(data.Year.unique()),2))
plt.legend(loc='upper left')
plt.title("奥运会参赛人数变化")
plt.show()

 从图中可以看出,参加奥运会的人数在逐渐增加,直到1996年开始人数逐渐趋于*稳。

#饼图
#历届奥运会男女比例
m_f_ration=data.drop_duplicates()
m_f_ration=m_f_ration.groupby(by="Sex")["Sex"].count()
m_f_ration=m_f_ration/m_f_ration.sum()*100
sex_data=[z for z in zip(m_f_ration.index,m_f_ration)]
pie = (Pie()
       .add('', sex_data,radius=["20%", "55%"])
       .set_global_opts(
        title_opts=opts.TitleOpts(title="历届奥运会男女比例",pos_left='center'),
        legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
        )
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
        )
pie.render_notebook()

 通过对所有奥运会运动员男女分别求和,后可得出历届奥运会男女运动员的比例。通过可视化知,女运动员占历届奥运会运动员的27.57%,男运动员占总体数量的72.43%。因为早期奥运会由于社会等原因导致参加奥运会的女性太少,以至于分析男女比例时差距巨大。

#奥运会运动员年龄
age_distribute=data.dropna(subset=['Age'])
age_distribute.Age.describe()

 接着对奥运会运动员的年龄进行分析,通过运行结果可得在这120年奥运会中最小运动员的年龄仅10岁,最大年龄的运动员有97岁。

#查看各个项目小于18岁的人数
data[data.Age<18].Sport.value_counts()[:5]

        通过了解得到,体操组织设定的年龄下限为16岁,也就是说16岁以下的运动员不得参加奥运体操,而跳水年龄的下限为14岁。在查看每个运动项目小于18岁的运动员中,游泳项目和体操18岁以下的运动员人数是比较多的,因为在游泳体操这类对身材体重要求较为严格的项目,而有一个不可阻挡的生理规律,只有少数运动员能突破发育关,在女子身上体现尤为明显,熬不过发育关的女孩子就会无可奈何地失去上奥运会的资格。所以游泳和体操项目的运动员年龄较小的会比较多。

#查看运动员年龄分布
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
plt.figure(figsize=(18,7))
sns.boxplot('Year','Age',data=data,hue='Sex',color='pink')
plt.title('运动员年龄分布')
plt.show()

        通过上面的箱型图可以看出,在这120年中的运动员选手的年龄大致都分布在17岁--30岁之间,整个跨度很大,从10岁到97岁的都有,大致是呈正态分布。从时间上看,*几十年运动员的年龄趋向于*稳,并且女性运动员的年龄比男性运动员年龄略低。

#奥运选手身高体重
WeightHeight_data = data.dropna(subset=['Weight','Height'])
plt.figure(figsize=(8,6))
sns.regplot('Weight','Height',data=WeightHeight_data,
            scatter_kws={'facecolor':'yellow','edgecolor':'maroon'},
            line_kws={'color':'k'})
plt.title('运动员身高体重')
plt.show()

 从上面图中可以看出,运动员的身高在140--220cm之间,体重在25--150kg之间,基本上是符合线性关系的,并且相关系数达到0.796。

#观察身高体重的线性关系
WeightHeight_data[['Weight','Height']].corr()
#相关系数达到0.796213,可以看出运动员的身高体重基本附和线性关系

 

#查看这些年运动员的体重变化
plt.figure(figsize=(17,7))
tmp1 = data[data.Season=='Summer']
sns.pointplot('Year','Weight',data=tmp1,hue='Sex',palette=sns.set_palette(['deepskyblue','orange']))
plt.title('120年中运动员体重变化') 

 在对运动员体重进行可视化中,可以明显看出男性运动员的体重比女性运动员重。而且随着时间的推移,发现运动员的体重在逐渐升高然后趋*于*稳。

#查看这些年运动员的身高变化
plt.figure(figsize=(17,7))
tmp2 = data[data.Season=='Summer']
sns.pointplot('Year','Height',data=tmp2,hue='Sex',palette=sns.set_palette(['deepskyblue','orange']))
plt.title('120年中运动员身高变化') 

 在对运动员的体重进行可视化中,男性运动员的身高同样大于女性运动员的身高,在开始一段时间波折后也成上升趋势然后逐渐趋于*稳。

#获得奖牌最多的运动员

temp = data[(data['Medal'] == 'Gold')]

athlete = temp.groupby(['Name'])['Medal'].count().reset_index()
athlete.columns = ['Name', 'Nums']
athlete = athlete.sort_values(by="Nums")

pb = (
PictorialBar(init_opts=opts.InitOpts(bg_color='lavender', width='1000px', height='750px'))
.add_xaxis([x.replace(' ', '\n') for x in athlete['Name'].tail(10).tolist()])
.add_yaxis(
"",
athlete['Nums'].tail(10).tolist(),
label_opts=opts.LabelOpts(is_show=False),
symbol_size=26,
symbol_repeat='fixed',
symbol_offset=[0, 0],
is_symbol_clip=True,
symbol='image://https://cdn.kesci.com/upload/image/q8f8otrlfc.png')
.reversal_axis()
.set_global_opts(
title_opts=opts.TitleOpts(title="获得金牌数量最多的运动员", pos_left='center',
title_textstyle_opts=opts.TextStyleOpts(color="black", font_size=20), ),
xaxis_opts=opts.AxisOpts(is_show=False),
yaxis_opts=opts.AxisOpts(
axistick_opts=opts.AxisTickOpts(is_show=False),
axisline_opts=opts.AxisLineOpts(
linestyle_opts=opts.LineStyleOpts(opacity=0)
),
),
))

pb.render_notebook()

 通过上面运行结果可知,在1896年--2016年中获得金牌最多的运动员为Michael Fred Phelps,他在自己的奥运生涯中共获得了23金3银2铜的成绩。

#获得奖牌的比例
total_athlete = len(set(data['Name']))
medal_athlete = len(set(data['Name'][data['Medal'].isin(['Gold', 'Silver', 'Bronze'])]))
gold_athlete = len(set(data['Name'][data['Medal'] == 'Gold']))

bl = Liquid(init_opts=opts.InitOpts(theme='dark', width='250px', height='200px'))
bl.add("获得奖牌", [medal_athlete / total_athlete],
       label_opts=opts.LabelOpts(font_size=50,
                                 formatter=JsCode(
                                     """function (param) {
                                             return (Math.floor(param.value * 10000) / 100) + '%';
                                         }"""),
                                 position="inside",
                                 ))
bl.set_global_opts(title_opts=opts.TitleOpts(title="获得过奖牌比例", pos_left='center',pos_top='15%'))
bl.set_series_opts(tooltip_opts=opts.TooltipOpts(is_show=False))

 
grid = Grid().add(bl, grid_opts=opts.GridOpts())
grid.render_notebook()

#获得金牌比例
bl = Liquid(init_opts=opts.InitOpts(theme='dark', width='1000px', height='800px'))
bl.add("获得金牌",
       [gold_athlete / total_athlete],
       center=["25%", "50%"],
       label_opts=opts.LabelOpts(font_size=50,
                                 formatter=JsCode(
                                     """function (param) {
                                             return (Math.floor(param.value * 10000) / 100) + '%';
                                         }"""),
                                 position="inside",
                                 ), )
bl.set_global_opts(title_opts=opts.TitleOpts(title="获得过金牌比例", pos_left='18%',pos_top='15%'))
bl.set_series_opts(tooltip_opts=opts.TooltipOpts(is_show=False))

grid = Grid().add(bl, grid_opts=opts.GridOpts())
grid.render_notebook()

 

 

获得过奖牌比例和获得过金奖比例这两个结果可知,获得过奖牌比例为20.93%而获得过金奖比例则更加少只有7.72%。

#获取各项运动产生金牌数

medal_data = data.groupby(['Year', 'Season', 'region', 'Medal'])['Event'].nunique().reset_index()
medal_data.columns = ['Year', 'Season', 'region', 'Medal', 'Nums']
medal_data = medal_data.sort_values(by="Year", ascending=True)
 
background_color_js = """new echarts.graphic.RadialGradient(0.5, 0.5, 1, [{
                                        offset: 0,
                                        color: 'darkgrey'
                                    }, {
                                        offset: 1,
                                        color: 'dimgrey'
                                    }])"""
 
tab = Tab()
temp = data[(data['Medal'] == 'Gold') & (data['Year'] == 2008) & (data['Season'] == 'Summer')]
 
event_medal = temp.groupby(['Sport'])['Event'].nunique().reset_index()
event_medal.columns = ['Sport', 'Nums']
event_medal = event_medal.sort_values(by="Nums", ascending=False)
 
pie = (Pie(init_opts=opts.InitOpts(bg_color=JsCode(background_color_js), width='1000px', height='800px'))
       .add('金牌', [(row['Sport'], row['Nums']) for _, row in event_medal.iterrows()],
            radius=["30%", "75%"],
            rosetype="radius")
       .set_global_opts(title_opts=opts.TitleOpts(title="2008年夏季奥运会各项运动产生金牌占比",
                                                  pos_left="center",
                                                  title_textstyle_opts=opts.TextStyleOpts(color="white",
                                                                                          font_size=20), ),
                        legend_opts=opts.LegendOpts(is_show=False))
       .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"),
                        tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"), )
       )
tab.add(pie, '2008年夏奥会')
tab.render_notebook()

 

 2008年奥运会在我国北京举行,所以我分析了2008年夏季奥运会各项运动产生金牌的占比。由图可知,田径项目占比较大排在首位,其次是游泳类项目。

#中国历届奥运会参赛人数
#夏奥会的中国参赛人数
 
CN_data = data[data.region == 'China']
CN_data.head()

athlete = CN_data.groupby(['Year', 'Season'])['Name'].nunique().reset_index()
athlete.columns = ['Year', 'Season', 'Nums']
athlete = athlete.sort_values(by="Year", ascending=False)
 
summer_bar = (
    Bar(init_opts=opts.InitOpts(theme='dark', width='1000px', height='300px'))
    .add_xaxis([row['Year'] for _, row in athlete[athlete.Season == 'Summer'].iterrows()])
    .add_yaxis("参赛人数", [row['Nums'] for _, row in athlete[athlete.Season == 'Summer'].iterrows()],
               category_gap='40%',
               itemstyle_opts=opts.ItemStyleOpts(
                   border_color='grey',
                   color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1, 
                                             [{
                                                 offset: 1,
                                                 color: 'limegreen'
                                             }, {
                                                 offset: 0.8,
                                                 color: 'yellow'
                                             },{
                                                 offset: 0,
                                                 color: 'pink'
                                             }])""")))
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
                                               position='top',
                                               font_style='italic'))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="夏奥会中国历年参赛人数", pos_left='center'),
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
        legend_opts=opts.LegendOpts(is_show=False),
        yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff65")),
        graphic_opts=[
            opts.GraphicImage(
                graphic_item=opts.GraphicItem(
                    right=0, top=0, z=-10, bounding="raw", origin=[75, 75]
                ),
                graphic_imagestyle_opts=opts.GraphicImageStyleOpts(
                    width=1000,
                    height=600,
               ),
            )
        ], ) 
)
 
page = (
    Page()
    .add(summer_bar, )
)
page.render_notebook()

 从1932年中国只有刘长春一人抵达赛地参加,而后的几十年中因为各种原因参加人数都比较少,直到1984年中国夏奥会历年的参赛人数才迅速增加,到现在的几百人。

#冬奥会的中国参赛人数
winter_bar = (
    Bar(init_opts=opts.InitOpts(theme='dark', width='1000px', height='300px'))
    .add_xaxis([row['Year'] for _, row in athlete[athlete.Season == 'Winter'].iterrows()])
    .add_yaxis("参赛人数", [row['Nums'] for _, row in athlete[athlete.Season == 'Winter'].iterrows()],
               category_gap='50%',
               itemstyle_opts=opts.ItemStyleOpts(
                   border_color='grey',
                   color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1, 
                                             [{
                                                 offset: 1,
                                                 color: 'plum'
                                             }, {
                                                 offset: 0.8,
                                                 color: 'gold'
                                             }, {
                                                 offset: 0,
                                                 color: 'lime'
                                             }])""")))
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
                                               position='top',
                                               font_style='italic'))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="冬奥会中国历年参赛人数", pos_left='center'),
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
        legend_opts=opts.LegendOpts(is_show=False),
        yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff65")),
        graphic_opts=[
            opts.GraphicImage(
                graphic_item=opts.GraphicItem(
                    id_="logo", right=0, top=-300, z=-10, bounding="raw", origin=[75, 75]
                ),
                graphic_imagestyle_opts=opts.GraphicImageStyleOpts(
                    width=1000,
                    height=600,
                ),
            )
        ], )
)
page = (
    Page()
    .add(winter_bar, )
)
page.render_notebook()

#中国参赛人数的变化
china=data[data.region=='China']
tmp = china[china.Season=='Summer'].groupby('Year')['ID'].count()
plt.figure(figsize=(16,6))
plt.xticks(np.arange(1892,2020,8))
tmp.plot(style="-o",color='darkorange')
plt.title("中国运动员参赛人数")
plt.show()

 通过折线图更能充分展示出中国参赛人数的增加。在那120年中中国在2008年北京奥运会参赛人数达到最高,有617人参加。

#漏斗图
#中国最强项目
adv_data=data[data["Team"]=="China"].groupby(by="Sport")["Medal"].count().to_frame()
adv_data=adv_data.sort_values(by="Medal",ascending=False)[0:10]
sport_name=[str(i) for i in adv_data.index]
sports=[int(j)for j in adv_data.values]

sha = (Funnel()
          .add("", [z for z in zip(sport_name,sports)])
          )

sha.render_notebook()

 沙漏图它简单易行,非常适用于对中国优势项目的可视化。由图可知中国在体操这项较为强,其次是跳水项目。

#词云图
#中国优势项目

CN_data = data[data.region == 'China']
CN_data.head()

CN_events = CN_data[CN_data.Medal == 'Gold'].groupby(['Year', 'Sport'])['Event'].nunique().reset_index()
CN_events = CN_events.groupby(['Sport'])['Event'].sum().reset_index()
CN_events.columns = ['Sport', 'Nums']
 
data_pair = [(row['Sport'], row['Nums']) for _, row in CN_events.iterrows()]
 
cy = (WordCloud(init_opts=opts.InitOpts(bg_color='silver', width='1000px', height='600px'))
      .add("", data_pair, word_size_range=[30, 80])
      .set_global_opts(title_opts=opts.TitleOpts(title="中国获得过金牌运动项目", pos_left="center",
                                                 title_textstyle_opts=opts.TextStyleOpts(color="white", font_size=22)))
      )
 
cy.render_notebook()

 数据分析及可视化到这里就结束了,接下来就是本文的全部代码

  1 #读取文件并打印出前五排
  2 import numpy as np
  3 import pandas as pd
  4 import matplotlib.pyplot as plt
  5 import seaborn as sns
  6 from pyecharts.charts import *
  7 from pyecharts import options as opts
  8 from pyecharts.commons.utils import JsCode
  9 
 10 plt.style.use('ggplot')
 11 
 12 athlete_data = pd.read_csv('C:/Users/Ethereal/python文本/athlete_events.csv')
 13 noc_data = pd.read_csv('C:/Users/Ethereal/python文本/noc_regions.csv')
 14 athlete_data.head(5)
 15 
 16 #读取noc_data数据前五排
 17 noc_data.head(5)
 18 
 19 #合并两个文件中的数据
 20 data=pd.merge(athlete_data,noc_data,on='NOC',how='left')
 21 data.head(5)
 22 
 23 #查看athlete_data中是否有缺失值
 24 data.info()
 25 
 26 #重复值处理
 27 #设置保留最后一个值
 28 data.drop_duplicates()
 29 
 30 #查看数据的总和、*均值、标准差、最小值、最大值以及较低的百分位数
 31 athlete_data.describe()
 32 
 33 #奥运会参赛人数变化
 34 plt.rcParams['font.sans-serif']=['SimHei']
 35 plt.rcParams['axes.unicode_minus']=False
 36 
 37 plt.figure(figsize=(16,5))
 38 sns.countplot('Year',data=data,hue='Season',palette='Set2')
 39 plt.xticks(np.arange(0,len(data.Year.unique()),2))
 40 plt.legend(loc='upper left')
 41 plt.title("奥运会参赛人数变化")
 42 plt.show()
 43 
 44 #饼图
 45 #历届奥运会男女比例
 46 m_f_ration=data.drop_duplicates()
 47 m_f_ration=m_f_ration.groupby(by="Sex")["Sex"].count()
 48 m_f_ration=m_f_ration/m_f_ration.sum()*100
 49 sex_data=[z for z in zip(m_f_ration.index,m_f_ration)]
 50 pie = (Pie()
 51        .add('', sex_data,radius=["20%", "55%"])
 52        .set_global_opts(
 53         title_opts=opts.TitleOpts(title="历届奥运会男女比例",pos_left='center'),
 54         legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
 55         )
 56     .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
 57         )
 58 pie.render_notebook()
 59 
 60 #奥运会运动员年龄
 61 age_distribute=data.dropna(subset=['Age'])
 62 age_distribute.Age.describe()
 63 
 64 #查看各个项目小于18岁的人数
 65 data[data.Age<18].Sport.value_counts()[:5]
 66 
 67 #查看运动员年龄分布
 68 
 69 plt.figure(figsize=(18,7))
 70 sns.boxplot('Year','Age',data=data,hue='Sex',color='pink')
 71 plt.title('运动员年龄分布')
 72 plt.show()
 73 
 74 #奥运选手身高体重
 75 WeightHeight_data = data.dropna(subset=['Weight','Height'])
 76 plt.figure(figsize=(8,6))
 77 sns.regplot('Weight','Height',data=WeightHeight_data,
 78             scatter_kws={'facecolor':'yellow','edgecolor':'maroon'},
 79             line_kws={'color':'k'})
 80 plt.title('运动员身高体重')
 81 plt.show()
 82 
 83 #观察身高体重的线性关系
 84 WeightHeight_data[['Weight','Height']].corr()
 85 
 86 #查看这些年运动员的体重变化
 87 plt.figure(figsize=(17,7))
 88 tmp1 = data[data.Season=='Summer']
 89 sns.pointplot('Year','Weight',data=tmp1,hue='Sex',palette=sns.set_palette(['deepskyblue','orange']))
 90 plt.title('120年中运动员体重变化') 
 91 
 92 #查看这些年运动员的身高变化
 93 plt.figure(figsize=(17,7))
 94 tmp2 = data[data.Season=='Summer']
 95 sns.pointplot('Year','Height',data=tmp2,hue='Sex',palette=sns.set_palette(['deepskyblue','orange']))
 96 plt.title('120年中运动员身高变化') 
 97 
 98 #获得过奖牌最多的运动员
 99  
100 temp = data[(data['Medal'] == 'Gold')]
101  
102 athlete = temp.groupby(['Name'])['Medal'].count().reset_index()
103 athlete.columns = ['Name', 'Nums']
104 athlete = athlete.sort_values(by="Nums")
105  
106 pb = (
107     PictorialBar(init_opts=opts.InitOpts(bg_color='lavender', width='1000px', height='750px'))
108     .add_xaxis([x.replace(' ', '\n') for x in athlete['Name'].tail(10).tolist()])
109     .add_yaxis(
110         "",
111         athlete['Nums'].tail(10).tolist(),
112         label_opts=opts.LabelOpts(is_show=False),
113         symbol_size=26,
114         symbol_repeat='fixed',
115         symbol_offset=[0, 0],
116         is_symbol_clip=True,
117         symbol='image://https://cdn.kesci.com/upload/image/q8f8otrlfc.png')
118     .reversal_axis()
119     .set_global_opts(
120         title_opts=opts.TitleOpts(title="获得金牌数量最多的运动员", pos_left='center',
121                                   title_textstyle_opts=opts.TextStyleOpts(color="black", font_size=20), ),
122         xaxis_opts=opts.AxisOpts(is_show=False),
123         yaxis_opts=opts.AxisOpts(
124             axistick_opts=opts.AxisTickOpts(is_show=False),
125             axisline_opts=opts.AxisLineOpts(
126                 linestyle_opts=opts.LineStyleOpts(opacity=0)
127             ),
128         ),
129     ))
130  
131 pb.render_notebook()
132 
133 #获得奖牌的比例
134 total_athlete = len(set(data['Name']))
135 medal_athlete = len(set(data['Name'][data['Medal'].isin(['Gold', 'Silver', 'Bronze'])]))
136 gold_athlete = len(set(data['Name'][data['Medal'] == 'Gold']))
137 
138 bl = Liquid(init_opts=opts.InitOpts(theme='dark', width='250px', height='200px'))
139 bl.add("获得奖牌", [medal_athlete / total_athlete],
140        label_opts=opts.LabelOpts(font_size=50,
141                                  formatter=JsCode(
142                                      """function (param) {
143                                              return (Math.floor(param.value * 10000) / 100) + '%';
144                                          }"""),
145                                  position="inside",
146                                  ))
147 bl.set_global_opts(title_opts=opts.TitleOpts(title="获得过奖牌比例", pos_left='center',pos_top='15%'))
148 bl.set_series_opts(tooltip_opts=opts.TooltipOpts(is_show=False))
149 
150  
151 grid = Grid().add(bl, grid_opts=opts.GridOpts())
152 grid.render_notebook()
153 
154 #获得金牌
155 bl = Liquid(init_opts=opts.InitOpts(theme='dark', width='1000px', height='800px'))
156 bl.add("获得金牌",
157        [gold_athlete / total_athlete],
158        center=["25%", "50%"],
159        label_opts=opts.LabelOpts(font_size=50,
160                                  formatter=JsCode(
161                                      """function (param) {
162                                              return (Math.floor(param.value * 10000) / 100) + '%';
163                                          }"""),
164                                  position="inside",
165                                  ), )
166 bl.set_global_opts(title_opts=opts.TitleOpts(title="获得过金牌比例", pos_left='18%',pos_top='15%'))
167 bl.set_series_opts(tooltip_opts=opts.TooltipOpts(is_show=False))
168 
169 grid = Grid().add(bl, grid_opts=opts.GridOpts())
170 grid.render_notebook()
171 
172 #获取各项运动产生金牌数
173 
174 medal_data = data.groupby(['Year', 'Season', 'region', 'Medal'])['Event'].nunique().reset_index()
175 medal_data.columns = ['Year', 'Season', 'region', 'Medal', 'Nums']
176 medal_data = medal_data.sort_values(by="Year", ascending=True)
177  
178 background_color_js = """new echarts.graphic.RadialGradient(0.5, 0.5, 1, [{
179                                         offset: 0,
180                                         color: 'darkgrey'
181                                     }, {
182                                         offset: 1,
183                                         color: 'dimgrey'
184                                     }])"""
185  
186 tab = Tab()
187 temp = data[(data['Medal'] == 'Gold') & (data['Year'] == 2008) & (data['Season'] == 'Summer')]
188  
189 event_medal = temp.groupby(['Sport'])['Event'].nunique().reset_index()
190 event_medal.columns = ['Sport', 'Nums']
191 event_medal = event_medal.sort_values(by="Nums", ascending=False)
192  
193 pie = (Pie(init_opts=opts.InitOpts(bg_color=JsCode(background_color_js), width='1000px', height='800px'))
194        .add('金牌', [(row['Sport'], row['Nums']) for _, row in event_medal.iterrows()],
195             radius=["30%", "75%"],
196             rosetype="radius")
197        .set_global_opts(title_opts=opts.TitleOpts(title="2008年夏季奥运会各项运动产生金牌占比",
198                                                   pos_left="center",
199                                                   title_textstyle_opts=opts.TextStyleOpts(color="white",
200                                                                                           font_size=20), ),
201                         legend_opts=opts.LegendOpts(is_show=False))
202        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"),
203                         tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"), )
204        )
205 tab.add(pie, '2008年夏奥会')
206 tab.render_notebook()
207 
208 #夏奥会的中国参赛人数
209  
210 CN_data = data[data.region == 'China']
211 CN_data.head()
212 
213 athlete = CN_data.groupby(['Year', 'Season'])['Name'].nunique().reset_index()
214 athlete.columns = ['Year', 'Season', 'Nums']
215 athlete = athlete.sort_values(by="Year", ascending=False)
216  
217 summer_bar = (
218     Bar(init_opts=opts.InitOpts(theme='dark', width='1000px', height='300px'))
219     .add_xaxis([row['Year'] for _, row in athlete[athlete.Season == 'Summer'].iterrows()])
220     .add_yaxis("参赛人数", [row['Nums'] for _, row in athlete[athlete.Season == 'Summer'].iterrows()],
221                category_gap='40%',
222                itemstyle_opts=opts.ItemStyleOpts(
223                    border_color='grey',
224                    color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1, 
225                                              [{
226                                                  offset: 1,
227                                                  color: 'limegreen'
228                                              }, {
229                                                  offset: 0.8,
230                                                  color: 'yellow'
231                                              },{
232                                                  offset: 0,
233                                                  color: 'pink'
234                                              }])""")))
235     .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
236                                                position='top',
237                                                font_style='italic'))
238     .set_global_opts(
239         title_opts=opts.TitleOpts(title="夏奥会中国历年参赛人数", pos_left='center'),
240         xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
241         legend_opts=opts.LegendOpts(is_show=False),
242         yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff65")),
243         graphic_opts=[
244             opts.GraphicImage(
245                 graphic_item=opts.GraphicItem(
246                     right=0, top=0, z=-10, bounding="raw", origin=[75, 75]
247                 ),
248                 graphic_imagestyle_opts=opts.GraphicImageStyleOpts(
249                     width=1000,
250                     height=600,
251                ),
252             )
253         ], ) 
254 )
255  
256 page = (
257     Page()
258     .add(summer_bar, )
259 )
260 page.render_notebook()
261 
262 #冬奥会的中国参赛人数
263 winter_bar = (
264     Bar(init_opts=opts.InitOpts(theme='dark', width='1000px', height='300px'))
265     .add_xaxis([row['Year'] for _, row in athlete[athlete.Season == 'Winter'].iterrows()])
266     .add_yaxis("参赛人数", [row['Nums'] for _, row in athlete[athlete.Season == 'Winter'].iterrows()],
267                category_gap='50%',
268                itemstyle_opts=opts.ItemStyleOpts(
269                    border_color='grey',
270                    color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1, 
271                                              [{
272                                                  offset: 1,
273                                                  color: 'plum'
274                                              }, {
275                                                  offset: 0.8,
276                                                  color: 'gold'
277                                              }, {
278                                                  offset: 0,
279                                                  color: 'lime'
280                                              }])""")))
281     .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
282                                                position='top',
283                                                font_style='italic'))
284     .set_global_opts(
285         title_opts=opts.TitleOpts(title="冬奥会中国历年参赛人数", pos_left='center'),
286         xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
287         legend_opts=opts.LegendOpts(is_show=False),
288         yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff65")),
289         graphic_opts=[
290             opts.GraphicImage(
291                 graphic_item=opts.GraphicItem(
292                     id_="logo", right=0, top=-300, z=-10, bounding="raw", origin=[75, 75]
293                 ),
294                 graphic_imagestyle_opts=opts.GraphicImageStyleOpts(
295                     width=1000,
296                     height=600,
297                 ),
298             )
299         ], )
300 )
301 page = (
302     Page()
303     .add(winter_bar, )
304 )
305 page.render_notebook()
306 
307 #中国参赛人数的变化
308 china=data[data.region=='China']
309 tmp = china[china.Season=='Summer'].groupby('Year')['ID'].count()
310 plt.figure(figsize=(16,6))
311 plt.xticks(np.arange(1892,2020,8))
312 tmp.plot(style="-o",color='darkorange')
313 plt.title("中国运动员参赛人数")
314 plt.show()
315 
316 #沙漏图
317 #中国最强项目
318 adv_data=data[data["Team"]=="China"].groupby(by="Sport")["Medal"].count().to_frame()
319 adv_data=adv_data.sort_values(by="Medal",ascending=False)[0:10]
320 sport_name=[str(i) for i in adv_data.index]
321 sports=[int(j)for j in adv_data.values]
322 
323 sha = (Funnel()
324           .add("", [z for z in zip(sport_name,sports)])
325           )
326 
327 sha.render_notebook()
328 
329 #词云图
330 #中国优势项目
331 
332 CN_data = data[data.region == 'China']
333 CN_data.head()
334 
335 CN_events = CN_data[CN_data.Medal == 'Gold'].groupby(['Year', 'Sport'])['Event'].nunique().reset_index()
336 CN_events = CN_events.groupby(['Sport'])['Event'].sum().reset_index()
337 CN_events.columns = ['Sport', 'Nums']
338  
339 data_pair = [(row['Sport'], row['Nums']) for _, row in CN_events.iterrows()]
340  
341 cy = (WordCloud(init_opts=opts.InitOpts(bg_color='silver', width='1000px', height='600px'))
342       .add("", data_pair, word_size_range=[30, 80])
343       .set_global_opts(title_opts=opts.TitleOpts(title="中国获得过金牌运动项目", pos_left="center",
344                                                  title_textstyle_opts=opts.TextStyleOpts(color="white", font_size=22)))
345       )
346  
347 cy.render_notebook()

 三、总结

        通过分析120年的奥运历史,深刻体会到其中的体育精神,也在某种程度上是国力强弱的体现,也是体现了国家的强大和发展。在分析各种数据中,参考了其他资料后顺利完成,大部分都符合我的预期还是较为理想。并且通过这次的课程设计,充分感受到数据可视化的便利,让我更加的直观的了解到这120年中的奥运历史。但本文运行结果的图表稍微有些简单不够细致,希望下次能够更完美的实现数据可视化。

 

 

posted @ 2023-06-05 20:21  brobowl  阅读(2182)  评论(0)    收藏  举报