I am writing a customized errorbar
function for myself. But I do not know how to control the CapSize
, like it is controlled in the default errorbar; zooming-in or zooming-out does not enlarge the Cap. A simplified version of my code is as follow-
function myErrorbar(x, y, h)
for i = 1:length(x)
y1 = y(i)-h(i);
y2 = y(i)+h(i);
x1 = x(i)-0.1*h(i);
x2 = x(i)+0.1*h(i);
% errorbar
line([x(i), x(i)], [y1, y2]); hold on
% caps
line([x1, x2], [y1, y1])
line([x1, x2], [y2, y2])
end
In the above code I have fixed the size of caps equal to 10% of h on either sides. I want to control the capsize like it could be done in the default. The code could be tested with following code
x = 1:10:100;
y = [20 30 45 40 60 65 80 75 95 90];
err = 8*ones(size(y));
myErrorbar(x,y,err)
Like Adriaan mentioned in his comment, this can be achieved by adding a listener to the XLim
property of the axes to draw to. See the code below and comments for explanation.
The idea is to get the XLim
after drawing the vertical lines, then determine the width fraction per cap of the axes' XLim
, and use this to scale the caps accordingly when the XLim
is changed.
function myErrorbar(ax, x, y, err, color)
% color input argument handling
if ~exist('color', 'var') || isempty(color)
color = lines(1); % default lightblue color
end
% first plot the vertical lines (so XLim is set to right value)
y_bot = y - err;
y_top = y + err;
% errorbar
l = line([x; x], [y_bot; y_top], 'color', color);
hold on
% get the current XLim
x_fracs = NaN(size(x)); % variable to store fractions of XLim
cur_xlim = diff(ax.XLim); % current XLim
% plot the caps
x_left = x - 0.1 .* err;
x_right = x + 0.1 .* err;
c_top = line([x_left; x_right], [y_top; y_top], 'color', color);
c_bot = line([x_left; x_right], [y_bot; y_bot], 'color', color);
% determine width fraction of current x limit
x_fracs = (x_right - x_left) ./ cur_xlim;
% add listener for xlim
addlistener(ax, 'XLim', 'PostGet', @updateCaps);
% --------------------------------------------------------------------------
% callback to update cap width
function updateCaps(hProperty, eventData)
% update XLim
cur_xlim = diff(ax.XLim);
% determine new cap widths and positions
cap_width = x_fracs .* cur_xlim;
x_left = x - 0.5 .* cap_width;
x_right = x + 0.5 .* cap_width;
% set cap line x and y data
for k = 1:length(x)
c_top(k).XData = [x_left(k), x_right(k)];
c_bot(k).XData = [x_left(k), x_right(k)];
end
end
end