上传文件至 /

This commit is contained in:
2025-12-05 10:31:03 +08:00
commit c6fefe76e4
5 changed files with 5259 additions and 0 deletions

327
box_plot.py Normal file
View File

@ -0,0 +1,327 @@
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)