Matlab小提琴图详解,从密度估计到多维度可视化

小提琴图(Violin Plot)是一种结合箱线图核密度估计(Kernel Density Estimation, KDE)的先进统计图表,1998年由Hintze和Nelson首次提出。它能同时展示数据的分布形态、概率密度及关键统计量(如中位数、四分位数),弥补了传统箱线图在多模态分布连续密度展示上的不足,尤其适用于大数据分析复杂分布比较

一、小提琴图的核心组成与数学原理

1. 基本结构

  • 密度曲线
    通过核密度估计得到,左右对称的曲线宽度表示数据在对应值处的概率密度,面积总和为1。
  • 内部标记
    • 中位数线(50%分位数):垂直线标记数据集的中间值。
    • 箱体范围(可选):使用短粗线或矩形表示Q1-Q3(25%-75%分位数)。
    • 须线(可选):显示1.5×IQR范围,或直接调整密度曲线尾部以反映数据范围。

2. 核密度估计(KDE)的数学背景 

3. 与箱线图的对比

特性箱线图小提琴图
分布形态展示仅五数概括,无法显示多峰显示完整密度曲线,包括双峰、偏态
数据复杂度适合中小样本量对比适合大样本或高密度区间分析
异常值检测明确标记离群点依赖密度尾部辨识,可能不够直观
可视化空间需求紧凑,适合多组对比需要更多横向空间以展示密度

二、MATLAB实现基础与进阶

1. 基础小提琴图绘制

MATLAB官方未直接提供小提琴图函数,但可通过ksdensitypatch手动创建:



% 调用示例
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');
% 小提琴图生成程序 - 高级版
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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值