Code covered by the BSD License  

Highlights from
Violin Plots for plotting multiple distributions (distributionPlot.m)

image thumbnail

Violin Plots for plotting multiple distributions (distributionPlot.m)

by

 

13 Apr 2009 (Updated )

Function for plotting multiple histograms side-by-side in 2D - better than boxplot.

Editor's Notes:

This file was selected as MATLAB Central Pick of the Week

myErrorbar(varargin)
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

Contact us