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

