Get from Ico-github-logo

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video

Highlights from
raacampbell/sigstar

  • demo_sigstar
    demo function for sigstar
  • sigstar(groups,stats,nosort)
    %Internal functions
  • View all files

Join the 15-year community celebration.

Play games and win prizes!

» Learn more

4.47619
4.5 | 21 ratings Rate this file 55 Downloads (last 30 days) File Size: 76.2 KB File ID: #39696 Version: 1.76
image thumbnail

raacampbell/sigstar

by

Rob Campbell (view profile)

 

02 Jan 2013 (Updated )

Add significance bars and asterisks to various plot types

| Watch this File

File Information
Description

Lines and asterisks indicating significant differences between two groups on a plot are commonly used in the life and social sciences. To my knowledge, no MATLAB function for adding these is openly available. sigstar makes it easy to add lines and significance asterisks joining one or more pairs of groups on bar charts, box plots, and even line plots. The user simply supplies the identities of the two groups and the p-value (which the user has calculated using an appropriate test).

** Usage
Group identity is defined as x-axis locations or, optionally, group names (if the x-axis labels are strings). sigstar converts the supplied p-values to the appropriate number of asterisks and plots these over the lines that link the pair of groups. sigstar attempts to intelligently place lines and asterisks so that they do not overlie existing plot elements. By default, bars with longer horizontal extents are plotted above shorter bars. This is the convention and it looks neater. The user has control over the order in which significance bars are added. Modifying the order provides control over the vertical position of the bars. This is important for obtaining a neat result in a cluttered plot.

** More
See examples in "help sigstar" for details. The handles of the added plot elements are returned by default, providing the user with fine control of the plot's appearance. This is important since it's difficult to provision for all possible usage scenarios (see demo_sigstar). The function should produce publication quality results, but you may need to play with the figure size and asterisk font size.

MATLAB release MATLAB 8.6 (R2015b)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (44)
18 Sep 2016 Anthony  
11 Jun 2016 Rob Campbell

Rob Campbell (view profile)

@Amanda:
Can you file an issue request on the GitHub page with an example of what does not work. The link to the Issue Tracker is in the top right of this page.

Comment only
10 Jun 2016 Rob Campbell

Rob Campbell (view profile)

@Or Gadish Can you contact me via my profile page and I'll include your updates. Then I'll put this thing up on GitHub to make it easier for people to contribute.

Comment only
02 Jun 2016 Evan

Evan (view profile)

Had some issue using with line objects. I replaced findMinY with:

function Y=findMinY_New(x)

oldXLim = get(gca,'XLim');
oldYLim = get(gca,'YLim');

axis tight
set(gca,'xlim',x) %Matlab automatically re-tightens y-axis

yLim = get(gca,'YLim'); %Now have max y value of all elements within range.
Y = max(yLim);

axis normal
set(gca,'XLim',oldXLim,'YLim',oldYLim)

24 Apr 2016 Amanda

Amanda (view profile)

Hi, I cannot to plot it correctly over my bar graphs. All that appears are small vertical dashes and stars above some of the bars...

Can somebody help me please?

Thank you!

Comment only
07 Apr 2016 Or Gadish

Thank you Rob, this is an EXCELLENT file – thank you so much. I've made an updated version combining others' suggestions below and a few others I had. Please contact me if you'd like the updated version, though I've only tested it with boxplots.

Edits:
1. Added AX as input so that you can choose which axis handle to apply sigstar to.
2. Changed Handle Output to cell array.
3. Added the ability to increase YLim as necessary to make space for the stars/n.s. above the objects.
4. Added increased font size to stars/n.s. as per Wei Chen below.
5. Fixed R2014b and onwards issue with Patch object by adding to the findMinY function as per Joseph O'Doherty below.
if isempty(p)
p = findobj(ax, 'tag', 'Box');"
end

25 Mar 2016 Jacqueline Hynes  
16 Mar 2016 Nicky Klaasen  
07 Mar 2016 Murty

Murty (view profile)

 
07 Mar 2016 Murty

Murty (view profile)

Thank you very much.

Comment only
04 Mar 2016 Wei Chen

Awesome function, but does anyone know how to change the size of the "*" and "n.s."?

I found it.

Ans: Change the sub function
" H=makeBar(x,y,p,font_size) "

The text size can be changed by modifying H(2) as follow:

H(2)=text(mean(x(:)),mean(y)+myRange(ylim)*offset,stars,...
'HorizontalAlignment','Center',...
'BackGroundColor','none','FontSize',font_size);

where font_size specify the font size you want.

07 Dec 2015 Tobias Piechowiak

Awesome!! Thanks a lot for sharing!

04 Dec 2015 Armen Enikolopov

