基于Python对奥运历史运动员和成绩的数据分析
一、数据说明
1、背景介绍
该数据集是现代奥运会的历史数据集,包括从1896年雅典奥运会到2016年里约奥运会的所有奥运会。
需要注意的是,冬季和夏季奥运会在同一年举行,直到1992年。在那之后,他们错开了它们,以便冬季奥运会以四年为周期举行,从1994年开始,然后是1996年的夏季,然后是1998年的冬季,依此类推。人们在分析这些数据时常犯的一个错误是假设夏季和冬季奥运会一直是错开的。
本篇主要是基于120年的奥运历史:运动员和成绩这个数据集去进行探索,对数据进行清洗分析,然后对数据进行可视化分析,通过作图来展现这份数据的不同方面。如,奥运会参赛人数的变化、运动选手男女的比例、运动选手的年龄身高体重等等。
2、数据内容
文件athlete_events.csv包含 271116 行和 15 列。每排对应一名参加个人奥运项目(运动员项目)的运动员。这些列是:
- ID - 每个运动员的唯一编号
- 姓名 - 运动员姓名
- 性别 - M 或 F
- 年龄 - 整数
- 高度 - 以厘米为单位
- 重量 - 以公斤为单位
- 团队 - 团队名称
- NOC - 国家奥委会 3 个字母代码
- 游戏 - 年份和季节
- 年份 - 整数
- 季节 - 夏季或冬季
- 城市 - 主办城市
- 体育 - 运动
- 事件 - 事件
- 奖牌 - 金牌、银牌、铜牌或 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年中的奥运历史。但本文运行结果的图表稍微有些简单不够细致,希望下次能够更完美的实现数据可视化。

浙公网安备 33010602011771号