function hh = myErrorbar(varargin) %MYERRORBAR Adds errorbars to existing plot (unlike errorbar.m, which creates a new plot, and allows only bars for y values) % MYERRORBAR(X,Y,L,U) adds error bars to the graph of vector X vs. vector Y with % error bars specified by the vectors L and U. L and U contain the % lower and upper error ranges for each point in Y. Each error bar % is L(i) + U(i) long and is drawn a distance of U(i) above and L(i) % below the points in (X,Y). If X,Y,L and U are matrices then each column % produces a separate line. % If L,U are the same size as X, Y, only error bars for Y will be plotted. % If L,U are twice the size of X,Y (or have twice the number of columns for % matrices), the first half of L, U specifies error bar lengths for X and the % second half specifies error bars for Y % % MYERRORBAR(X,Y,E) or MYERRORBAR(Y,E) plots error bars [Y-E Y+E]. % % MYERRORBAR(AX,...), where AX is an axis handle, plots errorbars into % axes AX % % H = MYERRORBAR(...) returns a vector of line handles. % % The tag of the errorbar-lines is: errorBar % % For example, % x = 1:10; % y = sin(x); % e = std(y)*ones(size(x)); % myErrorbar(x,y,e) % draws symmetric error bars of unit standard deviation for y values. % myErrorbar(x,y,[e,e]) % draws symmetric error bars of unit standard deviation for x and y % values. % % Based on the matlab-function errorbar as revised by Claude Berney % c: jonas, 06-03 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %================== % check input %================== if nargin < 2 error('not enough input arguments!') end % check if the first input argument is a handle if length(varargin{1}) == 1 && ishandle(varargin{1}) && strcmpi(get(varargin{1},'Type'),'axes') axesH = varargin{1}; % remove axis handle varargin(1) = []; else axesH = gca; end % there could be % y,e % x,y,e % x,y,l,u switch length(varargin) case 2 % y, e y = varargin{1}; y = y(:); lengthY = length(y); x = [1:lengthY]'; e = varargin{2}; % check for 2 dimension errorbars e = e(:); if length(e) == 2*lengthY e = reshape(e,lengthY,2); end [l,u] = deal(e); case 3 % x,y,e x = varargin{1}; x = x(:); y = varargin{2}; y = y(:); lengthY = length(y); e = varargin{3}; % check for 2 dimension errorbars e = e(:); if length(e) == 2*lengthY e = reshape(e,lengthY,2); end [l,u] = deal(e); case 4 % x,y,l,u % x,y,e x = varargin{1}; x = x(:); y = varargin{2}; y = y(:); lengthY = length(y); l = varargin{3}; % check for 2 dimension errorbars l = l(:); if length(l) == 2*lengthY l = reshape(l,lengthY,2); end u = varargin{4}; % check for 2 dimension errorbars u = u(:); if length(u) == 2*lengthY u = reshape(u,lengthY,2); end if ~all(size(u)==size(l)) error('l, u have to be the same size!') end end % switch number of inputs u = abs(u); l = abs(l); if ischar(x) || ischar(y) || ischar(u) || ischar(l) error('Arguments must be numeric.') end if ~isequal(size(x),size(y)) error('The sizes of X and Y must be the same.'); end if isequal([1 2].*size(x),size(l)) && isequal([1 2].*size(x),size(u)) xyBars = 1; elseif isequal(size(x),size(l)) && isequal(size(x),size(u)) xyBars = 0; else error('The sizes of L and U must be equal to or twice the size of X, Y') end %======================= % Plot graph and bars hold_state = ishold; hold on; %find color of current plot dataH = get(axesH,'Children'); myLineH = dataH(1); % support also bar plots if strcmp(get(myLineH,'Type'),'hggroup') latestColor = get(myLineH,'EdgeColor'); %new children are added on top! else latestColor = get(myLineH,'Color'); %new children are added on top! end tee=0; if ~strcmp('log',get(axesH,'XScale')) tee = (max(x(:))-min(x(:)))/100; % make tee .02 x-distance for error bars tee = min(tee,0.3*nanmedian(diff(unique(x(:))))); % or at most 0.3*deltaX xl = x - tee; xr = x + tee; end if strcmp('log',get(axesH,'XScale')) tee = (max(log(x(:)))-min(log(x(:))))/100; % make tee .02 x-distance for error bars tee = min(tee,0.3*nanmedian(diff(unique(log(x(:)))))); % or at most 0.3*deltaX xl = x *exp(tee); xr = x *exp(-tee); end if xyBars if ~strcmp('log',get(axesH,'YScale')) tee = (max(y(:))-min(y(:)))/100; % make tee .02 y-distance for error bars tee = min(tee,0.3*nanmedian(diff(unique(y(:))))); % or at most 0.3*deltaY yl = y - tee; yr = y + tee; end if strcmp('log',get(axesH,'YScale')) tee = (max(log(y(:)))-min(log(y(:))))/100; % make tee .02 y-distance for error bars tee = min(tee,0.3*nanmedian(diff(unique(log(y(:)))))); % or at most 0.3*deltaX yl = y *exp(tee); yr = y *exp(-tee); end end %specify coordinates to plot error bars if xyBars xtop = x + u(:,1:size(x,2)); xbot = x - l(:,1:size(x,2)); ytop = y + u(:,size(x,2)+1:end); ybot = y - l(:,size(x,2)+1:end); else ytop = y + u; ybot = y - l; end n = size(y,2); % build up nan-separated vector for bars xb = zeros(lengthY*9,n); xb(1:9:end,:) = x; xb(2:9:end,:) = x; xb(3:9:end,:) = NaN; xb(4:9:end,:) = xl; xb(5:9:end,:) = xr; xb(6:9:end,:) = NaN; xb(7:9:end,:) = xl; xb(8:9:end,:) = xr; xb(9:9:end,:) = NaN; yb = zeros(lengthY*9,n); yb(1:9:end,:) = ytop; yb(2:9:end,:) = ybot; yb(3:9:end,:) = NaN; yb(4:9:end,:) = ytop; yb(5:9:end,:) = ytop; yb(6:9:end,:) = NaN; yb(7:9:end,:) = ybot; yb(8:9:end,:) = ybot; yb(9:9:end,:) = NaN; h = [line(xb,yb,'parent',axesH,'Color',latestColor)]; if xyBars xb(1:9:end,:) = xtop; xb(2:9:end,:) = xbot; xb(3:9:end,:) = NaN; xb(4:9:end,:) = xtop; xb(5:9:end,:) = xtop; xb(6:9:end,:) = NaN; xb(7:9:end,:) = xbot; xb(8:9:end,:) = xbot; xb(9:9:end,:) = NaN; yb(1:9:end,:) = y; yb(2:9:end,:) = y; yb(3:9:end,:) = NaN; yb(4:9:end,:) = yl; yb(5:9:end,:) = yr; yb(6:9:end,:) = NaN; yb(7:9:end,:) = yl; yb(8:9:end,:) = yr; yb(9:9:end,:) = NaN; h = [h;line(xb,yb,'parent',axesH,'Color',latestColor)]; end %set the tag of all errorBar-objects to 'errorBar' set(h,'Tag','errorBar'); % make sure errorbar doesn't produce a legend entry for lineH = h' set(get(get(lineH,'Annotation'),'LegendInformation'),... 'IconDisplayStyle','off'); end if ~hold_state, hold off; end if nargout>0, hh = h; end