如何绘制双图?解决Python可视化仅显示单图的技术问题
我需要绘制两张独立图表,分别展示德国收入最高10%群体与收入最低10%群体的收入占比,但当前代码只能显示一张图,且数据读取逻辑存在错误。以下是原始数据和问题代码:
原始数据样本
低收入群体(最低10%)数据:
"#""Germany"",""DEU"",""Income share held by lowest 10%"",""SI.DST.FRST.10"","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""",""3.7"",""3.7"",""3.7"",""3.4"",""3.4"",""3.7"",""3.6"",""3.6"",""3.5"",""3.5"",""3.5"",""3.4"",""3.4"",""3.4"",""3.3"",""3.3"",""3.4"",""3.4"",""3.3"",""3.4"",""3.4"",""3.2"",""3.3"",""3.2"",""3.1"",""3.1"",""2.8"",""3.1"",""3.1"","""","""","""","
高收入群体(最高10%)数据:
"Germany,""DEU"",""Income share held by highest 10%"",""SI.DST.10TH.10"","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""","""",""23.2"",""23.1"",""22.8"",""22.9"",""22.7"",""22.3"",""22.4"",""22.3"",""23.1"",""22.9"",""23.9"",""23.7"",""23.9"",""24"",""25.1"",""24.7"",""25.1"",""24.7"",""24"",""24"",""24.5"",""24.4"",""25"",""24.1"",""24.8"",""24.6"",""24.8"",""25.2"",""25.2"","""","""","""","
问题代码中的核心错误
- 重复读取数据且路径错误:
plot_income_distribution中两次调用read_income_shares,第二次将两个参数都传入高收入文件路径,导致数据重复且错误。 - 高收入数据读取逻辑错误:读取高收入文件时,错误地将同一列数据同时赋值给
values_poorest和values_wealthiest,覆盖了低收入数据,未正确提取高收入数据。 - 未创建独立图表:所有绘图操作都在同一个
plt实例中执行,导致两个数据系列画在同一张图里,而非两张独立图表。
修正后的代码
import csv import matplotlib.pyplot as plt def read_income_shares(poorest_file, wealthiest_file): income_shares = {} years = [] # 读取低收入群体数据 try: with open(poorest_file, 'r', encoding='utf-8') as file: reader = csv.reader(file, quoting=csv.QUOTE_NONE) # 跳过前4行无关内容 for _ in range(4): next(reader) # 提取年份列表 header = next(reader) years = [int(year.strip('"')) for year in header[4:] if year.strip('"').isdigit()] # 读取国家数据行 for line in reader: country_name = line[0].strip('"') values = [] for val in line[4:]: val_clean = val.replace('""""', '0').replace('"', '').strip() if val_clean and val_clean.replace('.', '').isdigit(): values.append(float(val_clean)) else: values.append(0) income_shares[country_name] = {'Poorest_10%': values} except FileNotFoundError: print(f"错误:未找到文件 '{poorest_file}'") except Exception as e: print(f"读取低收入文件时出错:{e}") # 读取高收入群体数据 try: with open(wealthiest_file, 'r', encoding='utf-8') as file: reader = csv.reader(file, quoting=csv.QUOTE_NONE) # 跳过前4行无关内容 for _ in range(4): next(reader) # 读取国家数据行 for line in reader: # 修正德国名称中的多余逗号 country_name = line[0].strip('"').replace(',', '') values = [] for val in line[4:]: val_clean = val.replace('""""', '0').replace('"', '').strip() if val_clean and val_clean.replace('.', '').isdigit(): values.append(float(val_clean)) else: values.append(0) # 合并到已有数据字典 if country_name in income_shares: income_shares[country_name]['Wealthiest_10%'] = values else: income_shares[country_name] = {'Wealthiest_10%': values} except FileNotFoundError: print(f"错误:未找到文件 '{wealthiest_file}'") except Exception as e: print(f"读取高收入文件时出错:{e}") return income_shares, years def plot_income_distribution(countries): # 仅读取一次完整数据 income_data, years = read_income_shares( 'C:\\Users\\Fabian\\Desktop\\Python Ausarbeitung\\Bravo\\one.txt', 'C:\\Users\\Fabian\\Desktop\\Python Ausarbeitung\\Bravo\\two.txt' ) years_to_plot = list(range(1960, 2023)) for country in countries: # 清理国家名称格式 country_formatted = country.strip('" \ufeff').replace(',', '') if country_formatted not in income_data: print(f"{country_formatted} 的数据不存在") continue country_data = income_data[country_formatted] # 绘制低收入群体独立图表 if 'Poorest_10%' in country_data: poorest_values = country_data['Poorest_10%'] # 过滤掉无效的0值数据 valid_years = [y for y, v in zip(years_to_plot, poorest_values) if v > 0] valid_values = [v for v in poorest_values if v > 0] plt.figure(figsize=(10, 6)) plt.plot(valid_years, valid_values, linestyle='dashed', color='blue') plt.title(f'{country_formatted} 收入最低10%群体收入占比') plt.xlabel('年份') plt.ylabel('收入占比 (%)') plt.xlim(1960, 2022) plt.ylim(0, 10) # 根据低收入占比范围调整Y轴,提升可读性 plt.grid(True) plt.savefig(f'{country_formatted}_poorest_10%.png', bbox_inches='tight') plt.show() # 绘制高收入群体独立图表 if 'Wealthiest_10%' in country_data: wealthiest_values = country_data['Wealthiest_10%'] # 过滤掉无效的0值数据 valid_years = [y for y, v in zip(years_to_plot, wealthiest_values) if v > 0] valid_values = [v for v in wealthiest_values if v > 0] plt.figure(figsize=(10, 6)) plt.plot(valid_years, valid_values, color='red') plt.title(f'{country_formatted} 收入最高10%群体收入占比') plt.xlabel('年份') plt.ylabel('收入占比 (%)') plt.xlim(1960, 2022) plt.ylim(20, 30) # 根据高收入占比范围调整Y轴,提升可读性 plt.grid(True) plt.savefig(f'{country_formatted}_wealthiest_10%.png', bbox_inches='tight') plt.show() # 调用示例 countries_to_plot = ['"Germany"'] plot_income_distribution(countries_to_plot)
修正要点
- 重构数据读取逻辑:分离低收入和高收入数据的读取流程,避免数据覆盖,同时修正德国名称中的格式问题。
- 优化数据读取效率:仅调用一次数据读取函数,避免重复IO操作。
- 创建独立图表:使用
plt.figure()为两类群体分别创建独立绘图窗口,并保存为不同的图片文件。 - 调整图表显示效果:根据两类群体的收入占比实际范围调整Y轴,让图表数据更清晰直观。
- 简化代码结构:删除冗余变量和逻辑,提升代码可读性和维护性。
内容的提问来源于stack exchange,提问作者FabianGragas

