技术菜鸟如何做出好看的奥运会奖牌榜

2021-08-13 16:14:22 浏览数 (4)

大家好,我是云朵君!

2021年7月23日,第32届夏季奥运会在日本东京拉开帷幕。大赛共设置33个大项50个分项339个小项,是历届奥运会中产生金牌最多的一届 。

中国队yyds!到目前为止稳居金牌榜榜首,云朵君计划用可视化方法看一看历届奥运会奖牌榜。


数据准备

所有数据均是从维基百科中获取,有如下数据:

中国历年奥运奖牌榜成绩

▲ 中国历年奥运奖牌榜成绩

历届奖牌榜全球总榜

▲ 历届奖牌榜全球总榜

历届各国奖牌榜

▲ 历届各国奖牌榜(2016年)

中国历届单项比赛奖牌榜

▲ 中国历届单项比赛奖牌榜

可视化

历年主办国分布图

▲ 历年主办国分布图

夏季奥林匹克运动会(Summer Olympic Games或Games of the Olympic)是由国际奥林匹克委员会主办的国际性多项运动赛事,每四年举办一次。从1904年起,夏季奥运会的每个项目都会颁发奖牌,其中第一名为金牌,第二名为银牌,第三名为铜牌。

美国举办过4次夏季奥运会,是举办奥运会次数最多的国家。英国于2012年第3次举办夏季奥运会,伦敦成为第1个举办3次夏季奥运会的城市。澳大利亚、法国、德国、日本和希腊都举办过2次夏季奥运会。

其他举办过夏季奥运会的国家有:中国、比利时、加拿大、芬兰、意大利、墨西哥、荷兰、韩国、西班牙、苏联和瑞典。亚洲第1次奥运会在日本东京举办。南美洲的第1次奥运会在巴西里约热内卢举办。有5个城市曾2次举办过夏季奥运会:东京、洛杉矶、伦敦、巴黎和雅典。

绘图方法

绘图工具:pyecharts Microsoft

第一步,利用pyecharts绘制主办国及主办次数全球地图可视化,可以直接到官网例子学习如何绘制一个全球图。

第二步,为地图标上带箭头的时间文字,由于暂未习得如何在pyecharts地图上用代码的方法实现标注,因此可以借助Microsoft手动标注。

代码语言:javascript复制
from pyecharts import options as opts
from pyecharts.charts import Map
df_1 = df_total.groupby(['country']).count().reset_index()
c = (
    Map()
    .add("", [list(z) for z in zip(df_1.country, df_1.年份)], "world",is_map_symbol_show=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="数据STUDIO"),
        visualmap_opts=opts.VisualMapOpts(max_=4,is_show=False),
    )
#     .render("map_world.html")
)
c.render_notebook()

历届奖牌榜

奥运会是全世界规模最大的综合性体育运动会,全世界的各个国家都会派运动员来参加!奥运会五大体育强国:1.美国,2.中国,3.英国,4.法国,5.德国。

截至里约奥运会,中国代表团共参加过九届夏季奥运会,累计取得546枚奥运奖牌,包括224枚金牌 、167枚银牌、155枚铜牌。

▲ 历届奖牌榜

绘图方法

上图是按照金牌总数金牌排序绘图,由于参赛国家过多,这里只绘制了金牌总数TOP30的国家。

绘图工具:Plotly Microsoft

第一步通过以下代码绘制堆叠柱状图,第二步将国旗图片与柱状图组合。

代码语言:javascript复制
df_total_country_num = df_total_country.iloc[:30,].iloc[::-1,:]
fig = go.Figure()
fig.add_trace(go.Bar(
    x=df_total_country_num['金'],
    y=df_total_country_num['国家'],
    name='金牌',
    orientation='h',
    marker=dict(
        color='rgba(242,192,86, 0.6)',
        line=dict(color='rgba(242,192,86, 1.0)', width=3)),
    textposition='inside',
    text=df_total_country_num['金'].values,
    textangle = 90))
fig.add_trace(go.Bar(银牌))
fig.add_trace(go.Bar(铜牌))

fig.update_layout(barmode='stack', height=1000,
    width=1000,
    title='历届奖牌榜TOP30',
    template='ggplot2',
    font=dict( size=12, color="Black" ),
    plot_bgcolor="#fafafa",
    legend=dict(yanchor="top",
    y=1.1, xanchor="left", x=0.9))
fig.show()

中国历年奥运奖牌榜成绩

翻阅新中国夏季奥运会历史,最早可上溯到1984年。中国在重返国际奥委会后首次派出代表团参加夏季奥运会。

1988年,乒乓球项目首次进入夏季奥运会,中国夺得了4枚金牌中的2枚,奠定了在该项目中不可动摇的地位。

1992年,巴塞罗那夏季奥运会上,中国代表团在田径、柔道中实现突破 。

1996年,亚特兰大奥运会上,首次实现了乒乓球项目的金牌包揽。

2000年,悉尼奥运会上,中国代表团在乒乓球项目再度实现对金牌的包揽,举重、体操、跳水、羽毛球等项目也收获颇丰,并获得了中国队在跆拳道项目的首枚金牌。

2004年,雅典奥运会,中国队在网球、摔跤和皮划艇比赛中首次有金牌入账,刘翔在男子110米栏比赛中为中国队取得历史上首枚男子径赛奥运金牌,成为国人的骄傲。

2008年,中国的首都北京成为奥运会主办国,中国取得了48金21银28铜的优异成绩,成为奥运历史上首个登上金牌榜首的亚洲国家。

