一、什么是箱线图
箱线图(Box Plot),也称为盒须图,是一种非常实用的统计图形工具,用于可视化数据的分布情况、集中趋势和异常值。它可以一图概括多个统计特征,因此在数据分析、科研、教学中被广泛使用。总而言之,箱线图是一种总结数据分布的可视化图表,可以快速识别数据的中位数、分布范围和异常值。
二、箱线图构成元素
1. 箱线图五大核心组成
(1)Q1(下四分位数)
a. 位置:箱体的下边缘。
b.含义:表示25%的数据小于这个值。
c.作用:界定低值区边界。
(2)Q2(中位数)
a. 位置:箱体中间的横线。
b. 含义:将数据一分为二,50%的值小于它。
c. 作用:衡量数据集中位置。
(3)Q3(上四分位数)
a. 位置:箱体的上边缘。
b. 含义:表示75%的数据小于这个值。
c. 作用:界定高值区边界。
(4)箱体(Box)
a. 定义:从 Q1 到 Q3 之间的矩形区域。
b. 含义:包含中间 50% 的数据,称为四分位距(IQR)。
c. 判断波动:箱体越高,数据离散程度越大。
(5)箱须(Whiskers)
a. 范围:从 Q1 - 1.5×IQR 到 Q3 + 1.5×IQR。
b. 连接:分别连接到最小值和最大值(非异常值)。
c. 用途:帮助识别正常范围内的数据边界。
2. 异常值(Outliers)
(1)定义:超出 (Q1 - 1.5×IQR )或 (Q3 + 1.5×IQR )的数据。
(2)表示方式:图中常用圆点、加号等标出。
(3)意义:指出极端情况,便于进一步分析或清洗数据。
3. 轴与标签
(1)横轴:分类标签
用于区分不同数据组,例如“成绩”、“组别A”、“实验B”等。
(2)纵轴:数值刻度
显示数据的实际数值分布(如考试分数、身高、温度等)。
箱线图实例示意图
三、几种类型的箱线图的适用场景
1. 单组箱线图:最基础,单一数据集的分布
单组箱线图的适用场景:
当你手头有一个数据集,想要分析该数据的分布情况、异常值、中位数等统计特征时,使用单组箱线图最为合适。
举个例子:
假设你在分析某个班级的学生期末数学成绩。通过箱线图,你可以清楚地看到成绩的分布情况,识别是否有异常值(如特别高或特别低的成绩)。
适用场景总结:
-
查看数据分布:分析数据集的集中趋势、分散程度及异常值。
-
展示数据的中位数与四分位数:明确数据的中位值、上下四分位值以及异常值的范围。
-
识别异常值:通过箱线图的“胡须”和“离群点”轻松发现数据集中的异常值。
2. 多组比较箱线图:对比不同组的分布差异
多组比较箱线图的适用场景:
当你手头有多个数据组,想要比较它们的分布、中位数以及是否存在显著差异时,多组比较箱线图是一个非常实用的工具。
举个例子:
假设你在分析三个班级(A班、B班、C班)学生的期末语文成绩。你想要了解每个班级的成绩分布情况以及它们之间的差异。通过多组比较箱线图,你可以直观地看到每个班级的成绩分布,进而比较它们的成绩高低、集中程度以及异常值。
适用场景总结:
-
比较多个组的数据分布:观察不同组之间是否存在显著的分布差异。
-
分析多个组的中位数、四分位数差异:对比各组的集中趋势和离散程度。
-
查看异常值差异:比较不同组之间的异常值数量和分布情况。
3. 分类变量箱线图:展示分类变量下的分布差异
分类变量箱线图的适用场景:
当你的数据包含一个分类变量(如性别、部门、地区等)和一个连续变量(如收入、成绩、温度等),你希望了解不同分类下连续变量的分布时,分类变量箱线图是一个非常有用的工具。
举个例子:
假设你在分析男女学生的数学成绩,想要比较男女学生成绩的分布。通过分类变量箱线图,你可以清楚地看到男女生成绩的中位数、四分位数及异常值,从而判断两者之间是否存在显著的分布差异。
适用场景总结:
-
比较不同类别的数据分布:查看不同类别下连续变量的分布差异。
-
观察类别之间的集中趋势与分散程度:对比不同类别的中位数和四分位数。
-
识别每个类别的异常值:通过箱线图的离群点标记,识别每个类别的异常数据。
4. 水平箱线图:适用于长标签的展示
水平箱线图的适用场景:
当你希望展示多个类别的数据,并且这些类别的标签较长或需要横向排列时,使用水平箱线图更加直观和方便。
举个例子:
假设你在分析公司不同部门的员工满意度分数,部门名称较长。为了让标签不至于重叠,采用水平箱线图,可以更清晰地展示各部门满意度的分布情况,并且避免标签重叠。
适用场景总结:
-
类目标签较长时的展示:当类别名称很长时,水平箱线图避免了标签重叠。
-
横向比较不同组数据:在需要比较多个数据组时,水平箱线图提供了一种更直观的方式。
-
展示分类数据的分布:适用于分析分类数据在不同组之间的分布差异。
5. 带抖动点箱线图:展示原始数据的分布
带抖动点箱线图的适用场景:
当你希望在箱线图的基础上展示所有原始数据的分布情况时,可以使用带抖动点的箱线图。这种图形将箱线图的统计特征与原始数据的具体点结合起来,提供更丰富的信息。
举个例子:
假设你正在分析一组实验数据,比如志愿者的血压反应,箱线图可以帮助你看到数据的整体分布和异常值,而通过加上抖动点,你可以进一步看到每个数据点的具体位置,进而更精确地分析数据的波动情况。
适用场景总结:
-
显示原始数据分布:除了箱线图的统计特征外,还能展示原始数据的具体分布。
-
揭示数据集的分散程度:通过抖动点,可以看到数据是否集中在某一部分,或分布较为分散。
-
分析数据的离群点:通过抖动点展示的离群点,可以帮助识别和分析数据中的极端值。
你手上有什么数据? | 用哪些箱线图? |
一组数据 | 单组箱线图 |
多组数据 | 多组比较箱线图 |
分类变量 + 连续变量 | 分类变量箱线图 |
标签较长的数据 | 水平箱线图 |
单组数据 + 原始数据 | 带抖动点箱线图 |
四、实现绘图前的数据检查
箱线图类型 | 特别准备事项 |
单组箱线图 | 确保只有一组连续变量数据 |
多组比较箱线图 | 确保有多组数据进行对比 |
分类变量箱线图 | 需要一个分类变量和一个连续变量 |
水平箱线图 | 适用于类目标签较长的数据 |
带抖动点箱线图 | 确保数据中包含原始数据点并呈现分布 |
五、MATLAB绘制相应散点图
1. 单组箱线图绘制
只要一组连续数值,比如某班学生的数学成绩,就可以使用基本的
boxplot()
绘制箱线图。
以下是相关代码实现:
% 某班的数学成绩(可以手动更改)
data = [75, 80, 85, 88, 90, 92, 95, 78, 85, 83, 91, 87, 89];
% 设置全局字体:中文用宋体,数字部分用 Helvetica
set(groot, 'defaultAxesFontName', 'Helvetica'); % 数字
set(groot, 'defaultTextFontName', '宋体'); % 图标题、坐标轴标题等中文
set(groot, 'defaultAxesFontSize', 11);
set(groot, 'defaultTextFontSize', 11);
% 创建图窗
figure('Color', 'w')
% 绘制箱线图
h = boxplot(data, ...
'Widths', 0.4, ...
'Colors', [0.1 0.4 0.7], ...
'Symbol', 'r+', ...
'BoxStyle', 'outline', ...
'MedianStyle', 'target');
% 添加填充色(半透明蓝,可更改)
boxes = findobj(gca, 'Tag', 'Box');
for j = 1:length(boxes)
patch(get(boxes(j), 'XData'), get(boxes(j), 'YData'), ...
[0.8 0.9 1], ...
'FaceAlpha', 0.5, ...
'EdgeColor', [0.1 0.4 0.7], ...
'LineWidth', 1.5);
end
% 添加均值点同时设置数字字体(这里数字字体为Helvetica)
hold on
m = mean(data);
plot(1, m, 'o', 'MarkerSize', 6, ...
'MarkerEdgeColor', 'k', 'MarkerFaceColor', 'm');
text(1.15, m, sprintf('%.1f', m), ...
'FontName', 'Helvetica', 'FontSize', 11, 'Color', 'k');
% 设置中文字体(这里使用宋体)
title('单组数学成绩箱线图', 'FontName', '宋体', 'FontWeight', 'bold');
ylabel('成绩', 'FontName', '宋体');
% 图形美化
grid on
box off
set(gca, 'XTickLabel', {'数学'}, 'XTick', 1)
ylim([70 100])
箱线图实现:
2. 多组比较箱线图
只要有多组连续数值,比如多个班级的学生成绩,就可以使用
boxplot()
对不同组进行并列比较,观察各组数据的分布、集中趋势与差异。
以下是相关代码实现:
% 三个班级的数学成绩(可更改)
data = {
[75, 80, 85, 88, 90, 92], % 1班
[65, 70, 72, 74, 78, 80, 83], % 2班
[85, 88, 90, 93, 95, 97, 98] % 3班
};
% 拼接成一个长向量并并标上组别标签
all_scores = [data{1}, data{2}, data{3}];
group_labels = [ ...
repmat({'1班'}, 1, length(data{1})), ...
repmat({'2班'}, 1, length(data{2})), ...
repmat({'3班'}, 1, length(data{3}))];
% 设置字体样式(可更改)
set(groot, 'defaultAxesFontName', 'Helvetica');
set(groot, 'defaultTextFontName', '宋体');
set(groot, 'defaultAxesFontSize', 11);
set(groot, 'defaultTextFontSize', 11);
% 创建图窗
figure('Color', 'w');
% 绘制箱线图
boxplot(all_scores, group_labels, ...
'Colors', [0.1 0.4 0.7], ...
'Widths', 0.4, ...
'Symbol', 'r+', ...
'BoxStyle', 'outline', ...
'MedianStyle', 'target');
% 添加填充色(半透明,可更改)
hold on
boxes = findobj(gca, 'Tag', 'Box');
for j = 1:length(boxes)
patch(get(boxes(j), 'XData'), get(boxes(j), 'YData'), ...
[0.8 0.9 1], ...
'FaceAlpha', 0.5, ...
'EdgeColor', [0.1 0.4 0.7], ...
'LineWidth', 1.5);
end
% 添加每组的均值点和数字标注
group_means = cellfun(@mean, data);
for i = 1:3
plot(i, group_means(i), 'o', ...
'MarkerSize', 6, ...
'MarkerFaceColor', 'm', ...
'MarkerEdgeColor', 'k');
% 添加均值文字(数字字体)
text(i + 0.1, group_means(i), sprintf('%.1f', group_means(i)), ...
'FontName', 'Helvetica', 'FontSize', 11);
end
% 设置图标题与坐标轴(设置中文宋体,可更改)
title('三班数学成绩分布比较', 'FontName', '宋体', 'FontWeight', 'bold');
ylabel('成绩', 'FontName', '宋体');
% 图形美化
grid on
box off
ylim([60 100]);
箱线图实现:
3. 分类变量箱线图
当数据包含一个分类变量(如性别)和一个连续变量(如数学成绩)时,可以使用
boxplot()
绘制分类变量箱线图,用于观察不同类别下数据的分布差异。
以下是相关代码实现:
% 学生成绩和对应性别(可更改)
scores = [85, 88, 90, 78, 82, 91, 87, 84, 93, 88, ...
70, 72, 75, 68, 65, 78, 74, 73, 69, 76]; % 共20人
genders = [ ...
repmat({'男'}, 1, 10), ... % 前10人是男生
repmat({'女'}, 1, 10)]; % 后10人是女生
% 设置字体(字体类型与大小按需修改)
set(groot, 'defaultAxesFontName', 'Helvetica');
set(groot, 'defaultTextFontName', '宋体');
set(groot, 'defaultAxesFontSize', 11);
set(groot, 'defaultTextFontSize', 11);
% 创建图窗
figure('Color', 'w');
% 绘制箱线图,按性别分类
boxplot(scores, genders, ...
'Colors', [0.1 0.4 0.7], ...
'Widths', 0.4, ...
'Symbol', 'r+', ...
'BoxStyle', 'outline', ...
'MedianStyle', 'target');
% 颜色设置(可更改)
hold on
boxes = findobj(gca, 'Tag', 'Box');
for j = 1:length(boxes)
patch(get(boxes(j), 'XData'), get(boxes(j), 'YData'), ...
[0.8 0.9 1], ...
'FaceAlpha', 0.5, ...
'EdgeColor', [0.1 0.4 0.7], ...
'LineWidth', 1.5);
end
% 添加每组均值点
mean_male = mean(scores(strcmp(genders, '男')));
mean_female = mean(scores(strcmp(genders, '女')));
plot(1, mean_male, 'o', 'MarkerFaceColor', 'm', 'MarkerEdgeColor', 'k');
plot(2, mean_female, 'o', 'MarkerFaceColor', 'm', 'MarkerEdgeColor', 'k');
% 添加注释(数字字体)
text(1.1, mean_male, sprintf('%.1f', mean_male), 'FontName', 'Helvetica');
text(2.1, mean_female, sprintf('%.1f', mean_female), 'FontName', 'Helvetica');
% 添加标题与坐标轴标签(中文)
title('按性别分类的数学成绩箱线图', 'FontName', '宋体', 'FontWeight', 'bold');
ylabel('成绩', 'FontName', '宋体');
% 图形美化
grid on
box off
ylim([60 100])
箱线图实现:
4. 水平箱线图
当类别标签较长或更希望横向比较数据分布时,可以使用
boxplot()
并设置‘Orientation','horizontal'
绘制水平箱线图,使信息更加清晰直观。
以下是相关代码实现:
% 三个班的数学成绩
data = {
[75, 80, 85, 88, 90, 92], % 1班
[65, 70, 72, 74, 78, 80, 83], % 2班
[85, 88, 90, 93, 95, 97, 98] % 3班
};
% 合并数据和组标签
all_scores = [data{1}, data{2}, data{3}];
group_labels = [ ...
repmat({'1班'}, 1, length(data{1})), ...
repmat({'2班'}, 1, length(data{2})), ...
repmat({'3班'}, 1, length(data{3}))];
% 设置字体(按需更改)
set(groot, 'defaultAxesFontName', 'Helvetica');
set(groot, 'defaultTextFontName', '宋体');
set(groot, 'defaultAxesFontSize', 11);
set(groot, 'defaultTextFontSize', 11);
% 创建图窗
figure('Color', 'w');
% 绘制水平箱线图
boxplot(all_scores, group_labels, ...
'Orientation', 'horizontal', ...
'Colors', [0.2 0.5 0.8], ...
'Widths', 0.5, ...
'Symbol', 'r+', ...
'BoxStyle', 'outline', ...
'MedianStyle', 'target');
% 添加填充
hold on
boxes = findobj(gca, 'Tag', 'Box');
for j = 1:length(boxes)
patch(get(boxes(j), 'XData'), get(boxes(j), 'YData'), ...
[0.85 0.92 1], ...
'FaceAlpha', 0.5, ...
'EdgeColor', [0.2 0.5 0.8], ...
'LineWidth', 1.5);
end
% 添加均值点和标签并设置数字字体
means = cellfun(@mean, data);
for i = 1:3
plot(means(i), i, 'o', ...
'MarkerSize', 6, ...
'MarkerFaceColor', 'm', ...
'MarkerEdgeColor', 'k');
text(means(i) + 1, i, sprintf('%.1f', means(i)), ...
'FontName', 'Helvetica', 'FontSize', 11);
end
% 添加标题与横坐标
title('三班数学成绩水平对比箱线图', 'FontName', '宋体', 'FontWeight', 'bold');
xlabel('成绩', 'FontName', '宋体');
% 美化图形
grid on
box off
xlim([60 100])
箱线图实现:
5.带抖动点的箱线图
当样本量较小时,为更直观地展示数据分布,可以在箱线图基础上添加带抖动的散点图层,从而同时观察统计特征与原始数据的离散情况。
以下是相关代码实现:
% 三个班级数学成绩数据
group1 = [75, 80, 85, 88, 90, 92];
group2 = [65, 70, 72, 74, 78, 80, 83];
group3 = [85, 88, 90, 93, 95, 97, 98];
% 合并数据和分组标签
scores = [group1, group2, group3];
labels = [ ...
repmat({'1班'}, 1, length(group1)), ...
repmat({'2班'}, 1, length(group2)), ...
repmat({'3班'}, 1, length(group3))];
% 设置字体
set(groot, 'defaultAxesFontName', 'Helvetica');
set(groot, 'defaultTextFontName', '宋体');
set(groot, 'defaultAxesFontSize', 11);
set(groot, 'defaultTextFontSize', 11);
% 创建图窗
figure('Color', 'w');
% 绘制箱线图(不显示默认异常值)
boxplot(scores, labels, ...
'Colors', [0.15 0.4 0.75], ...
'Widths', 0.5, ...
'Symbol', '', ...
'BoxStyle', 'outline', ...
'MedianStyle', 'target');
% 添加半透明填充色
hold on
boxes = findobj(gca, 'Tag', 'Box');
for j = 1:length(boxes)
patch(get(boxes(j), 'XData'), get(boxes(j), 'YData'), ...
[0.85 0.92 1], ...
'FaceAlpha', 0.5, ...
'EdgeColor', [0.15 0.4 0.75], ...
'LineWidth', 1.5);
end
% 抖动散点
group_index = [ones(1, length(group1)), 2*ones(1, length(group2)), 3*ones(1, length(group3))];
x_jitter = group_index + 0.15 * randn(size(group_index)); % 调整抖动幅度
scatter(x_jitter, scores, ...
40, ... % 更大点
[0.3 0.3 0.3], ...
'filled', 'MarkerFaceAlpha', 0.5);
% 添加每组均值点
means = [mean(group1), mean(group2), mean(group3)];
for i = 1:3
plot(i, means(i), 'o', ...
'MarkerSize', 7, ...
'MarkerEdgeColor', 'k', ...
'MarkerFaceColor', [1 0 1]); % 紫色均值点
% 均值数值标签(数字字体)
text(i + 0.1, means(i), sprintf('%.1f', means(i)), ...
'FontName', 'Helvetica', ...
'FontSize', 12, 'FontWeight', 'bold', ...
'Color', [0.1 0.1 0.1]);
end
% 添加标题与标签
title('各班数学成绩带抖动的箱线对比图', ...
'FontName', '宋体', 'FontWeight', 'bold');
ylabel('成绩', 'FontName', '宋体');
% 美化图形
ylim([60 100]);
xlim([0.5 3.5]);
grid on
box off
箱线图实现:
通过本篇博客,我们系统地介绍了五种常见的箱线图类型及其在 MATLAB 中的实现方式,从基础的单组箱线图,到多组对比、分类变量分布、水平展示,再到融合原始数据点的增强型可视化。每种类型都适用于不同的数据结构与分析需求,帮助我们在“看见数据”的同时,更准确地理解数据的分布特征与差异。
希望这些示例能为你今后的数据分析、教学展示或科研图表制作提供实用参考。如果你有任何问题或想法,欢迎留言交流,一起精进可视化表达的技巧!