MATLAB | 绘图复刻(十七) | 半小提琴图

文摘   2024-09-11 09:02   英国  
请尊重原创劳动成果
转载请注明本文链接
及文章作者:slandarer

嘿,真的是好久不见,最近有点过于忙了,今天更一个好久之前粉丝问的半小提琴图的绘制方法,要复刻这张图:

绘制效果如下:

还是挺好看的,下面直接进入正题:

教程部分

0 数据准备

这里随机生成了两组数据DataL和DataR,分别是半小提琴图左侧小提琴的数据和右侧小提琴的数据,同时需要设置好各个位置标签变量名,类名,显著性结果等文本信息。

Name = {'AAA''BBB''CCC'};
ClassName = {'Ambient','WarNing'};
Condition = {'ns','*','**'};

% 随机生成数据
rng(2)
offset = repmat(rand(13), [100,1]).*2;
DataL = rand(1003) + offset;
DataR = rand(1003) + offset;

1 其他参数

% 配色
CList = [153,153,253255,153,154]./255;
% 此参数用于调整小提琴图宽度
width = .36;

2 坐标区域修饰

生成一个空的坐标区域,并设置字体,X轴标签等信息:

% 坐标区域修饰
ax = gca; 
ax.NextPlot = 'add';
ax.Box = 'on';
ax.XGrid = 'on';
ax.YGrid = 'on';
ax.XTick = 1:length(Name);
ax.XTickLabel = Name;
ax.FontName = 'Times New Roman';
ax.FontSize = 15;
ax.XTickLabelRotation = 30;
ax.XLim = [0length(Name)] + .5;

3 绘制小提琴图

使用ksdensity函数计算核密度,使用quantile函数计算分位数,使用median计算中位数,并循环绘图:

for i = 1:length(Name)
    % 绘制核密度曲线
    [fL, yiL] = ksdensity(DataL(:, i));
    [fR, yiR] = ksdensity(DataR(:, i));
    fill(ax, (i - fL.*width), yiL, CList(1,:), 'EdgeColor','none''FaceAlpha',.5)
    fill(ax, (i + fR.*width), yiR, CList(2,:), 'EdgeColor','none''FaceAlpha',.5)
    % 绘制四分位数线
    qt25L = quantile(DataL(:, i), 0.25); qt75L = quantile(DataL(:, i), 0.75);
    plot(ax, [-11nan-11nan00].*.05 + i - .08, [qt75L, qt75L, nan, qt25L, qt25L, nan, qt75L, qt25L], 'LineWidth',1'Color','k')
    qt25R = quantile(DataR(:, i), 0.25); qt75R = quantile(DataR(:, i), 0.75);
    plot(ax, [-11nan-11nan00].*.05 + i + .08, [qt75R, qt75R, nan, qt25R, qt25R, nan, qt75R, qt25R], 'LineWidth',1'Color','k')
    % 绘制中位数点
    medL = median(DataL(:, i));
    scatter(i - .08, medL, 20'filled''CData',[0,0,0]);
    medR = median(DataR(:, i));
    scatter(i + .08, medR, 20'filled''CData',[0,0,0]);
    % 绘制显著性标签
    text(ax, imax([yiL(:);yiR(:)]), Condition{i},...
        'FontSize',16'FontName','Times New Roman',...
        'HorizontalAlignment','center''VerticalAlignment','baseline')
end

4 绘制图例

在坐标区域外再画两个填充矩形用来当作图例的句柄:

% 绘制图例
fillHdl(1) = fill(ax, [-1,-2,-1], [0,0,1], CList(1,:), 'EdgeColor','none''FaceAlpha',.5);
fillHdl(2) = fill(ax, [-1,-2,-1], [0,0,1], CList(2,:), 'EdgeColor','none''FaceAlpha',.5);
lgdHdl = legend(fillHdl, ClassName, 'Location','best''Box','off');
lgdHdl.ItemTokenSize=[20,20];

完整代码

% half violin plot 

Name = {'AAA''BBB''CCC'};
ClassName = {'Ambient','WarNing'};
Condition = {'ns','*','**'};

% 随机生成数据
rng(2)
offset = repmat(rand(13), [100,1]).*2;
DataL = rand(1003) + offset;
DataR = rand(1003) + offset;


% 配色
CList = [153,153,253255,153,154]./255;
% CList = [0,64,115; 254,103,110]./255;
% 此参数用于调整小提琴图宽度
width = .36;

% 坐标区域修饰
ax = gca; 
ax.NextPlot = 'add';
ax.Box = 'on';
ax.XGrid = 'on';
ax.YGrid = 'on';
ax.XTick = 1:length(Name);
ax.XTickLabel = Name;
ax.FontName = 'Times New Roman';
ax.FontSize = 15;
ax.XTickLabelRotation = 30;
ax.XLim = [0length(Name)] + .5;


for i = 1:length(Name)
    % 绘制核密度曲线
    [fL, yiL] = ksdensity(DataL(:, i));
    [fR, yiR] = ksdensity(DataR(:, i));
    fill(ax, (i - fL.*width), yiL, CList(1,:), 'EdgeColor','none''FaceAlpha',.5)
    fill(ax, (i + fR.*width), yiR, CList(2,:), 'EdgeColor','none''FaceAlpha',.5)
    % 绘制四分位数线
    qt25L = quantile(DataL(:, i), 0.25); qt75L = quantile(DataL(:, i), 0.75);
    plot(ax, [-11nan-11nan00].*.05 + i - .08, [qt75L, qt75L, nan, qt25L, qt25L, nan, qt75L, qt25L], 'LineWidth',1'Color','k')
    qt25R = quantile(DataR(:, i), 0.25); qt75R = quantile(DataR(:, i), 0.75);
    plot(ax, [-11nan-11nan00].*.05 + i + .08, [qt75R, qt75R, nan, qt25R, qt25R, nan, qt75R, qt25R], 'LineWidth',1'Color','k')
    % 绘制中位数点
    medL = median(DataL(:, i));
    scatter(i - .08, medL, 20'filled''CData',[0,0,0]);
    medR = median(DataR(:, i));
    scatter(i + .08, medR, 20'filled''CData',[0,0,0]);
    % 绘制显著性标签
    text(ax, imax([yiL(:);yiR(:)]), Condition{i},...
        'FontSize',16'FontName','Times New Roman',...
        'HorizontalAlignment','center''VerticalAlignment','baseline')
end

% 绘制图例
fillHdl(1) = fill(ax, [-1,-2,-1], [0,0,1], CList(1,:), 'EdgeColor','none''FaceAlpha',.5);
fillHdl(2) = fill(ax, [-1,-2,-1], [0,0,1], CList(2,:), 'EdgeColor','none''FaceAlpha',.5);
lgdHdl = legend(fillHdl, ClassName, 'Location','best''Box','off');
lgdHdl.ItemTokenSize=[20,20];

以上已经是完整代码,如果懒得复制,可以去绘图复刻系列gitee仓库查看:

  • https://gitee.com/slandarer/PLTreprint/


slandarer随笔
slandarer个人公众号,目前主要更新MATLAB相关内容。
 最新文章