how can I place my error bar in separate bar center?

load SIwb ( % load the workbook of data)
whos LTST PhA_SD BSIR SIR (% find variable)
G = findgroups(LTST, PhA_SD);(% Grouping the variables)
BSIRm=splitapply(@nanmean,BSIR,G);(% Mean of each group of BSIR)
SIRm=splitapply(@nanmean,SIR,G);(% Mean of each group of SIR)
SIRc=[BSIRm,SIRm];(% Combine the SIR mean of Baseline and after SD)
(%Calculate the standard error,SEMM function is uploaded)
BLSIRe=splitapply(@SEMM,BSIR,G);
SIRe=splitapply(@SEMM,SIR,G);
(%combine the std error of BLSIR and SIR)
SIRec=[BLSIRe, SIRe];
(%split the std error into LT and ST)
LTSIRe=SIRec(1:4,:);
STSIRe=SIRec(5:8,:);
(%split the LT and ST)
LTSIR=SIRc(1:4,:);
STSIR=SIRc(5:8,:);
(%Plot the LT graph)
subplot(2,2,1)
(%Plot the data of SI for Long term)
H=bar(LTSIR);
hold on
errorbar(LTSIR,LTSIRe,'.')
%--------------------
legend('Baseline-SIR','SIR','Location','northwest');
grid on
P=gca();
set(P,'XTICKLABEL',{'CH-PhA-','CH-PhA+','SD-PhA-','SD-PhA+'});
ylabel(P,'SIR(%)');
title('LT stress and PhA impact on SIR','FontSize',10)
(%Set up color of each group of bar)
set(H(1),'FaceColor','k');
set(H(2),'FaceColor','r');
The work book data is in attachment.

 Accepted Answer

dpb
dpb on 29 Jan 2018
Edited: dpb on 30 Jan 2018
See the "trick" to locate the midpoint of stacked bars from the hidden property at How-do-i-label-each-bar-in-bar-group-with-a-string-on-top
I don't know if it's yet been made visible or not; add to the complaints to TMW about how poorly-designed the BAR function user interface is in general; I've railed for 20+ years.
ADDENDUM
Stab at adapting to your variables above...
H=bar(LTSIR);
hold on
X=[]; % placeholder for X position from bar
for i=1:length(H) % iterate over number of bar objects
X=[X H(i).XData+hB(i).XOffset]; % and get the center bar group positions
end
hE=errorbar(X,[LTSIR LTSIRe],'.')
You'll have to check on orientation/size of X vector vis a vis the error data arrays but the idea is to retrieve the X locations of the midpoints of the bar and then plot the error bars versus it instead of the nominal bar position.
Again, this kind of thing should be available as properties/methods of the bar object already.
ADDENDUM 2
OK, I had a few minutes...
AB=randi([110 160],4,2); % make some sample data
hB=bar(AB); % make default bar plot
ylim([0 200]) % scale same for rough appearance similar
e=std(AB); % get a sample error value
X=[]; % collect the X values with offset for each
for i=1:length(hB)
X=[X;hB(i).XData+hB(i).XOffset];
end
>> X=X.' % rearrange X by column and show what this is...
X =
0.8571 1.1429
1.8571 2.1429
2.8571 3.1429
3.8571 4.1429
>> hold on % so can add to bar plot
>> hEB=errorbar(X,AB,repmat(e,4,1),'.'); % add error bars
>>
The above gives the attached figure...
You'll have to clean up to match your colors, etc., etc., etc., but shows how to get the correct X positions to plot on each bar in the multiple-bar style.
ADDENDUM 2
Reflection made me realize don't need the loop to retrieve the X coordinates--
X=cell2mat(get(hB,'XData')).' + [hB.XOffset];
will do the same thing using the fact that get will retrieve the same property across multiple handles and return as cell array and knowing that the .XOffset property is a constant for each bar series then recent releases will do the addition using implicit singleton expansion. At the time I wrote the Answer linked to, the latter feature was not yet implemented in the release available to me at the time.

9 Comments

Thank you, but it is so difficult to understand. I am just a beginner.
dpb
dpb on 29 Jan 2018
Edited: dpb on 29 Jan 2018
" is so difficult to understand."
Blame TMW for that...the bar interface is difficult, indeed. :(
I took a stab at it; see updated Answer based on the link as starting point...
I tried your code, but it returned error message:
Undefined variable "hB" or class "hB".
Error in SIscript2 (line 35) X=[X H(i).XData+hB(i).XOffset]; % and get the center bar group positions
That should be observable as changing from the handle for the bar plot in my example to yours that I missed one...read the code and try some on your end, too...
Thank you sooooo much! You are so helpful! I will try !
I run the code below, it goes very well but I do not know why it shows 4 bars behind.
load SIwb % load the workbook of data
whos LTST PhA_SD BSIR SIR % find variable
G = findgroups(LTST, PhA_SD);
% Grouping the variables
BSIRm=splitapply(@nanmean,BSIR,G);% Mean of each group of BSIR
SIRm=splitapply(@nanmean,SIR,G);% Mean of each group of SIR
SIRc=[BSIRm,SIRm];% Combine the SIR mean of Baseline and after SD
%Calculate the standard error,SEMM function is uploaded
BLSIRe=splitapply(@SEMM,BSIR,G); SIRe=splitapply(@SEMM,SIR,G);
%combine the std error of BLSIR and SIR
SIRec=[BLSIRe, SIRe];
%split the std error into LT and ST
LTSIRe=SIRec(1:4,:); STSIRe=SIRec(5:8,:);
%split the LT and ST
LTSIR=SIRc(1:4,:); STSIR=SIRc(5:8,:); %------------------------
%Plot the LT graph
%Plot the data of SI for Long term
% The parameter for each group the x label, mean value(y), standard error
x=['CH-PhA-';'CH-PhA+';'SD-PhA-';'SD-PhA+']; y=LTSIR; error=LTSIRe;
%-------------------------------------------------------
%Plot the LT bar graph
h = bar(y); set(h,'BarWidth',1); % The bars will now touch each other
hold on;
%Make error bar op top of each bar
numgroups = size(y, 1); numbars = size(y, 2); groupwidth = min(0.8, numbars/(numbars+1.5)); for i = 1:numbars
% Based on barweb.m by Bolu Ajiboye from MATLAB File Exchange
x = (1:numgroups) - groupwidth/2 + (2*i-1) * groupwidth / (2*numbars);
% Aligning error bar with individual bar
errorbar(x, y(:,i), error(:,i), 'k', 'linestyle', 'none');
end
%-------------------------------------------
%Set up the property if of the bar graph
legend('Baseline-SIR','SIR','Location','northwest'); grid on P=gca();
set(P,'XTICKLABEL',{'CH-PhA-','CH-PhA+','SD-PhA-','SD-PhA+'});
ylabel(P,'SIR(%)'); title('LT stress and PhA impact on SIR','FontSize',10)
%Set up color of each group of bar set(h(1),'FaceColor','k'); set(h(2),'FaceColor','r'); end
My problem solved! thank you so much!
Why regress to the specific computation that presumes TMW doesn't change anything inside bar instead of using the .XData and .XOffset properties from the actual object?
As the example shows, this works; if you got something unexpected you made an error; debug/fix it instead would be my recommendation.
Thank you so much dpb, you are very helpful!

Sign in to comment.

More Answers (2)

This is a very useful code exmaple for the bar graph and error bar!

Categories

Asked:

on 29 Jan 2018

Answered:

on 25 Jan 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!