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

一、准备环境

  1. matlab版本:matlab 2021b

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

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

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

二、柱状图绘制

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、多组不同条件的柱状图绘制

在这里插入图片描述

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、多组不同条件的柱状图绘制(颜色由浅至深)

在这里插入图片描述

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、多组不同条件的柱状图绘制(不同组颜色不同,颜色由浅至深)

在这里插入图片描述

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、多组不同条件的柱状图绘制(添加显著性差异*)

在这里插入图片描述

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版本较低,不支持显示以一个x值为中心的一组条形,即运行下面matlab官方代码报错。
在这里插入图片描述

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

2、其他问题

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

四、参考链接

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

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

2、Statistical significance line

Statistical significance line

  • 4
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
1. 显著点的检测 Itti的A Model of Saliency-Based Visual Attention for Rapid Scene Analysis (TPAMI 1999)论文是显著性检测的鼻祖论文,检测出来的是用户关注的点。 2. 显著区域的检测 侯晓迪同学在2007年发表的一篇CVPR的论文,用很简单的方法检测了显著性区域,那之后显著性检测主要以区域检测为主:Saliency detection: A spectral residual approach (CVPR 2007),虽然之后有人诟病这篇论文有不足之处,但该想法简单,推动了显著性研究的普及。侯同学靠这一篇文章再加上投稿期间的趣事,就封神了。 3. 其他经典的显著性检测方法 在那之后陆续又有一些经典的显著性检测算法被提出:https://blog.csdn.net/touch_dream/article/details/78716507 可以看这个博文。 4. 基于深度学习的显著性检测 再之后,显著性检测领域就进入了Deep Learning时代, Deep Visual Attention Prediction TIP2018 (CODE)     https://github.com/wenguanwang/deepattention Predicting Human Eye Fixations via an LSTM-based Saliency Attentive Model (CODE)     https://github.com/marcellacornia/sam CVPR2016 Shallow and Deep Convolutional Networks for Saliency Prediction (CODE)     https://github.com/imatge-upc/saliency-2016-cvpr Saliency Detection with GAN (2017)     https://github.com/imatge-upc/saliency-salgan-2017  (CODE)     https://github.com/batsa003/salgan/ (PyTorch的版本) 5. 非自然图象的显著性检测 例如,海报的显著性检测,图表的显著性检测,地理数据的显著性检测等等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值