If you happen to be plotting multiple bar plots to the same axis (to have different colors, for example), make the following changes to findMinY() to make it work.
> xd=p.XData;
becomes
> xd=cell2mat({p.XData});

and
> yd=p.YData;
> yd=cell2mat({p.YData});

Comment only
27 Aug 2015 Joseph O'Doherty

To handle boxplots in the new graphics system I added the following in the findMin subfunction:

if isempty(p)
p = findobj(gca, 'tag', 'Box');
end

Comment only
23 Aug 2015 Yeong Seok Jeong

How can I modulate star bar position? Actually, I want to draw star bar above my error bar

Comment only
15 Jul 2015 Jan Schupp

awesomeness!

04 Jun 2015 Antoine

Hi Rob,

Thanks a lot for sharing your matlab function.
unfortunately I have been not able to run it on Matlab R2009b.

When I try the first example:
bar([5,2,1.5])
sigstar({[1,2], [1,3]})

I have this error:
??? Error: File: sigstar.m Line: 167 Column: 11
Expression or statement is incorrect--possibly unbalanced (, {, or [.

It's look like the "Groups" input is not correct but I don't understand why.
Do you have any ideas?

Thanks a lot for your help.

Comment only
30 Apr 2015 Zheng Zhiwei

very nice job! thank you!

17 Feb 2015 Anne Urai

In 2014b, the problem lies in the subfunction Y=findMinY(x). Specifically, p = findobj(gca,'Type','Patch'); returns an empty handle, since Patches are handled differently. For an errorbar sigstar (but haven't tried with bargraphs or lines, so this is not a general solution) I solved the problem by changing 'Patch' into 'Errorbar'.

13 Nov 2014 Rob Campbell

Rob Campbell (view profile)

I will look into this soonish.

Comment only
13 Nov 2014 Alexander

Does not work in 2014b release, but looks great in a previous version of matlab (2011b for me).

In 2014b I get this error :
Error using plot
Vectors must be the same length.

Error in sigstar>makeBar (line 249)
H(1)=plot(x(:),y,'-k','LineWidth',1.5);

Error in sigstar (line 186)
H(ii,:)=makeBar(xlocs(ii,:),thisY,stats(ii));

Error in demo_sigstar (line 11)
H=sigstar(groups,[0.001,0.05,0.04]);

when I try to run demo_sigstar

03 Nov 2014 ondrej

ondrej (view profile)

Error using plot
Vectors must be the same length.

Error in sigstar>makeBar (line 249)
H(1)=plot(x(:),y,'-k','LineWidth',1.5);

Error in sigstar (line 186)
H(ii,:)=makeBar(xlocs(ii,:),thisY,stats(ii));

14 Oct 2014 Robert

Robert (view profile)

Very nice function, thanks for sharing!

21 Aug 2014 Benjamin Meltzer

Yes that makes sense. Thanks so much

Comment only
19 Aug 2014 Rob Campbell

Rob Campbell (view profile)

This is the minimal example:
>> clf
>> bar([1,2;3,4],'grouped')
>> sigstar([1.1,2.1])
>> sigstar([0.9,1.1])

Does that make sense? Each group is centred around an integer. You can also automate this by extracting the x values from the graph. But the above works as a first-pass.

Comment only
19 Aug 2014 Benjamin Meltzer

Hi Rob
Great code, thanks. I have a grouped bar chart, and would like to add significance stars between bars within each group. I think similar to Ellen's question.
Could you please advise?

Comment only
14 Aug 2014 Mahsa

Mahsa (view profile)

I've been trying to change the font size of the asterisk, but I can't find a way. I can easily change the line width. Has anyone done this?

Comment only
08 Aug 2014 Rob Campbell

Rob Campbell (view profile)

Ellen, I don't really understand your question. Probably the best thing is for you to mail me off-line with an example of what you're trying to do.

Comment only
08 Aug 2014 Ellen

Ellen (view profile)

This is a really useful script but I am struggling to make the sigstar go within the groups - for example in x1, there are 3 bars, and I want to put sigstars between them as opposed to putting sigstars between x1 and x2. Could someone assist? I see someone already asked but I'm still not sure.

03 Jul 2014 Rob Campbell

Rob Campbell (view profile)

I don't think I understand. This function is just a way of reporting statistical results that you have already calculated. So it's up to you to do your stats appropriately if your groups have different sizes.

Comment only
03 Jul 2014 Andreas

Andreas (view profile)

Very great tool!

Is there an easy way to use "sigstar" for groups of different size, for example 10 and 20 subjects

15 Apr 2014 Dimitrios Korkinof  
31 Mar 2014 Rob Campbell

Rob Campbell (view profile)

Look through the examples, it should be clear(ish). You manually choose the x values want and tell it to draw the bar across those positions. This is pretty much the only way of doing it since there's no way for the function to know which locations you want to link. It can't know this because it doesn't know the structure of your data.

Comment only
31 Mar 2014 Mech Princess

how do I do this if my bar plot has more than one bar per x axis value?

Comment only
15 Feb 2014 Rob Campbell

Rob Campbell (view profile)

Daniel,

The answer is "sort of." On the one hand, yes, you can significance indicators however you want on a line plot. I think Maria's example and those in the function show how to this. On the other hand, *should* you be doing it? What do you mean by "significance of two lines"? In most cases, if you have data that can be plotted along a line, then you should be doing a regression of some sort and reporting the relevant coefficients in the text. It is easy to over-use the graphical significance indicators. To be honest, I myself have never used the sigstar for anything. :)

Rob

Comment only
15 Feb 2014 Daniel

Daniel (view profile)

great tool. Is there any chance to check significance of to line plots?

I'd like to check out the significance of to lines at -10:5:10. So above the lines a star or two would represent significance. Is this possible?

Maybe this works very similar to Maria's group comparison solution, but I was not able to modify it the right way...

05 Feb 2014 Seban

Seban (view profile)

Thanks to the creater of the script and to Maria, too.

18 Oct 2013 Jeroen Aeles  
27 Mar 2013 Rob Campbell

Rob Campbell (view profile)

Awesome graph! I'm glad the function can cope with this sort of thing.

Comment only
27 Mar 2013 Maria

Maria (view profile)

Thank you for your quick answer!

I was able to figure out how. Here is my example for within groups and between groups comparisons :

figure
barvalues=rand(3,5);
errorsL=zeros(3,5);
errorsU=ones(3,5)*0.05;
handles.bars=bar(barvalues);
hold on
numgroups=size(barvalues, 1);
numbars=size(barvalues, 2);

for i=1:numbars
x=get(get(handles.bars(i), 'children'), 'xdata');
x=mean(x([1 3],:));
pos_bars(i,:)=x;
handles.errors(i)=errorbar(x,barvalues(:,i), errorsL(:,i), errorsU(:,i), 'k', 'linestyle', 'none', 'linewidth', 1);
end
handles.pos_bars=pos_bars;
comp_wgroups={ [handles.pos_bars(1),handles.pos_bars(2)], ...
[handles.pos_bars(1),handles.pos_bars(3)], ...
[handles.pos_bars(1),handles.pos_bars(4)], ...
[handles.pos_bars(2),handles.pos_bars(3)], ...
[handles.pos_bars(2),handles.pos_bars(4)], ...
[handles.pos_bars(3),handles.pos_bars(4)]};
sigstar(comp_wgroups)

comp_bgroups={ [handles.pos_bars(5),handles.pos_bars(6)], ...
[handles.pos_bars(5),handles.pos_bars(7)], ...
[handles.pos_bars(5),handles.pos_bars(8)]};
sigstar(comp_bgroups)

Comment only
27 Mar 2013 Rob Campbell

Rob Campbell (view profile)

Sure, here's an example:
>> clf
>> bar(rand(3,5))
>> sigstar([1,2])

I just tested it, it works.

Comment only
27 Mar 2013 Maria

Maria (view profile)

This function is great, exactly what I was looking for!

But I am still not able to make it work with a grouped bar graph. Can you please provide an example?

25 Jan 2013 Rob Campbell

Rob Campbell (view profile)

Felix, I have submitted an update that should fix the issue with the grouped error bars.

Comment only
25 Jan 2013 Felix

Felix (view profile)

Unfortunately it doesn't work with grouped bar charts.
It' like to add lines and asteriks between two groups of bars, but it gives the error:
"Undefined function or method 'lt' for input arguments of type 'cell'." in findMinY...
would it be difficult to add this functionality?

Comment only
Updates
16 Jan 2013 1.1

Add the ability to label data as being not significantly different. Example 2 in the function's help text shows how to do this.

25 Jan 2013 1.2

Update to work with grouped error bars.

17 Oct 2013 1.3

Update code to no longer call the range function, which is part of the stats toolbox.

15 Nov 2014 1.4

Bar plot code updated to run on 2014b. Boxplots *don't* work (yet) on 2014b. Sorry for the slow updates, but I personally don't use 2014b because the new graphics engine is clearly not ready yet.

25 Aug 2015 1.4

change description

10 Jun 2016 1.41

typo

11 Jun 2016 1.75

Fix for >R2014b. Now box plots and line plots work with new versions of MATLAB. Code is neater. A few other small improvements. Add demo code. Move to GitHub.

11 Jun 2016 1.76

update description that was stripped when moving to GitHub.

Contact us