function niceaxes(varargin)
% NICEAXES Replaces the normal axes with nicer ones
%
% NICEAXES(ARG1, VAL1, ARG2, VAL2, ...) sets the properties of the new axes
% 
% Options
%    XAxis: [ {on} | off ]
%    XAxisLength: [ {normal} | tight ]
%    YAxis: [ {on} | off ]
%    YAxisLength: [ {normal} | tight ]

% Copyright 2012 Mikkel N. Schmidt, ms@it.dk, www.mikkelschmidt.dk




o = mgetopt(varargin);
XAxis = mgetopt(o, 'XAxis', 'on');
XAxisLength = mgetopt(o, 'XAxisLength', 'normal');
YAxis = mgetopt(o, 'YAxis', 'on');
YAxisLength = mgetopt(o, 'YAxisLength', 'normal');
XLabelRotation = mgetopt(o, 'XLabelRotation', 0);
YLabelRotation = mgetopt(o, 'YLabelRotation', 90);
XTickRotation = mgetopt(o, 'XTickRotation', 0);
YTickRotation = mgetopt(o, 'YTickRotation', 0);
XLabelFactor = mgetopt(o, 'XLabelFactor', 4);
YLabelFactor = mgetopt(o, 'YLabelFactor', 8);

hc = gca;
axis off;
set(gcf, 'Units', 'Centimeters');
FigurePosition = get(gcf, 'PaperPosition');
%Position = get(gca, 'Position');
Position = plotboxpos(gca);
XTick = get(hc, 'XTick');
XTickLabel = cellstr(get(hc, 'XTickLabel'));
XAxisLocation = get(hc, 'XAxisLocation');
YTick = get(hc, 'YTick');
YTickLabel = cellstr(get(hc, 'YTickLabel'));
YAxisLocation = get(hc, 'YAxisLocation');
FontSize = get(hc, 'FontSize');

ha = axes('Position',[0 0 1 1]);
axis off;
set(gcf, 'Color', 'w');
axis([0 1 0 1]);

XLim = get(hc, 'XLim');
YLim = get(hc, 'YLim');

% X-AXIS
XTickLength = 0.1/FigurePosition(4);
TickPos = (XTick-XLim(1))/(XLim(2)-XLim(1));
switch XAxisLocation
    case 'bottom'
        YPos = Position(2);
        YTickSign = -1;
        TextVerticalAlignment = 'top';                
    otherwise
        YPos = Position(2)+Position(4);
        YTickSign = 1;
        TextVerticalAlignment = 'baseline';                
end
switch XAxis
    case 'on'
        switch XAxisLength
            case 'normal'
                line(Position(1)+Position(3)*[0 1],[YPos YPos],'Color','k');
            otherwise
                line(Position(1)+Position(3)*[TickPos(1) TickPos(end)],[YPos YPos],'Color','k');
        end
        for i = 1:length(XTickLabel)
             line(Position(1)+Position(3)*[TickPos(i) TickPos(i)],[YPos YPos+YTickSign*XTickLength],'Color','k');
        end
    otherwise
end
for i = 1:length(XTickLabel)
    text(Position(1)+Position(3)*TickPos(i),YPos+1.5*YTickSign*XTickLength,XTickLabel{i}, ...
        'HorizontalAlignment', 'center', 'VerticalAlignment', TextVerticalAlignment, ...
        'FontSize', FontSize);
end

% Y-AXIS
YTickLength = 0.1/FigurePosition(3);
TickPos = (YTick-YLim(1))/(YLim(2)-YLim(1));
switch YAxisLocation
    case 'left'
        XPos = Position(1);
        XTickSign = -1;        
        TextHorizontalAlignment = 'right';
    otherwise
        XPos = Position(1)+Position(3);
        XTickSign = 1;
        TextHorizontalAlignment = 'left';
end
if YTickRotation ~= 0
    YTickExtra = XTickSign*.5*YTickLength;
    TextHorizontalAlignment = 'center'; 
else
    YTickExtra = 0;
end
switch YAxis
    case 'on'        
        switch YAxisLength
            case 'normal'
                line([XPos XPos],Position(2)+Position(4)*[0 1],'Color','k');
            otherwise
                line([XPos XPos],Position(2)+Position(4)*[TickPos(1) TickPos(end)],'Color','k');
        end
        for i = 1:length(YTickLabel)
            line([XPos XPos+XTickSign*YTickLength],Position(2)+Position(4)*[TickPos(i) TickPos(i)],'Color','k');
        end
    otherwise
