-
数据准备:
-
创建Excel文件(示例名:
学生成绩.xlsx
) -
包含列:
学号
、姓名
、班级
、性别
、成绩
-
支持中文列名(需与代码中变量名一致)
-
-
执行流程:
-
导入数据 → 数据清洗 → 整体统计 → 可视化分析
-
自动生成8张分析图表
-
控制台输出详细统计结果
-
-
输出图表:
-
成绩分布直方图(含正态拟合)
-
及格率饼图
-
班级箱线图对比
-
班级平均分柱状图
-
性别分组箱线图
-
性别-成绩分布热力图
-
班级&性别联合分析图
-
-
统计指标:
-
整体/分班/分性别:平均分、最高分、最低分、标准差
-
整体/分班/分性别挂科率
-
按班级分组详细统计表
-
扩展功能:
-
异常值处理:代码已包含缺失值处理(填充0分)
-
动态分组:支持任意班级数量和性别类型
-
多维度分析:提供班级、性别单维度及交叉分析
-
可视化增强:
-
直方图+正态分布曲线
-
带数据标签的柱状图
-
小提琴图+散点图的组合展示
-
热力图直观展示分布密度
-
以下是完整代码演示
%% 学生成绩分析系统
% 作者:MATLAB助手
% 日期:2025-03-01
% 功能:课程成绩统计分析及可视化
%% 步骤1:导入数据
data = readtable('学生成绩.xlsx'); % 替换为你的Excel文件名
disp('前5行数据预览:');
disp(head(data, 5));
%% 步骤2:数据清洗
% 处理缺失值(用0填充)
if any(ismissing(data.成绩))
data.成绩 = fillmissing(data.成绩, 'constant', 0);
disp('已处理成绩中的缺失值');
end
%% 步骤3:基础统计分析
fprintf('\n===== 整体成绩统计 =====\n');
avg_score = mean(data.成绩);
max_score = max(data.成绩);
min_score = min(data.成绩);
std_score = std(data.成绩);
fail_rate = mean(data.成绩 < 60) * 100; % 挂科率(60分以下)
fprintf('平均分: %.2f\n', avg_score);
fprintf('最高分: %d\n', max_score);
fprintf('最低分: %d\n', min_score);
fprintf('标准差: %.2f\n', std_score);
fprintf('挂科率: %.2f%%\n', fail_rate);
%% 步骤4:绘制直方图
figure('Name','成绩分布直方图','Position',[100 100 900 400])
subplot(1,2,1)
histogram(data.成绩, 'BinWidth',5, 'FaceColor','#2c7fb8')
title('成绩频率分布直方图')
xlabel('分数')
ylabel('学生人数')
grid on
% 添加正态分布曲线
hold on
x = linspace(min_score-10, max_score+10, 100);
y = normpdf(x, avg_score, std_score) * numel(data.成绩) * 5; % 5为组距
plot(x, y, 'LineWidth', 2, 'Color', '#d95f0e')
legend('实际分布', '正态拟合')
hold off
%% 步骤5:绘制饼图(及格率)
subplot(1,2,2)
pass_status = categorical(data.成绩 >= 60, [true false], {'及格', '不及格'});
pie(pass_status)
title('整体及格率分布')
colormap([0.2 0.8 0.3; 0.9 0.2 0.2])
%% 步骤6:按班级分组比较
figure('Name','班级成绩分析','Position',[100 100 1200 500])
% 班级箱线图
subplot(1,2,1)
boxplot(data.成绩, data.班级, 'Colors','k')
title('各班级成绩分布箱线图')
xlabel('班级')
ylabel('分数')
grid on
% 班级统计表
subplot(1,2,2)
[class_groups, class_ids] = findgroups(data.班级);
class_stats = splitapply(@(x) [mean(x), max(x), min(x), std(x), mean(x<60)*100],...
data.成绩, class_groups);
class_table = table(class_ids, class_stats(:,1), class_stats(:,2), class_stats(:,3),...
class_stats(:,4), class_stats(:,5),...
'VariableNames',{'班级','平均分','最高分','最低分','标准差','挂科率%'});
disp('===== 班级成绩统计 =====');
disp(class_table);
% 绘制班级平均分柱状图
figure('Name','班级平均分比较')
bar(class_table.班级, class_table.平均分, 'FaceColor',[0.3 0.6 0.9])
title('各班级平均分对比')
xlabel('班级')
ylabel('平均分')
grid on
hold on
% 在柱子上方显示数值
for i = 1:height(class_table)
text(class_table.班级(i), class_table.平均分(i)+0.5,...
sprintf('%.1f', class_table.平均分(i)),...
'HorizontalAlignment','center')
end
hold off
%% 步骤7:按性别分组分析
figure('Name','性别成绩分析','Position',[100 100 800 600])
% 性别分组箱线图
subplot(2,1,1)
boxplot(data.成绩, data.性别)
title('性别成绩分布对比')
ylabel('分数')
% 性别分组统计
subplot(2,1,2)
gender_groups = findgroups(data.性别);
gender_stats = splitapply(@(x) [mean(x), std(x), mean(x<60)*100],...
data.成绩, gender_groups);
gender_labels = unique(data.性别);
gender_table = table(categorical(gender_labels), gender_stats(:,1),...
gender_stats(:,2), gender_stats(:,3),...
'VariableNames',{'性别','平均分','标准差','挂科率%'});
disp('===== 性别成绩统计 =====');
disp(gender_table);
% 绘制性别分组直方图对比
figure('Name','性别成绩分布对比')
histogram2(data.成绩, data.性别, 'DisplayStyle','tile','ShowEmptyBins','on')
title('性别-成绩分布热力图')
xlabel('分数')
ylabel('性别')
colorbar
%% 步骤8:综合分组分析(班级+性别)
figure('Name','班级性别交叉分析')
g = gramm('x',data.班级,'y',data.成绩,'color',data.性别);
g.geom_jitter('alpha',0.6); % 散点图显示分布
g.geom_violin('dodge',0.7,'fill','transparent'); % 小提琴图
g.set_title('班级与性别联合分析');
g.set_names('x','班级','y','成绩','color','性别');
g.draw();