Matlab绘制柱状图(含显著性差异*)

一、准备环境

  1. matlab版本:matlab 2021b

  2. 代码使用之前必须先安装cbrewer函数包,参考链接:Matlab绘图配色解决方案——cbrewer函数的介绍与使用

  3. 如果想添加显著性差异(*),必须下载sigline函数,参考链接:Statistical significance
    line

  4. 需要cbrewer函数包的,加作者微信(song408862610),因为我也不知道怎么上传文件

二、柱状图绘制

1、不同条件的柱状图绘制

Matlab绘制柱状图(含显著性差异*)_第1张图片

clear all; close all; clc;
%% n对应的是有几个柱子
data_mean = [212,238,250]; %均值
data_std = [56,65,59]; %标准差

%% 颜色选择 根据自己的需求选择
RGB1 = cbrewer('seq', 'Greys', 11, 'linear');
RGB2 = cbrewer('seq', 'Blues', 11, 'linear');
RGB3 = cbrewer('seq', 'Greens', 11, 'linear');
RGB = [RGB1(4,:);RGB2(5,:);RGB3(5,:)]; %每个柱子的颜色

%% 绘图
figure
y = data_mean; 
neg = data_std; 
pos = data_std; 
n = size(y,2);
x = 1 : n;
h = bar(x, y);
%% 单独设置第j个柱子的颜色
for j = 1 : n
    h.FaceColor = 'flat';
    h.CData(j,:) = RGB(j,:);
    h.EdgeColor = 'flat';
end
%% 获取误差线 x 值
xx = h.XEndPoints;
% 绘制误差线
hold on
errorbar(xx, y, neg, pos, 'LineStyle', 'none', 'Color', 'k', 'LineWidth', 1);
hold off
%% 设置figure的格式
% matlab中默认字体是 Arial 8% 设置xticklabels和yticklabels的字体以及字体的大小
set(gca, 'FontSize',13);
set(gca,'FontName','Times New Roman');
% 设置 x 轴 xticklabels
set(gca, 'XTickLabel', {'\fontname{Times New Roman}Con1', '\fontname{Times New Roman}Con2', ...
    '\fontname{Times New Roman}Con3'},'FontSize',13);
% xticks([]) %如果不想设置xticklabels,使用该命令
% 设置 y 轴标签
ylabel('\fontname{Times New Roman}y\fontname{宋体}轴标签','FontSize',15);
% 设置y轴范围
ylim([0 350])
% 去除上边界和右边界
box off
% 设置边框的粗细
set(gca,'XColor','k','YColor','k','linewidth',1);

2、多组不同条件的柱状图绘制

Matlab绘制柱状图(含显著性差异*)_第2张图片

clear all; close all; clc;
%% 数据 % m * n的矩阵,m对应的是一共有几组,n对应的是每组有几个柱子
data_mean = [212,238,250;212,238,250];
data_std = [56,65,59;56,65,59];

%% 颜色选择 根据自己的需求选择
RGB1 = cbrewer('seq', 'Greys', 11, 'linear');
RGB2 = cbrewer('seq', 'Blues', 11, 'linear');
RGB3 = cbrewer('seq', 'Greens', 11, 'linear');
RGB = [RGB1(4,:);RGB2(5,:);RGB3(5,:)];
%% 绘图
figure
y = data_mean; 
neg = data_std; 
pos = data_std; 
m = size(y,1);
n = size(y,2);
x = 1 : m;
h = bar(x, y);
%% 单独设置第i个组第j个柱子的颜色
for i = 1 : m
    for j = 1 : n
        h(1, j).FaceColor = 'flat';
        h(1, j).CData(i,:) = RGB(j,:);
        h(1,j).EdgeColor = 'flat';
    end
end
%% 获取误差线 x 值
xx = zeros(m, n);
for i = 1 : n
    xx(:, i) = h(1, i).XEndPoints';
end
% 绘制误差线
hold on
errorbar(xx, y, neg, pos, 'LineStyle', 'none', 'Color', 'k', 'LineWidth', 1);
hold off
%% 设置figure的格式
% matlab中默认字体是 Arial 8% 设置xticklabels和yticklabels的字体以及字体的大小
set(gca, 'FontSize',13);
set(gca,'FontName','Times New Roman');
% 设置 x 轴 xticklabels
set(gca, 'XTickLabel', {'\fontname{宋体}第\fontname{Times New Roman}1\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}2\fontname{宋体}'},'FontSize',13);
% xticks([]) %如果不想设置xticklabels,使用该命令
% 设置legend图例
legend({'Con1', 'Con2', 'Con3'},'NumColumns',3,'Location','north','FontName','Times New Roman','FontSize',13);
legend('boxoff'); %去除legend的边框
% 设置 y 轴标签
ylabel('\fontname{Times New Roman}y\fontname{宋体}轴标签','FontSize',15);
% 设置y轴范围
ylim([0 400])
% 去除上边界和右边界
box off
% 设置边框的粗细
set(gca,'XColor','k','YColor','k','linewidth',1);

