import pandas as pd import matplotlib.pyplot as plt import numpy as np import seaborn as sns import os # 设置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False def plot_individual_boxplots(csv_file_path, save_dir="boxplots"): """ 为每个数据列单独绘制箱型图并保存 参数: csv_file_path: CSV文件路径 save_dir: 保存图片的目录 """ try: # 读取CSV文件 df = pd.read_csv(csv_file_path) # 获取第五列之后的数据列(索引从0开始,第五列索引为4) data_columns = df.iloc[:, 4:] # 检查是否有数据列 if data_columns.empty: print("错误:CSV文件中没有足够的列(至少需要5列)") return # 创建保存目录 if not os.path.exists(save_dir): os.makedirs(save_dir) print(f"创建目录: {save_dir}") # 为每个数据列单独绘制箱型图 for column in data_columns.columns: # 移除空值 clean_data = data_columns[column].dropna() if len(clean_data) == 0: print(f"跳过列 '{column}': 没有有效数据") continue # 创建新图形 plt.figure(figsize=(8, 6)) # 绘制箱型图 box_plot = plt.boxplot([clean_data], labels=[column], patch_artist=True, showfliers=False) # 美化箱型图 box_plot['boxes'][0].set_facecolor('lightblue') box_plot['boxes'][0].set_alpha(0.7) # 添加散点 x_pos = np.random.normal(1, 0.04, size=len(clean_data)) plt.scatter(x_pos, clean_data, alpha=0.6, s=30, color='red', edgecolors='black', linewidth=0.5, zorder=3) # 设置标题和标签 plt.title(f'{column} - 箱型图', fontsize=14, fontweight='bold') plt.xlabel('数据列', fontsize=12) plt.ylabel('数值', fontsize=12) # 添加统计信息到图上 stats_text = f'数据点数: {len(clean_data)}\n均值: {clean_data.mean():.2f}\n中位数: {clean_data.median():.2f}\n标准差: {clean_data.std():.2f}' plt.text(0.02, 0.98, stats_text, transform=plt.gca().transAxes, verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8)) # 添加网格 plt.grid(True, alpha=0.3, linestyle='--') # 调整布局 plt.tight_layout() # 保存图片 safe_column_name = column.replace('/', '_').replace('\\', '_').replace(':', '_') save_path = os.path.join(save_dir, f'{safe_column_name}_boxplot.png') plt.savefig(save_path, dpi=300, bbox_inches='tight') print(f"已保存: {save_path}") # 关闭图形以释放内存 plt.close() print(f"\n所有箱型图已保存到目录: {save_dir}") except FileNotFoundError: print(f"错误:找不到文件 {csv_file_path}") except Exception as e: print(f"错误:{str(e)}") def plot_individual_boxplots_seaborn(csv_file_path, save_dir="boxplots_seaborn"): """ 使用seaborn为每个数据列单独绘制箱型图并保存 参数: csv_file_path: CSV文件路径 save_dir: 保存图片的目录 """ try: # 读取CSV文件 df = pd.read_csv(csv_file_path) # 获取第五列之后的数据列 data_columns = df.iloc[:, 4:] if data_columns.empty: print("错误:CSV文件中没有足够的列(至少需要5列)") return # 创建保存目录 if not os.path.exists(save_dir): os.makedirs(save_dir) print(f"创建目录: {save_dir}") # 为每个数据列单独绘制箱型图 for column in data_columns.columns: # 移除空值 clean_data = data_columns[column].dropna() if len(clean_data) == 0: print(f"跳过列 '{column}': 没有有效数据") continue # 创建新图形 plt.figure(figsize=(8, 6)) # 创建数据框用于seaborn plot_data = pd.DataFrame({ '列名': [column] * len(clean_data), '数值': clean_data }) # 使用seaborn绘制箱型图和散点 sns.boxplot(data=plot_data, x='列名', y='数值', palette='Set2') sns.stripplot(data=plot_data, x='列名', y='数值', color='red', alpha=0.6, size=5, jitter=True) # 设置标题和标签 plt.title(f'{column} - 箱型图 (Seaborn)', fontsize=14, fontweight='bold') plt.xlabel('数据列', fontsize=12) plt.ylabel('数值', fontsize=12) # 添加统计信息 stats_text = f'数据点数: {len(clean_data)}\n均值: {clean_data.mean():.2f}\n中位数: {clean_data.median():.2f}\n标准差: {clean_data.std():.2f}' plt.text(0.02, 0.98, stats_text, transform=plt.gca().transAxes, verticalalignment='top', bbox=dict(boxstyle='round', facecolor='lightgreen', alpha=0.8)) # 添加网格 plt.grid(True, alpha=0.3, linestyle='--') # 调整布局 plt.tight_layout() # 保存图片 safe_column_name = column.replace('/', '_').replace('\\', '_').replace(':', '_') save_path = os.path.join(save_dir, f'{safe_column_name}_boxplot_seaborn.png') plt.savefig(save_path, dpi=300, bbox_inches='tight') print(f"已保存: {save_path}") # 关闭图形以释放内存 plt.close() print(f"\n所有箱型图已保存到目录: {save_dir}") except Exception as e: print(f"错误:{str(e)}") def plot_boxplot_with_scatter(csv_file_path): """ 读取CSV文件并绘制第五列之后数据列的箱型图,同时标注散点 参数: csv_file_path: CSV文件路径 """ try: # 读取CSV文件 df = pd.read_csv(csv_file_path) # 获取第五列之后的数据列(索引从0开始,第五列索引为4) data_columns = df.iloc[:, 4:] # 从第五列开始的所有列 # 检查是否有数据列 if data_columns.empty: print("错误:CSV文件中没有足够的列(至少需要5列)") return # 设置图形大小 plt.figure(figsize=(12, 8)) # 准备数据用于绘制箱型图 box_data = [] labels = [] for column in data_columns.columns: # 移除空值 clean_data = data_columns[column].dropna() if len(clean_data) > 0: box_data.append(clean_data) labels.append(column) # 绘制箱型图 box_plot = plt.boxplot(box_data, labels=labels, patch_artist=True, showfliers=False) # 不显示异常值点,因为我们要自己绘制散点 # 美化箱型图 colors = plt.cm.Set3(np.linspace(0, 1, len(box_data))) for patch, color in zip(box_plot['boxes'], colors): patch.set_facecolor(color) patch.set_alpha(0.7) # 在每个箱型图上添加散点 for i, data in enumerate(box_data): # 为每个数据点添加一些随机的x轴偏移,避免重叠 x_pos = np.random.normal(i + 1, 0.04, size=len(data)) # 绘制散点 plt.scatter(x_pos, data, alpha=0.6, s=20, color='red', edgecolors='black', linewidth=0.5, zorder=3) # 设置标题和标签 plt.title('数据列箱型图(带散点标注)', fontsize=16, fontweight='bold') plt.xlabel('数据列', fontsize=12) plt.ylabel('数值', fontsize=12) # 旋转x轴标签以避免重叠 plt.xticks(rotation=45, ha='right') # 添加网格 plt.grid(True, alpha=0.3, linestyle='--') # 调整布局 plt.tight_layout() # 显示图形 plt.show() # 打印统计信息 print(f"成功绘制了 {len(labels)} 个数据列的箱型图") print("数据列名称:", labels) # 显示每列的基本统计信息 print("\n各列基本统计信息:") for column in labels: data = data_columns[column].dropna() print(f"{column}: 数据点数={len(data)}, 均值={data.mean():.2f}, 中位数={data.median():.2f}") except FileNotFoundError: print(f"错误:找不到文件 {csv_file_path}") except Exception as e: print(f"错误:{str(e)}") def plot_boxplot_with_seaborn(csv_file_path): """ 使用seaborn绘制更美观的箱型图(可选方法) 参数: csv_file_path: CSV文件路径 """ try: # 读取CSV文件 df = pd.read_csv(csv_file_path) # 获取第五列之后的数据列 data_columns = df.iloc[:, 4:] if data_columns.empty: print("错误:CSV文件中没有足够的列(至少需要5列)") return # 将数据转换为长格式用于seaborn melted_data = pd.melt(data_columns, var_name='列名', value_name='数值') melted_data = melted_data.dropna() # 移除空值 # 设置图形大小 plt.figure(figsize=(12, 8)) # 使用seaborn绘制箱型图和散点 sns.boxplot(data=melted_data, x='列名', y='数值', palette='Set3') sns.stripplot(data=melted_data, x='列名', y='数值', color='red', alpha=0.6, size=4, jitter=True) # 设置标题和标签 plt.title('数据列箱型图(Seaborn版本)', fontsize=16, fontweight='bold') plt.xlabel('数据列', fontsize=12) plt.ylabel('数值', fontsize=12) # 旋转x轴标签 plt.xticks(rotation=45, ha='right') # 添加网格 plt.grid(True, alpha=0.3, linestyle='--') # 调整布局 plt.tight_layout() # 显示图形 plt.show() except Exception as e: print(f"错误:{str(e)}") # 主程序 if __name__ == "__main__": # 请修改为您的CSV文件路径 csv_file_path = r"E:\code\WQ\yaobao925\output.csv" # 替换为您的CSV文件路径 print("请选择绘图方法:") print("1. 使用matplotlib绘制(所有列在一张图)") print("2. 使用seaborn绘制(所有列在一张图)") print("3. 分别绘制每列并保存(matplotlib版本)") print("4. 分别绘制每列并保存(seaborn版本)") choice = input("请输入选择(1-4):").strip() if choice == "1": plot_boxplot_with_scatter(csv_file_path) elif choice == "2": plot_boxplot_with_seaborn(csv_file_path) elif choice == "3": plot_individual_boxplots(csv_file_path) elif choice == "4": plot_individual_boxplots_seaborn(csv_file_path) else: print("默认使用分别绘制并保存(seaborn版本)...") plot_individual_boxplots_seaborn(csv_file_path)