利用Python繪制好看的奧運會獎牌榜

2021年7月23日,第32屆夏季奧運會在日本東京拉開帷幕。大賽共設置33個大項50個分項339個小項,是歷屆奧運會中產(chǎn)生金牌最多的一屆 。
中國隊yyds!到目前為止穩(wěn)居金牌榜榜首,云朵君計劃用可視化方法看一看歷屆奧運會獎牌榜。
數(shù)據(jù)準備
所有數(shù)據(jù)均是從維基百科中獲取,有如下數(shù)據(jù):
中國歷年奧運獎牌榜成績

歷屆獎牌榜全球總榜

歷屆各國獎牌榜

中國歷屆單項比賽獎牌榜

可視化
歷年主辦國分布圖

夏季奧林匹克運動會(Summer Olympic Games或Games of the Olympic)是由國際奧林匹克委員會主辦的國際性多項運動賽事,每四年舉辦一次。從1904年起,夏季奧運會的每個項目都會頒發(fā)獎牌,其中第一名為金牌,第二名為銀牌,第三名為銅牌。
美國舉辦過4次夏季奧運會,是舉辦奧運會次數(shù)最多的國家。英國于2012年第3次舉辦夏季奧運會,倫敦成為第1個舉辦3次夏季奧運會的城市。澳大利亞、法國、德國、日本和希臘都舉辦過2次夏季奧運會。
其他舉辦過夏季奧運會的國家有:中國、比利時、加拿大、芬蘭、意大利、墨西哥、荷蘭、韓國、西班牙、蘇聯(lián)和瑞典。亞洲第1次奧運會在日本東京舉辦。南美洲的第1次奧運會在巴西里約熱內(nèi)盧舉辦。有5個城市曾2次舉辦過夏季奧運會:東京、洛杉磯、倫敦、巴黎和雅典。
繪圖方法
繪圖工具:pyecharts + Microsoft
第一步,利用pyecharts繪制主辦國及主辦次數(shù)全球地圖可視化,可以直接到官網(wǎng)例子學習如何繪制一個全球圖。
第二步,為地圖標上帶箭頭的時間文字,由于暫未習得如何在pyecharts地圖上用代碼的方法實現(xiàn)標注,因此可以借助Microsoft手動標注。
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="數(shù)據(jù)STUDIO"),
visualmap_opts=opts.VisualMapOpts(max_=4,is_show=False),
)
# .render("map_world.html")
)
c.render_notebook()
歷屆獎牌榜
奧運會是全世界規(guī)模最大的綜合性體育運動會,全世界的各個國家都會派運動員來參加!奧運會五大體育強國:1.美國,2.中國,3.英國,4.法國,5.德國。
截至里約奧運會,中國代表團共參加過九屆夏季奧運會,累計取得546枚奧運獎牌,包括224枚金牌 、167枚銀牌、155枚銅牌。

繪圖方法
上圖是按照金牌總數(shù)金牌排序繪圖,由于參賽國家過多,這里只繪制了金牌總數(shù)TOP30的國家。
繪圖工具:Plotly + Microsoft
第一步通過以下代碼繪制堆疊柱狀圖,第二步將國旗圖片與柱狀圖組合。
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年,巴塞羅那夏季奧運會上,中國代表團在田徑、柔道中實現(xiàn)突破 。
1996年,亞特蘭大奧運會上,首次實現(xiàn)了乒乓球項目的金牌包攬。
2000年,悉尼奧運會上,中國代表團在乒乓球項目再度實現(xiàn)對金牌的包攬,舉重、體操、跳水、羽毛球等項目也收獲頗豐,并獲得了中國隊在跆拳道項目的首枚金牌。
2004年,雅典奧運會,中國隊在網(wǎng)球、摔跤和皮劃艇比賽中首次有金牌入賬,劉翔在男子110米欄比賽中為中國隊取得歷史上首枚男子徑賽奧運金牌,成為國人的驕傲。
2008年,中國的首都北京成為奧運會主辦國,中國取得了48金21銀28銅的優(yōu)異成績,成為奧運歷史上首個登上金牌榜首的亞洲國家。
2012年,第30屆奧運會在英國倫敦舉行。羽毛球跟隨乒乓球其后,成為中國隊第二個實現(xiàn)金牌包攬的項目。
2016年,第31屆里約奧運會上,中國隊不僅在乒乓球、跳水等傳統(tǒng)優(yōu)勢項目上爭金奪銀,而且在場地自行車項目中首次拿到金牌。中國女排暨1984、2004年兩度奪冠以來,再次登頂,續(xù)寫女排精神的榮耀。
相對于體育強國美國而言,中國近年來一路逆襲,無時無刻不在詮釋著中國的奧運精神。


▲ 美國歷年奧運獎牌榜成績
繪圖方法
繪圖工具:Plotly
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="獎牌數(shù)",
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()
單項比賽項目成績表
從比賽項目來看,跳水、舉重、體操、乒乓球、射擊、羽毛球是中國傳統(tǒng)的優(yōu)勢體育項目。其中,跳水更是以40枚金牌成為了中國獲得最多金牌的奧運項目。

▲ 圖片來源:人民日報客戶端

繪圖方法
繪圖工具:Excel
直接選中數(shù)據(jù),插入條形圖,并設置數(shù)據(jù)點格式,用目標圖片對其進行填充(圖片或紋理填充),填充方式為層疊。

酷炫的全球獎牌分布動圖




繪圖方法
繪圖工具:geopandas + imageio
第一步,先利用geopandas繪制出歷年各個獎牌的全球分布圖,其中比較影響美觀的參數(shù):cmap,根據(jù)matplotlib顏色集選取合適的顏色,以達到美觀的效果。
第二步,將上面繪制出的png靜態(tài)圖,通過imageio將其合成動態(tài)圖,可以看到獎牌榜分布隨著時間的變化情況。
地圖繪制代碼
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}牌總數(shù)',
color='gray',fontsize=20)
plt.show()
plt.savefig(fname=f'{name}.png')
Gif動圖合成代碼
import imageio
def create_gif(image_list, gif_name, duration = 2):
"""
生成Gif文件,原始圖像僅僅支持png格式
image_list : 輸入圖像的路徑
gif_name : 字符串,所生成的gif文件名,帶.gif文件名后綴
duration : gif圖像時間間隔,這里默認2s
"""
# 創(chuàng)建一個空列表,用來存源圖像
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圖片及數(shù)據(jù)來源維基百科: https://zh.wikipedia.org/wiki/夏季奧林匹克運動會
[2] 奧運歷史資料:https://baijiahao.baidu.com/s?id=1706677041934937288&wfr=spider&for=pc