2012年,第30届奥运会在英国伦敦举行。羽毛球跟随乒乓球其后,成为中国队第二个实现金牌包揽的项目。

2016年,第31届里约奥运会上,中国队不仅在乒乓球、跳水等传统优势项目上争金夺银,而且在场地自行车项目中首次拿到金牌。中国女排暨1984、2004年两度夺冠以来,再次登顶,续写女排精神的荣耀。

相对于体育强国美国而言,中国近年来一路逆袭,无时无刻不在诠释着中国的奥运精神。

▲ 中国历年奥运奖牌榜成绩

▲ 美国历年奥运奖牌榜成绩

绘图方法

绘图工具:Plotly

代码语言:javascript复制
fig = go.Figure()
fig.add_trace(go.Bar(
    x=df_total_year['地点'],
    y=df_total_year['金牌'],
    name='金牌',
    marker_color='gold',
    textposition='inside',
    text=df_total_year['金牌'].values,
    textangle = 90
))
fig.add_trace(go.Bar('银牌'))
fig.add_trace(go.Bar('铜牌'))
fig.add_trace(go.Scatter(
    x=df_total_year['地点'],
    y=df_total_year['参赛选手'],
    name='参赛选手',
    mode='markers text lines',
    marker_color='black',
    marker_size=10,
    textposition='top center',
    line=dict(color='orange',dash='dash'),
    yaxis='y2'))
fig.update_layout(barmode='group', xaxis_tickangle=-45,
    title='中国历年奥运奖牌榜成绩',
    xaxis_title="主办国",
    yaxis_title="奖牌数",
    template='ggplot2',
    font=dict(size=12, color="Black"),
    xaxis=dict(showgrid=False),
    yaxis=dict(showgrid=False),
    plot_bgcolor="#fafafa",
    yaxis2=dict(showgrid=True,overlaying='y',side='right',title='参赛选手'),
    legend=dict(yanchor="top",
    y=1.3, xanchor="left", x=0.9))
fig.show()

单项比赛项目成绩表

从比赛项目来看,跳水、举重、体操、乒乓球、射击、羽毛球是中国传统的优势体育项目。其中,跳水更是以40枚金牌成为了中国获得最多金牌的奥运项目。

▲ 图片来源:人民日报客户端

▲ 单项比赛项目成绩表

绘图方法

绘图工具:Excel

直接选中数据,插入条形图,并设置数据点格式,用目标图片对其进行填充(图片或纹理填充),填充方式为层叠。

▲ 设置数据点格式

酷炫的全球奖牌分布动图

▲ 总榜

▲ 金牌

▲ 银牌

▲ 铜牌

绘图方法

绘图工具:geopandas imageio

第一步,先利用geopandas绘制出历年各个奖牌的全球分布图,其中比较影响美观的参数:cmap,根据matplotlib颜色集选取合适的颜色,以达到美观的效果。

第二步,将上面绘制出的png静态图,通过imageio将其合成动态图,可以看到奖牌榜分布随着时间的变化情况。

地图绘制代码
代码语言:javascript复制
import geopandas
import matplotlib.colors
import pycountry
import matplotlib.pyplot as plt

def alpha3code(column):
    CODE=[]
    for country in column:
        try:
            code=pycountry.countries.get(name=country).alpha_3
            CODE.append(code)
        except:
            CODE.append('None')
    return CODE

def draw_geo(geo_temp,col,kind,name,name2,cmap='Set3'):
    geo_temp['CODE']=alpha3code(geo_temp['English'])
    vmin = 0
    vmax = 40
    world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
    world.columns=['pop_est', 'continent', 'name', 'CODE', 'gdp_md_est', 'geometry']
    merge=pd.merge(world,geo_temp,on='CODE')

    ax = world.plot(figsize=(20,15), linewidth=0.25, edgecolor=background_color, color='lightgray')
    ax.axis('off')
    # ax.set_facecolor(background_color)
    merge.plot(column=col,figsize=(20, 15),cmap=cmap,ax=ax, legend=True,
               legend_kwds={'shrink': 0.5},vmin=vmin, vmax=vmax)

    ax.text(-175,112,f'{name}年{name2}奥运会',
            fontsize=30,fontweight='bold',color='#323232')
    ax.text(-175,102,f'{kind}牌总数',
            color='gray',fontsize=20)

    plt.show()
    plt.savefig(fname=f'{name}.png')
Gif动图合成代码
代码语言:javascript复制
import imageio
def create_gif(image_list, gif_name, duration = 2):
    """
    生成Gif文件,原始图像仅仅支持png格式
    image_list : 输入图像的路径
    gif_name : 字符串,所生成的gif文件名,带.gif文件名后缀
    duration : gif图像时间间隔,这里默认2s
    """
    # 创建一个空列表,用来存源图像
    frames = [] 
    # 利用方法append把图片挨个存进列表 
    for image_name in image_list:
        frames.append(imageio.imread(image_name))
    # 保存为gif格式的图
    imageio.mimsave(gif_name, frames, 'GIF', duration = duration)
    return    
def main(name):
    image_list = ['1984.png','1988.png','1992.png','1996.png','2000.png',
                  '2004.png', '2008.png', '2012.png','2016.png']
    gif_name = f'{name}.gif'
    duration = 1.5
    create_gif(image_list, gif_name)
参考资料

[1] 奥运会logo图片及数据来源维基百科: https://zh.wikipedia.org/wiki/夏季奥林匹克运动会 [2] 奥运历史资料:https://baijiahao.baidu.com/s?id=1706677041934937288&wfr=spider&for=pc

0 人点赞