3、多组不同条件的柱状图绘制(颜色由浅至深)

Matlab绘制柱状图(含显著性差异*)_第3张图片

clear all; close all; clc;
%% 数据 % m * n的矩阵,m对应的是一共有几堆,n对应的是每堆有几个柱子
data_mean = [212,238,250;212,238,250;212,238,250;212,238,250];
data_std = [56,65,59;56,65,59;56,65,59;56,65,59];

%% 颜色选择 根据自己的需求选择
RGB1 = cbrewer('seq', 'Blues', 12, 'linear');
RGB2 = cbrewer('seq', 'Greens', 12, 'linear');
RGB3 = cbrewer('seq', 'Purples', 12, 'linear');
RGB1  = RGB1([5,7,8,9],:);
RGB2  = RGB2([5,7,8,9],:);
RGB3  = RGB3([5,7,8,9],:);
RGB = cat(3,RGB1,RGB2,RGB3);
%% 绘图
figure
y = data_mean; 
neg = data_std; 
pos = data_std; 
m = size(y,1);
n = size(y,2);
x = 1 : m;
h = bar(x, y);
%% 单独设置第i个组第j个柱子的颜色
for i = 1 : m
    for j = 1 : n
        h(1, j).FaceColor = 'flat';
        h(1, j).CData(i,:) = squeeze(RGB(i,:,j));
        h(1,j).EdgeColor = 'flat';
    end
end

%% 获取误差线 x 值
xx = zeros(m, n);
for i = 1 : n
    xx(:, i) = h(1, i).XEndPoints';
end
% 绘制误差线
hold on
errorbar(xx, y, neg, pos, 'LineStyle', 'none', 'Color', 'k', 'LineWidth', 1);
hold off
%% 设置figure的格式
% matlab中默认字体是 Arial 8% 设置xticklabels和yticklabels的字体以及字体的大小
set(gca, 'FontSize',13);
set(gca,'FontName','Times New Roman');
% 设置 x 轴 xticklabels
set(gca, 'XTickLabel', {'\fontname{宋体}第\fontname{Times New Roman}1\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}2\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}3\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}4\fontname{宋体}'}, 'FontSize',13);
% xticks([]) %如果不想设置xticklabels,使用该命令
% 设置legend图例
legend({'Con1', 'Con2', 'Con3'},'NumColumns',3,'Location','north','FontName','Times New Roman','FontSize',13);
legend('boxoff'); %去除legend的边框
% 设置 y 轴标签
ylabel('\fontname{Times New Roman}y\fontname{宋体}轴标签','FontSize',15);
% 设置y轴范围
ylim([0 400])
% 去除上边界和右边界
box off
% 设置边框的粗细
set(gca,'XColor','k','YColor','k','linewidth',1);

4、多组不同条件的柱状图绘制(不同组颜色不同,颜色由浅至深)

Matlab绘制柱状图(含显著性差异*)_第4张图片

clear all; close all; clc;
%% 数据 % m * n的矩阵,m对应的是一共有几堆,n对应的是每堆有几个柱子
data_mean = [212,238,250;212,238,250;212,238,250;212,238,250];
data_std = [56,65,59;56,65,59;56,65,59;56,65,59];

%% 颜色选择 根据自己的需求选择
RGB1 = cbrewer('seq', 'Blues', 12, 'linear');
RGB2 = cbrewer('seq', 'Greens', 12, 'linear');
RGB3 = cbrewer('seq', 'Purples', 12, 'linear');
RGB4 = cbrewer('seq', 'Greys', 12, 'linear');
RGB1  = RGB1([5,7,8,9],:);
RGB2  = RGB2([5,7,8,9],:);
RGB3  = RGB3([5,7,8,9],:);
RGB4  = RGB4([5,7,8,9],:);
RGB = cat(3,RGB1,RGB2,RGB3,RGB4);
%% 绘图
figure
y = data_mean; 
neg = data_std; 
pos = data_std; 
m = size(y,1);
n = size(y,2);
x = 1 : m;
h = bar(x, y);
%% 单独设置第i个组第j个柱子的颜色
for i = 1 : m
    for j = 1 : n
        h(1, j).FaceColor = 'flat';
        h(1, j).CData(i,:) = squeeze(RGB(j,:,i));
        h(1,j).EdgeColor = 'flat';
    end
