MATLAB Answers

0

How do I change the width of the horizontal lines at top and bottom of error bars in my Errorbar plot?

For example, how can I increase the width of each of the error bars in the following plot:

figure;
X = 0:pi/10:pi;
Y = sin(X);
E = std(Y)*ones(size(X));
errorbar(X,Y,E);

Products


Release

R2006a

4 Answers

Answer by MathWorks Support Team on 23 Jun 2016
 Accepted Answer

In MATLAB R2016b, this can be accomplished using the ‘CapSize’ property of the Errorbar plot. The following code illustrates how to do this:

 

x = 0:pi/10:pi;
y = sin(x);
e = std(y)*ones(size(x));
 
figure
h = errorbar(x,y,e);
h.CapSize = 12;

 

 

In MATLAB versions R2014b through R2016a, this functionality is not present.

 

In MATLAB R2014a and earlier, you can change the width of these horizontal lines by modifying the ‘Xdata’ of each of them. The following code illustrates how to do this in an automated fashion:

 

hf = figure;
X = 0:pi/10:pi;
Y = sin(X);
E = std(Y)*ones(size(X));
ha = errorbar(X,Y,E);
hb = get(ha,'children'); 
Xdata = get(hb(2),'Xdata');
temp = 4:3:length(Xdata);
temp(3:3:end) = [];
% xleft and xright contain the indices of the left and right
%  endpoints of the horizontal lines
xleft = temp; xright = temp+1;
% Increase line length by 0.2 units
Xdata(xleft) = Xdata(xleft) - .1;
Xdata(xright) = Xdata(xright) + .1;
set(hb(2),'Xdata',Xdata)

 

  2 Comments

The above code works on Matlab 2013b, but does not work with Matlab 2015b. Could anyone suggest an alternative? Thanks.

See my solution posted as an alternate answer on this page 1/25/2018. I have a method that I have validated in Matlab 2015b.

Sign in to comment.


Answer by Brandon Madsen on 25 Jan 2018

Below is a method I just found through trial and error (haha) that works for 2015b (I suspect it would also work for 2014b, 2015a, and 2016a, but I haven't tested it on these versions).

This method works by accessing a hidden primitive object type called LineStrip, whose handle is stored in a hidden property called Bar. The LineStrip object contains a property called VertexData, which stores coordinates for the endpoints (vertices) of all line segments used to draw the figure.

VertexData is a 3-by-(6*N) single-precision numeric array, where N equals the number of error bars represented by the ErrorBar object. This is because there are two vertices per line segment (start and end coordinates), and there are 3 lines that make up a single error bar (one vertical and two horizontal caps), so 2*3=6. More info:

  • The three rows contain X, Y, and Z coordinates, in that order.
  • Each column contains data for exactly one vertex.
  • The columns are organized such that (:,1:2*N) represent the vertical lines, (:,2*N+1:4*N) represent the lower cap-lines, and (:,4*N+1:end) represent the upper cap-lines.
  • Within each of these broader sections (vertical error bar, lower cap, upper cap), the column indices map in 2-to-1 fashion onto the XData / YData / ZData properties of the ErrorBar object, so that, for instance: indices (:,1:2) contain the start and end points for a line segment corresponding to the first data point; indices (:,3:4) contain start and end points for a line segment corresponding to the second data point, etc.
  • The odd-numbered columns contain coordinates for the lower-most (for the vertical lines) and left-most (for the horizontal lines) end of the line segment. Conversely, the even-numbered columns contain the upper-most and right-most coordinates.

You can then replace or alter these values as you wish to fully customize the error bars. An example implementation is shown here:

% Create errorbar to start with
X = 0:pi/10:pi;
Y = sin(X);
E = std(Y)*ones(size(X));
hErr = errorbar(X,Y,E);
% Make cap-lines twice as long
mult = 2;                               % twice as long
b = hErr.Bar;                           % hidden property/handle
drawnow                                 % populate b's properties
vd = b.VertexData;
N = numel(X);                           % number of error bars
capLength = vd(1,2*N+2,1) - vd(1,1,1);  % assumes equal length on all
newLength = capLength * mult;
leftInds = N*2+1:2:N*6;
rightInds = N*2+2:2:N*6;
vd(1,leftInds,1) = [X-newLength, X-newLength];
vd(1,rightInds,1) = [X+newLength, X+newLength];
b.VertexData = vd;

(Note: The drawnow command is superfluous if you're stepping through in debug mode or using command-line entry, but it is absolutely essential if you're running in a function or script - otherwise the properties of the LineStrip will still be empty/default when you try to access them.)

Finally, of course, you could also set mult to 0 to eliminate the caps altogether, or manually put in the length you want, or anything else.

  0 Comments

Sign in to comment.


Answer by F. G.
on 20 Oct 2015

The above code works on Matlab 2013b, but does not work with Matlab 2015b. Could anyone suggest an alternative? Thanks.

  2 Comments

Starting MATLAB R2014b, there is no way to control length of horizontal lines at ends of errorbar using the properties of the errorbar objects.

As a workaround, you can create line objects at data point as demonstrated in the following example :

% Create errorbar
X = 0:pi/10:pi;
Y = sin(X) + 1;
E = std(Y) * ones(size(X));
ha = errorbar(X, Y, E);
% Width of the top and bottom lines of errorbar
xlength = 0.1;
% Make horizontal lines with 'line'
for k = 1:length(X)
 x = [X(k) - xlength, X(k) + xlength];
 y_h = [Y(k) + E(k), Y(k) + E(k)];
 line(x, y_h);
 y_b = [Y(k) - E(k), Y(k) - E(k)];
 line(x, y_b);
end

I hope this helps!

- Abhishek

This works if you want to make them longer, but not if you want to make them shorter. See my posted answer for a solution that edits the existing ErrorBar object directly.

Sign in to comment.


Answer by Benjamin Spencer on 8 Jun 2017
Edited by Benjamin Spencer on 8 Jun 2017

What am I paying for if Matlab can't do simple functions like control the damn capsize of an error bar?

  0 Comments

Sign in to comment.