Matlab小提琴图详解,从密度估计到多维度可视化
创作时间:
作者:
@小白创作中心
Matlab小提琴图详解,从密度估计到多维度可视化
引用
CSDN
1.
https://blog.csdn.net/weixin_31268759/article/details/146167415
小提琴图(Violin Plot)是一种结合箱线图与核密度估计(Kernel Density Estimation, KDE)的先进统计图表,1998年由Hintze和Nelson首次提出。它能同时展示数据的分布形态、概率密度及关键统计量(如中位数、四分位数),弥补了传统箱线图在多模态分布和连续密度展示上的不足,尤其适用于大数据分析和复杂分布比较。
一、小提琴图的核心组成与数学原理
1. 基本结构
- 密度曲线:通过核密度估计得到,左右对称的曲线宽度表示数据在对应值处的概率密度,面积总和为1。
- 内部标记:
- 中位数线(50%分位数):垂直线标记数据集的中间值。
- 箱体范围(可选):使用短粗线或矩形表示Q1-Q3(25%-75%分位数)。
- 须线(可选):显示1.5×IQR范围,或直接调整密度曲线尾部以反映数据范围。
2. 核密度估计(KDE)的数学背景
核密度估计(Kernel Density Estimation, KDE)是一种非参数概率密度估计方法,用于估计随机变量的概率密度函数。其基本思想是将每个数据点视为一个小的核函数(如高斯核),然后将这些核函数叠加起来形成一个平滑的概率密度曲线。KDE的公式可以表示为:
$$
\hat{f}h(x) = \frac{1}{n}\sum{i=1}^{n}K_h(x-x_i)
$$
其中,$K_h$是带宽为$h$的核函数,$x_i$是数据点,$n$是数据点的数量。常见的核函数包括高斯核、Epanechnikov核等。
3. 与箱线图的对比
特性 | 箱线图 | 小提琴图 |
|---|---|---|
分布形态展示 | 仅五数概括,无法显示多峰 | 显示完整密度曲线,包括双峰、偏态 |
数据复杂度 | 适合中小样本量对比 | 适合大样本或高密度区间分析 |
异常值检测 | 明确标记离群点 | 依赖密度尾部辨识,可能不够直观 |
可视化空间需求 | 紧凑,适合多组对比 | 需要更多横向空间以展示密度 |
二、MATLAB实现基础与进阶
1. 基础小提琴图绘制
MATLAB官方未直接提供小提琴图函数,但可通过ksdensity与patch手动创建:
% 调用示例
data1 = randn(1000,1)*0.8 + 2;
data2 = randn(1000,1)*1.5 + 5;
figure; hold on;
plotViolin(data1, 1, [0.2 0.6 0.8]);
plotViolin(data2, 2, [0.8 0.4 0.2]);
xlim([0.5 2.5]);
set(gca, 'XTick', [1 2], 'XTickLabel', {'Group A', 'Group B'});
ylabel('Value');
title('基础小提琴图');
function plotViolin(data, position, color)
% 核密度估计
[f, xi] = ksdensity(data);
f = f / max(f) * 0.4; % 缩放宽度
% 绘制左半部分
patch([position - f, position + fliplr(f)], ...
[xi, fliplr(xi)], color, 'FaceAlpha', 0.6, 'EdgeColor', 'none');
% 添加中位数线
median_val = median(data);
line([position - 0.05, position + 0.05], [median_val, median_val], ...
'Color', 'k', 'LineWidth', 2);
end
2. 增强型小提琴图
(1) 叠加箱线图与散点
% 绘制小提琴图基础
plotViolin(data1, 1, [0.9 0.2 0.2]);
plotViolin(data2, 2, [0.2 0.7 0.3]);
% 在每个小提琴中心添加箱线图
boxplot(data1, 'Positions', 0.9, 'Widths', 0.15, 'Colors', 'k');
boxplot(data2, 'Positions', 2.1, 'Widths', 0.15, 'Colors', 'k');
% 叠加抖动散点
jitter1 = 0.9 + (rand(size(data1)) - 0.5)*0.1;
jitter2 = 2.1 + (rand(size(data2)) - 0.5)*0.1;
scatter(jitter1, data1, 20, [0.9 0.2 0.2], 'filled', 'MarkerEdgeColor', 'k');
scatter(jitter2, data2, 20, [0.2 0.7 0.3], 'filled', 'MarkerEdgeColor', 'k');
(2) 调整带宽与核函数
% 自定义带宽和Epanechnikov核
[f, xi] = ksdensity(data1, 'Bandwidth', 0.5, 'Kernel', 'Epanechnikov');
3. 高级小提琴图实现
% 小提琴图生成程序 - 高级版
clear; clc; close all;
% 生成示例数据(三种不同的分布)
rng(42); % 设置随机种子保证可重复性
data{1} = 1.5*randn(500,1) + 3; % 正态分布N(3, 1.5^2)
data{2} = 0.8*randn(300,1) - 1; % 正态分布N(-1, 0.8^2)
data{3} = 0.6*randn(400,1) + 6; % 正态分布N(6, 0.6^2)
data{4} = 0.4*randn(250,1) + 8; % 正态分布N(8, 0.4^2)
% 参数设置
positions = 1:length(data); % 小提琴位置
bandwidth = []; % 核密度估计带宽(空表示自动选择)
violinWidth = 0.6; % 小提琴最大宽度
colorMap = parula(length(data)); % 颜色映射
medianColor = [1 0.2 0.2]; % 中位数线颜色
meanSymbol = 'd'; % 均值点符号
outlierThresh = 1.5; % 离群值阈值(IQR倍数)
% 初始化图形
figure('Color','white', 'Position', [100, 100, 800, 600])
hold on;
% 为每个数据集绘制小提琴图
for k = 1:length(data)
% 核密度估计
[f, xi] = ksdensity(data{k}, 'Bandwidth', bandwidth);
f = violinWidth * f/max(f); % 归一化到小提琴宽度
% 统计量计算
q = quantile(data{k}, [0.25 0.5 0.75]);
iqr = q(3) - q(1);
lowerWhisker = max(min(data{k}), q(1) - outlierThresh*iqr);
upperWhisker = min(max(data{k}), q(3) + outlierThresh*iqr);
% 绘制小提琴主体
fill([positions(k)-f, fliplr(positions(k)+f)],...
[xi, fliplr(xi)], colorMap(k,:),...
'FaceAlpha', 0.6, 'EdgeColor', 'none',...
'LineWidth', 1.2, 'EdgeAlpha', 0.8);
% 绘制箱线图元素
rectangle('Position', [positions(k)-0.1, q(1), 0.2, q(3)-q(1)],...
'FaceColor', 'w', 'EdgeColor', 'k', 'LineWidth', 1.5);
line([positions(k)-0.1 positions(k)+0.1], [q(2) q(2)],...
'Color', medianColor, 'LineWidth', 2.5); % 中位数线
% 绘制须线
line([positions(k) positions(k)], [lowerWhisker q(1)],...
'Color', 'k', 'LineStyle', '-', 'LineWidth', 1.2);
line([positions(k) positions(k)], [q(3) upperWhisker],...
'Color', 'k', 'LineStyle', '-', 'LineWidth', 1.2);
% 绘制均值标记
meanValue = mean(data{k});
plot(positions(k), meanValue, meanSymbol,...
'MarkerSize', 10, 'MarkerFaceColor', 'w',...
'MarkerEdgeColor', 'k', 'LineWidth', 1.5);
% 标记离群值
outliers = data{k}(data{k} < lowerWhisker | data{k} > upperWhisker);
plot(positions(k)*ones(size(outliers)), outliers, 'ko',...
'MarkerSize', 4, 'LineWidth', 1);
end
% 图形美化
ax = gca;
ax.XTick = positions;
ax.XTickLabel = {'Group A', 'Group B', 'Group C', 'Group D'};
ax.TickLength = [0 0];
ax.FontName = 'Arial';
ax.FontSize = 12;
ax.LineWidth = 1.5;
grid on;
xlim([0.5 length(data)+0.5])
ylabel('Value', 'FontSize',14, 'FontWeight','bold')
title('Advanced Violin Plot with Statistical Markers',...
'FontSize',16, 'FontWeight','bold')
% 添加图例
h = zeros(3,1);
h(1) = plot(NaN,NaN,'-', 'Color', colorMap(1,:), 'LineWidth',5);
h(2) = plot(NaN,NaN,'-', 'Color', medianColor, 'LineWidth',2);
h(3) = plot(NaN,NaN,meanSymbol, 'MarkerFaceColor','w','MarkerEdgeColor','k');
legend(h, {'Distribution', 'Median', 'Mean'},...
'Location','northwest', 'FontSize',12)
% 添加色标
colormap(colorMap)
c = colorbar;
c.Ticks = [];
c.Label.String = 'Group Density Distribution';
c.Label.FontSize = 12;
% 附加说明
annotation('textbox', [0.15 0.82 0.2 0.1],...
'String', {'• Whiskers show 1.5IQR range',...
'• Circles denote outliers'},...
'FitBoxToText','on', 'EdgeColor','none',...
'FontSize',10, 'Color',[0.3 0.3 0.3])
% 调整布局
set(gcf, 'Color','w')
hold off
热门推荐
中外驰名的八达岭长城
热熔胶的种类、应用及使用方法详解
绝对不能错过!济南美食排行榜前十,每一道都让你流口水
大五人格测试与MBTI测试相比,哪个更好?
《玉兰黄鹂》的故事
“哪吒”的启示不止在票房
肚子疼也“内卷”?一文解析多种隐藏病症!
古代早婚现象探析:社会、经济及文化因素的影响
【训练】「爆发力训练」提升生活品质!5个动作将肌力化为爆发力
武汉到北京:一段穿越时空的铁路之旅
为什么骨性地包天做掩饰性正畸医生不建议?答案在这里!
西凉锦马超:悲情英雄的传奇人生
“寒门”为什么越来越难出大企业家?这本犀利的书揭开真相!
CBT——心理学在疼痛治疗中的应用
提升篮球投篮技巧的训练方法(从基本动作到高难度训练)
昆明到广州两条高铁线路,耗时几乎一样,票价对比却出乎意料
畜牧兽医专业详解:培养目标、就业方向及核心课程
全自动滚筒洗衣机的清洗方法(轻松保持洗衣机的清洁与卫生)
中国第一个覆盖全国的互联网主干网的诞生
驾驶电动自行车交通安全出行规则大全
如何选择合适的翅片电加热管产品
探索海南三沙市:详尽旅游攻略与必备贴士
月份越大,血压越高?如何管理好孕期血压?
长期吃他汀的患者,一定要牢记“三查两忌”
三国演义:从张飞六次战吕布分析,吕布后期已不是天下第一了
U盘打不开怎么办?多种实用恢复方法详解
低情商和高情商的区别:从名人故事看情商的重要性
深入探讨股票投资:策略、资金运转与市场动态
地道!撸串不止淄博,『山东烧烤江湖』哪个才是你最爱?
电脑文件管理八大技巧:让杂乱无章的文件井井有条