You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何绘制双图?解决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"","""","""","""","

问题代码中的核心错误

  1. 重复读取数据且路径错误:plot_income_distribution中两次调用read_income_shares,第二次将两个参数都传入高收入文件路径,导致数据重复且错误。
  2. 高收入数据读取逻辑错误:读取高收入文件时,错误地将同一列数据同时赋值给values_poorest和values_wealthiest,覆盖了低收入数据,未正确提取高收入数据。
  3. 未创建独立图表:所有绘图操作都在同一个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)

修正要点

  1. 重构数据读取逻辑:分离低收入和高收入数据的读取流程,避免数据覆盖,同时修正德国名称中的格式问题。
  2. 优化数据读取效率:仅调用一次数据读取函数,避免重复IO操作。
  3. 创建独立图表:使用plt.figure()为两类群体分别创建独立绘图窗口,并保存为不同的图片文件。
  4. 调整图表显示效果:根据两类群体的收入占比实际范围调整Y轴,让图表数据更清晰直观。
  5. 简化代码结构:删除冗余变量和逻辑,提升代码可读性和维护性。

内容的提问来源于stack exchange,提问作者FabianGragas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 17:42:32