end
%% 获取误差线 x 值
xx = zeros(m, n);
for i = 1 : n
    xx(:, i) = h(1, i).XEndPoints';
end
% 绘制误差线
hold on
errorbar(xx, y, neg, pos, 'LineStyle', 'none', 'Color', 'k', 'LineWidth', 1);
hold off
%% 设置figure的格式
% matlab中默认字体是 Arial 8% 设置xticklabels和yticklabels的字体以及字体的大小
set(gca, 'FontSize',13);
set(gca,'FontName','Times New Roman');
% 设置 x 轴 xticklabels
set(gca, 'XTickLabel', {'\fontname{宋体}第\fontname{Times New Roman}1\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}2\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}3\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}4\fontname{宋体}'}, 'FontSize',13);
% xticks([]) %如果不想设置xticklabels,使用该命令
% 设置legend图例
% 设置 y 轴标签
ylabel('\fontname{Times New Roman}y\fontname{宋体}轴标签','FontSize',15);
% 设置y轴范围
ylim([0 400])
% 去除上边界和右边界
box off
% 设置边框的粗细
set(gca,'XColor','k','YColor','k','linewidth',1);

5、多组不同条件的柱状图绘制(添加显著性差异*)

Matlab绘制柱状图(含显著性差异*)_第5张图片

clear all; close all; clc;
%% 数据 % m * n的矩阵,m对应的是一共有几组,n对应的是每堆有几个柱子
data_mean = [212,238,250;212,238,250]; % 均值
data_std = [56,65,59;56,65,59]; % 标准差

%% 颜色选择 根据自己的需求选择
RGB1 = cbrewer('seq', 'Greys', 11, 'linear');
RGB2 = cbrewer('seq', 'Blues', 11, 'linear');
RGB3 = cbrewer('seq', 'Greens', 11, 'linear');
RGB = [RGB1(4,:);RGB2(5,:);RGB3(5,:)];
%% 绘制bar图
figure
y = data_mean; 
neg = data_std; 
pos = data_std; 
m = size(y,1);
n = size(y,2);
x = 1 : m;
h = bar(x, y);
%% 单独设置第i个组第j个柱子的颜色
for i = 1 : m
    for j = 1 : n
        h(1, j).FaceColor = 'flat';
        h(1, j).CData(i,:) = RGB(j,:);
        h(1,j).EdgeColor = 'flat';
    end
end
%% 获取误差线 x 值
xx = zeros(m, n);
for i = 1 : n
    xx(:, i) = h(1, i).XEndPoints';
end
% 绘制误差线
hold on
errorbar(xx, y, neg, pos, 'LineStyle', 'none', 'Color', 'k', 'LineWidth', 1);
%% 绘制显著性差异
% 演示一下
t1 = 1; %第t1组
n1 = 1; %第t1组的第n1个柱子
n2 = 3; %第t1组的第n2个柱子
%获取显著性差异线的x坐标
x1 = xx(t1,n1); x2 = xx(t1,n2);
%获取显著性差异线的y坐标
ySig = max(y(t1,n1)+pos(t1,n1),y(t1,n2)+pos(t1,n2));
%绘制显著性差异
sigline([x1,x2],[],ySig);

% 再演示一下
t1 = 2; %第t1组
n1 = 2; %第t1组的第n1个柱子
n2 = 3; %第t1组的第n2个柱子
%获取显著性差异线的x坐标
x1 = xx(t1,n1); x2 = xx(t1,n2);
%获取显著性差异线的y坐标
ySig = max(y(t1,n1)+pos(t1,n1),y(t1,n2)+pos(t1,n2));
%绘制显著性差异
sigline([x1,x2],[],ySig);


%% 设置figure的格式
% matlab中默认字体是 Arial 8% 设置xticklabels和yticklabels的字体以及字体的大小
set(gca, 'FontSize',13);
set(gca,'FontName','Times New Roman');
% 设置 x 轴 xticklabels
set(gca, 'XTickLabel', {'\fontname{宋体}第\fontname{Times New Roman}1\fontname{宋体}组', ...
    '\fontname{宋体}第\fontname{Times New Roman}2\fontname{宋体}'},'FontSize',13);
