如何基于数据框匹配行值分组为每个国家绘制折线图
基于行值分组绘图实现方案
使用Python生态最适合初学者的pandas做数据处理、matplotlib+seaborn做可视化即可实现需求,全程不需要复杂逻辑,步骤如下:
1. 安装依赖库
如果本地没有安装相关库,先在终端执行命令安装:pip install pandas matplotlib seaborn
2. 数据预处理
你当前的数据集是宽表结构(年份单独作为列存在),需要先转成长表结构,才能按维度分组绘图。
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 解决matplotlib中文显示乱码、负号显示异常问题 plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["axes.unicode_minus"] = False # ---------------------- # 你自己使用时,替换成读取本地文件的代码即可 # 例如csv文件:df = pd.read_csv("你的数据文件.csv") # 例如excel文件:df = pd.read_excel("你的数据文件.xlsx") # 下面是和你给出的结构一致的示例数据 data = [ ["Afghanistan", "Estimate", -1.63, -1.57, -1.41], ["Afghanistan", "Sources", 5, 8, 7], ["Afghanistan", "Percentile", 0.95, 0.94, 2.36], ["Zambia", "Estimate", 1.63, 1.57, 1.41], ["Zambia", "Sources", 7, 10, 8], ["Zambia", "Percentile", 0.88, 0.77, 1.54] ] df = pd.DataFrame(data, columns=["Country", "Type", "2011", "2012", "2013"]) # ---------------------- # 宽表转长表,把年份从列名转换为单独的维度列 df_long = df.melt( id_vars=["Country", "Type"], var_name="Year", value_name="Value" ) # 把年份转为整数类型,避免绘图时年份顺序错乱 df_long["Year"] = df_long["Year"].astype(int)
3. 按国家分组生成折线图
根据你的需求选对应方式即可:
方式一:每个国家单独生成一张图片
适合国家数量较多的场景,每个国家的图会单独保存为本地文件:
# 遍历数据集中所有唯一的国家 for country in df_long["Country"].unique(): # 筛选出当前国家的所有数据 current_country_data = df_long[df_long["Country"] == country] # 创建画布 plt.figure(figsize=(8, 4)) # 绘制折线图:x轴为年份,y轴为指标值,不同Type自动用不同颜色区分并生成图例 sns.lineplot(data=current_country_data, x="Year", y="Value", hue="Type", marker="o") # 配置图表标签 plt.title(f"{country} 年度指标变化趋势") plt.xlabel("年份") plt.ylabel("指标数值") plt.grid(alpha=0.3) # 保存图片,文件名以国家命名 plt.savefig(f"{country}_指标折线图.png", dpi=150, bbox_inches="tight") # 关闭当前画布,避免后续绘图重叠 plt.close()
方式二:所有国家子图放在同一张画布对比
适合国家数量较少的场景,所有国家的趋势图排列在同一张图里方便横向对比:
country_list = df_long["Country"].unique() # 创建1行多列的子图布局 fig, axes = plt.subplots(1, len(country_list), figsize=(6*len(country_list), 4), sharex=True) # 逐个国家绘图 for ax, country in zip(axes, country_list): current_country_data = df_long[df_long["Country"] == country] sns.lineplot(data=current_country_data, x="Year", y="Value", hue="Type", marker="o", ax=ax) ax.set_title(f"{country}") ax.set_xlabel("年份") ax.set_ylabel("指标数值") ax.grid(alpha=0.3) # 自动调整子图间距 plt.tight_layout() plt.savefig("各国指标对比折线图.png", dpi=150, bbox_inches="tight") plt.show()
补充说明
- 如果不同
Type的数值范围差距过大(比如Sources都是5-10的整数,Percentile是0-1之间的小数),可以后续给每个Type配置独立y轴,避免数值小的折线被压缩,初学者可以先跑出基础图再按需调整细节。 - 代码不需要根据年份数量修改,无论你有多少个年份列,
melt方法都会自动完成格式转换。
内容的提问来源于stack exchange,提问作者Professional_Learner
相关产品推荐
相关产品推荐