end
for i = 1:length(YTickLabel)
    text(XPos+2*XTickSign*YTickLength+YTickExtra, Position(2)+Position(4)*TickPos(i), YTickLabel{i}, ...
        'HorizontalAlignment', TextHorizontalAlignment, 'VerticalAlignment', 'middle', ...
        'FontSize', FontSize, 'Rotation', YTickRotation);
end

% AXIS LABELS
XLabel = get(get(hc, 'XLabel'), 'String');
text(Position(1)+.5*Position(3), YPos+XLabelFactor*YTickSign*XTickLength, XLabel, 'Rotation', XLabelRotation, ...
    'VerticalAlignment', TextVerticalAlignment, 'HorizontalAlignment', 'center', ...
    'FontSize', FontSize, 'Clipping', 'off');
YLabel = get(get(hc, 'YLabel'), 'String');
text(XPos+YLabelFactor*XTickSign*YTickLength, Position(2)+.5*Position(4), YLabel, 'Rotation', YLabelRotation, ...
    'VerticalAlignment', 'middle', 'HorizontalAlignment', 'center', ...
    'FontSize', FontSize, 'Clipping', 'off');

set(gcf, 'CurrentAxes', hc);




function pos = plotboxpos(h)
%PLOTBOXPOS Returns the position of the plotted axis region
%
% pos = plotboxpos(h)
%
% This function returns the position of the plotted region of an axis,
% which may differ from the actual axis position, depending on the axis
% limits, data aspect ratio, and plot box aspect ratio.  The position is
% returned in the same units as the those used to define the axis itself.
% This function can only be used for a 2D plot.  
%
% Input variables:
%
%   h:      axis handle of a 2D axis (if ommitted, current axis is used).
%
% Output variables:
%
%   pos:    four-element position vector, in same units as h

% Copyright 2010 Kelly Kearney

% Check input

if nargin < 1
    h = gca;
end

if ~ishandle(h) || ~strcmp(get(h,'type'), 'axes')
    error('Input must be an axis handle');
end

% Get position of axis in pixels

currunit = get(h, 'units');
set(h, 'units', 'pixels');
axisPos = get(h, 'Position');
set(h, 'Units', currunit);

% Calculate box position based axis limits and aspect ratios

darismanual  = strcmpi(get(h, 'DataAspectRatioMode'),    'manual');
pbarismanual = strcmpi(get(h, 'PlotBoxAspectRatioMode'), 'manual');

if ~darismanual && ~pbarismanual
    
    pos = axisPos;
    
else

    dx = diff(get(h, 'XLim'));
    dy = diff(get(h, 'YLim'));
    dar = get(h, 'DataAspectRatio');
    pbar = get(h, 'PlotBoxAspectRatio');

    limDarRatio = (dx/dar(1))/(dy/dar(2));
    pbarRatio = pbar(1)/pbar(2);
    axisRatio = axisPos(3)/axisPos(4);

    if darismanual
        if limDarRatio > axisRatio
            pos(1) = axisPos(1);
            pos(3) = axisPos(3);
            pos(4) = axisPos(3)/limDarRatio;
            pos(2) = (axisPos(4) - pos(4))/2 + axisPos(2);
        else
            pos(2) = axisPos(2);
            pos(4) = axisPos(4);
            pos(3) = axisPos(4) * limDarRatio;
            pos(1) = (axisPos(3) - pos(3))/2 + axisPos(1);
        end
    elseif pbarismanual
        if pbarRatio > axisRatio
            pos(1) = axisPos(1);
            pos(3) = axisPos(3);
            pos(4) = axisPos(3)/pbarRatio;
            pos(2) = (axisPos(4) - pos(4))/2 + axisPos(2);
        else
            pos(2) = axisPos(2);
            pos(4) = axisPos(4);
            pos(3) = axisPos(4) * pbarRatio;
            pos(1) = (axisPos(3) - pos(3))/2 + axisPos(1);
        end
    end
end

% Convert plot box position to the units used by the axis

temp = axes('Units', 'Pixels', 'Position', pos, 'Visible', 'off', 'parent', get(h, 'parent'));
set(temp, 'Units', currunit);
pos = get(temp, 'position');
delete(temp);