% xticks([]) %如果不想设置xticklabels,使用该命令
% 设置legend图例
legend({'Con1', 'Con2', 'Con3'},'NumColumns',3,'Location','north','FontName','Times New Roman','FontSize',13);
legend('boxoff'); %去除legend的边框
% 设置 y 轴标签
ylabel('\fontname{Times New Roman}y\fontname{宋体}轴标签','FontSize',15);
% 设置y轴范围
ylim([0 450])
% 去除上边界和右边界
box off
% 设置边框的粗细
set(gca,'XColor','k','YColor','k','linewidth',1);
function sigline(xs,lbl,h,yv)
%SIGLINE plots a line of statistical significance on the current axis
%   sigline(xs) plots a significance line between the value in the 2D
%   vector xs along the x-coordinate. 
% 
%   sigline(xs,lbl) places a text lbl beside the significance line.
% 
%   sigline(xs,lbl,h) attempts to plot the significance line above a
%   highest value in a graphics object with handle h. If h is not a
%   graphics handle, the line will be plotted above the value of h. 
% 
%   sigline(xs,...,vy) give a way to specify that the line be plotted above
%   vy which should not be assumed to be a graphics object. This is
%   optional and overrides h; but probaly won't ever be needed. The vy is a
%   value on the y-axis above which the sig line is plotted. It is only
%   useful for a possibly, rare occurance of a given y in h unwantedly
%   matching a graphic object in value.
% 
%   Examples #1: Plot 5 random points and add a significance line between
%   point 2 and 4.
%   plot(rand(5,1))
%   sigline([2,4])
% 
%   Examples #3: Plot 5 random points as bar chart and add a significance
%   line between point 2 and 3 and print p=0.05 beside it.
%   bar(rand(5,1))
%   sigline([2,3],'p=0.05')
% 
%   Examples #4: Plot 5 random points and add a significance line between
%   point 2 and 4 and specify the handle to be used to obtaine the value
%   above which the line will be plotted.
%   h=plot(rand(5,1))
%   sigline([2,4],[],h)
% 
%   Examples #5: Plot 5 random points and add a significance line between
%   point 2 and 4 and a value above which the line will be plotted.
%   plot(rand(5,1))
%   sigline([2,4],[],0.9)
%
%   TODO: To avoid messing up legend, we should redo this function using
%   drawing rather than plots? A work aroound for now is to plot legends b4
%   calling this function.

if nargin==1
    y=gety(gca);
    lbl=[];
elseif nargin==2
    y=gety(gca);
elseif nargin==3
    y=gety(h);
elseif nargin==4
    y=yv;
end


% Now plot the sig line on the current axis
hold on
xs=[xs(1);xs(2)];
plot(xs,[1;1]*y*1.1,'-k', 'LineWidth',1);%line
plot(mean(xs), y*1.15, '*k')% the sig star sign
if lbl
    text(mean(xs)*1.1, y*1.18, lbl)% the sig star sign
end
plot([1;1]*xs(1),[y*1.05,y*1.1],'-k', 'LineWidth',1);%left edge drop
plot([1;1]*xs(2),[y*1.05,y*1.1],'-k', 'LineWidth',1);%right edge drop
hold off

%--------------------------------------------------------------------------
% Helper function that Returns the largest single value of ydata in a given
% graphic handle. It returns the given value if it is not a graphics
% handle. 
function y=gety(h)
    %Returns the largest single value of ydata in a given graphic handle
    %h= figure,axes,line. Note that y=h if h is not a graphics
    if isgraphics(h) 
        switch(get(h,'type'))
            case {'line','hggroup','patch'},
                y=max(get(h,'ydata'));
                return;
            otherwise
                ys=[];
                hs=get(h,'children');
                for n=1:length(hs)
                    ys=[ys,gety(hs(n))];
                end
                y=max(ys(:));
        end
    else
        y=h;
    end
end

end

三、可能存在的问题

1、错误使用bar,X和Y的长度必须相同

Matlab绘制柱状图(含显著性差异*)_第6张图片

原因是matlab版本较低,不支持显示以一个x值为中心的一组条形,即运行下面matlab官方代码报错。
Matlab绘制柱状图(含显著性差异*)_第7张图片

解决方法:升级matlab版本,2021及以上版本是可以,2018及以下版本不可以。至于2019和2020版本是否可用,作者也不清楚。

2、其他问题

解决方法:学会使用matlab中的help百度一下,文章下面评论、加作者微信(song408862610)询问

四、参考链接

1、Matlab 绘图配色解决方案 — cbrewer 函数的介绍与使用

Matlab绘图配色解决方案——cbrewer函数的介绍与使用

2、Statistical significance line

Statistical significance line

你可能感兴趣的:(matlab,matlab,算法)