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

Python批量生成92份合同分析图表并保存至指定文件夹报错求助

解决你的图表保存与循环问题

我来一步步帮你搞定当前的代码问题,先梳理下核心错误和改进方向:

首先,你的代码里的几个关键错误

  • plt.plot不支持kind参数:kind是pandas数据框绘图(df.plot())的专属参数,matplotlib原生的plt.plot默认就是折线图,不需要这个参数——这也是触发AttributeError的直接原因。
  • 文件夹重复创建报错:你在内层循环里每次都尝试创建Analysis i文件夹,第一次循环创建成功后,第二次循环再执行os.mkdir(folder_name)就会因为文件夹已存在而直接中断循环。
  • 字符串格式化语法错误:"Analyse" + str[i+1] "{}" + extension.format(name)这段写法有语法问题,str[i+1]应该写成str(i+1),而且拼接逻辑混乱,用f-string会更简洁不易出错。
  • 遗漏numpy导入:代码里用到了np.linspace和np.random.random,但没写import numpy as np,运行会直接报错。
  • print语句变量未定义:savefile这个变量根本没在代码里定义过,执行print时会触发变量未找到的错误。

修正后的完整代码

import pandas as pd
import matplotlib.pyplot as plt
import os
import numpy as np  # 必须导入numpy,因为用到了它的随机数和序列函数

# 保存分析结果的根文件夹
URL5 = r"C:\Users\A\AppData\Local\Programs\Python\Python39"

# 按合同ID分组(假设你的outer_merged_df已经提前定义好)
groups = outer_merged_df.groupby("ID_Contrat")
# 获取去重后的合同ID列表,避免重复处理同一合同
List_ID_Contrat = outer_merged_df["ID_Contrat"].unique().tolist()

def create_plot(file_name, x, y):
    # 用subplots创建图表,推荐用面向对象的写法,更灵活可控
    fig, ax = plt.subplots()
    # 绘制折线图,移除无效的kind参数,用label设置图例文本
    ax.plot(x, y, color="red", linewidth=2, label="合同数据")
    ax.legend()  # 显示图例
    plt.savefig(file_name, dpi=300)  # dpi参数可以提升图表清晰度
    plt.close()  # 关闭图表释放内存,避免绘制大量图表后内存溢出

def main():
    parent_folder = URL5
    # 确保根文件夹存在,不存在就创建
    os.makedirs(parent_folder, exist_ok=True)
    os.chdir(parent_folder)
    
    extension = ".png"
    num_analyses = 5  # 你要执行的分析次数
    
    for i in range(num_analyses):
        # 定义当前分析的文件夹名称
        folder_name = f'Analysis {i+1}'
        # 创建文件夹,exist_ok=True表示如果文件夹已存在就跳过,不会报错
        os.makedirs(folder_name, exist_ok=True)
        
        # 遍历每个合同ID,生成对应图表
        for contrat_id in List_ID_Contrat:
            # 生成规范的文件名:比如"Analyse 1 Contrat 001.png"
            file_name = f'Analyse {i+1} Contrat {contrat_id}{extension}'
            # 用os.path.join拼接路径,自动适配Windows/Linux的路径分隔符
            full_file_path = os.path.join(folder_name, file_name)
            
            # ----------------------
            # 这里替换成你的真实数据逻辑
            # 从分组中获取当前合同的具体数据
            contrat_data = groups.get_group(contrat_id)
            # 示例:假设你要绘制x是"时间列",y是"金额列",替换成你实际的列名
            # x = contrat_data["日期"]
            # y = contrat_data["月度金额"]
            # 暂时用随机数据测试代码逻辑
            x = np.linspace(1, 100, 100)
            y = np.random.random(100)
            # ----------------------
            
            # 生成并保存图表
            create_plot(full_file_path, x, y)
            print(f"图表 {full_file_path} 已成功保存")

if __name__ == "__main__":
    main()

关键改进点说明

  1. 修复kind参数错误:移除了plt.plot里的无效参数,改用面向对象的ax.plot写法,后续如果需要其他类型的图表(比如柱状图),直接替换成ax.bar()等对应函数即可。
  2. 安全创建文件夹:用os.makedirs(..., exist_ok=True)确保每个分析文件夹只创建一次,不会因为重复创建报错中断循环。
  3. 可靠的路径处理:用os.path.join拼接路径,避免不同操作系统的路径分隔符问题(比如Windows用\,Linux用/)。
  4. 优化内存占用:在create_plot里添加plt.close(),每次绘制完图表就关闭,避免绘制92*5=460张图表后内存溢出。
  5. 清晰的文件名格式:用f-string生成文件名,语法直观,不容易出错。
  6. 避免重复处理合同:用unique().tolist()获取合同ID列表,确保每个合同只被处理一次(如果你的原始数据里有重复ID的话)。

替换为真实数据的提示

你现在用的是随机数据测试,只需要把代码中# ----------------------之间的部分替换成你的真实数据逻辑即可:

# 从分组中获取当前合同的具体数据
contrat_data = groups.get_group(contrat_id)
# 替换成你实际要绘制的x、y列名
x = contrat_data["你的时间列名称"]
y = contrat_data["你的数值列名称"]

这样运行代码后,就能在URL5路径下生成Analysis 1到Analysis 5五个文件夹,每个文件夹里都会有92张对应合同的图表啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:47:47