import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
# 读取数据
data = pd.read_csv("data/GMD.csv" )
# 主要国家列表
cname = ["USA" , "DEU" , "FRA" , "GBR" , "JPN" , "CHN" , "SGP" , "NLD" , "ITA" , "IND" , "KOR" , "CAN" ]
label_map = {
"GBR" : "UK"
}
start_year = 1980
end_year = 2024
# 地区分组与颜色映射
country_region = {
"USA" : "North America" , "CAN" : "North America" ,
"DEU" : "Europe" , "FRA" : "Europe" , "GBR" : "Europe" ,
"ITA" : "Europe" , "NLD" : "Europe" ,
"CHN" : "Asia" , "JPN" : "Asia" , "KOR" : "Asia" ,
"IND" : "Asia" , "SGP" : "Asia"
}
region_colors = {
"North America" : "tab:blue" ,
"Europe" : "tab:green" ,
"Asia" : "tab:red"
}
# 计算出口占比
data = data.copy()
if "exports_USD" not in data.columns:
data["exports_USD" ] = data["exports" ] / data["USDfx" ]
data["total_exports" ] = data.groupby("year" )["exports_USD" ].transform("sum" )
data["export_share" ] = data["exports_USD" ] / data["total_exports" ] * 100
# 筛选数据
rank_data = data[data["ISO3" ].isin(cname) & (data["year" ] >= start_year) & (data["year" ] <= end_year)].copy()
# 计算排名(1为最大)
rank_data["rank" ] = rank_data.groupby("year" )["export_share" ].rank(ascending= False , method= "min" )
# 绘图
plt.figure(figsize= (8 , 5 ))
for country in cname:
country_data = rank_data[rank_data["ISO3" ] == country]
region = country_region.get(country, "Other" )
color = region_colors.get(region, "gray" )
label = label_map.get(country, country)
plt.plot(
country_data["year" ],
country_data["rank" ],
label= label,
linewidth= 2 ,
color= color
)
# 添加起止年份标签
if not country_data.empty:
plt.text(
country_data["year" ].min () - 1 ,
country_data["rank" ].iloc[0 ],
label,
va= "center" , ha= "right" , fontsize= 10 ,
color= color
)
plt.text(
country_data["year" ].max () + 1 ,
country_data["rank" ].iloc[- 1 ],
label,
va= "center" , ha= "left" , fontsize= 10 ,
color= color
)
# 图形美化
plt.gca().invert_yaxis() # 排名 1 在顶部
plt.yticks(np.arange(1 , len (cname) + 1 ))
plt.xlabel("Year" )
plt.ylabel("Rank of Export Share" )
plt.title("Export Share Ranking of Major Countries (1980–2024)" )
plt.xlim(start_year - 5 , end_year + 5 )
plt.grid(axis= "y" , linestyle= "--" , alpha= 0.5 )
# 自定义图例(按地区)
from matplotlib.lines import Line2D
legend_elements = [
Line2D([0 ], [0 ], color= "tab:blue" , lw= 2 , label= "North America" ),
Line2D([0 ], [0 ], color= "tab:green" , lw= 2 , label= "Europe" ),
Line2D([0 ], [0 ], color= "tab:red" , lw= 2 , label= "Asia" )
]
plt.legend(handles= legend_elements, loc= "upper center" , bbox_to_anchor= (0.5 , - 0.15 ), ncol= 3 )
plt.tight_layout()
plt.show()