% =========================================================================
% *** FUNCTION ACID
% ***
% *** MATLAB2TikZ ACID test functions
% ***
% =========================================================================
function [status] = ACID(k)

  % assign the functions to test
  testfunction_handles = {                        ...
                           @multiline_labels    , ...
                           @plain_cos           , ...
                           @sine_with_markers   , ...
                           @markerSizes         , ...
                           @markerSizes2        , ...
                           @sine_with_annotation, ...
                           @linesWithOutliers   , ...
                           @peaks_contour       , ...
                           @contourPenny        , ...
                           @peaks_contourf      , ...
                           @many_random_points  , ...
                           @double_colorbar     , ...
                           @randomWithLines     , ...
                           @double_axes         , ...
                           @double_axes2        , ...
                           @logplot             , ...
                           @colorbarLogplot     , ...
                           @legendplot          , ...
                           @legendplotBoxoff    , ...
                           @plotyyLegends         , ...
                           @zoom                , ...
                           @quiveroverlap       , ...
                           @quiverplot          , ...
                           @quiver3plot         , ...
                           @logicalImage        , ...
                           @imagescplot         , ...
                           @imagescplot2        , ...
                           @stairsplot          , ...
                           @polarplot           , ...
                           @roseplot            , ...
                           @compassplot         , ...
                           @stemplot            , ...
                           @stemplot2           , ...
                           @bars                , ...
                           @xAxisReversed       , ...
                           @errorBars           , ...
                           @errorBars2          , ...
                           @subplot2x2b         , ...
                           @manualAlignment     , ...
                           @subplotCustom       , ...
                           @legendsubplots      , ...
                           @bodeplots           , ...
                           @rlocusPlot          , ...
                           @mandrillImage       , ...
                           @besselImage         , ...
                           @clownImage          , ...
                           @zplanePlot1         , ...
                           @zplanePlot2         , ...
                           @freqResponsePlot    , ...
                           @axesLocation        , ...
                           @axesColors          , ...
                           @multipleAxes        , ...
                           @scatterPlotRandom   , ...
                           @scatterPlot         , ...
                           @scatter3Plot        , ...
                           @spherePlot          , ...
                           @surfPlot            , ...
                           @surfPlot2           , ...
                           @superkohle          , ...
                           @meshPlot            , ...
                           @ylabels             , ...
                           @spectro             , ... % takes pretty long to LuaLaTeX-compile
                           @mixedBarLine        , ...
                           @decayingharmonic    , ...
                           @texcolor            , ...
                           @textext             , ...
                           @texrandom           , ...
                           @latexInterpreter    , ...
                           @latexmath2          , ...
                           @parameterCurve3d    , ...
                           @parameterSurf       , ...
                           @fill3plot           , ...
                           @rectanglePlot       , ...
                           @herrorbarPlot       , ...
                           @hist3d              , ...
                           @myBoxplot           , ...
                           @areaPlot            , ...
                           @customLegend        , ...
                           @pixelLegend         , ...
                           @croppedImage        , ...
                           @pColorPlot          , ...
                           @hgTransformPlot     , ...
                           @scatterPlotMarkers  , ...
                           @multiplePatches     , ...
                           @logbaseline         , ...
                           @alphaImage          , ...
                           @annotationAll       , ...
                           @annotationSubplots  , ...
                           @annotationText      , ...
                           @annotationTextUnits , ...
                           @imageOrientation_PNG, ...
                           @imageOrientation_inline, ...
                           @texInterpreter      , ...
                           @stackedBarsWithOther, ...
                           @colorbarLabelTitle  , ...
                           @textAlignment       , ...
                           @overlappingPlots    , ...
                           @histogramPlot       , ...
                           @alphaTest           , ...
                           @removeOutsideMarker , ...
                           @colorbars           , ...
                           @colorbarManualLocationRightOut , ...
                           @colorbarManualLocationRightIn  , ...
                           @colorbarManualLocationLeftOut  , ...
                           @colorbarManualLocationLeftIn
                         };

  numFunctions = length( testfunction_handles );

  if (k<=0)
      status = testfunction_handles;
      return;  % This is used for querying numFunctions.

  elseif (k<=numFunctions)
      status = testfunction_handles{k}();
      status.function = func2str(testfunction_handles{k});

  else
      error('testfunctions:outOfBounds', ...
            'Out of bounds (number of testfunctions=%d)', numFunctions);
  end

end
% =========================================================================
function data = ACID_data()
  % Data to be used for various ACID tests
  % This ensures the tests don't rely on functions that yield
  % non-deterministic output, e.g. `rand` and `svd`.
  data = [    11    11     9
               7    13    11
              14    17    20
              11    13     9
              43    51    69
              38    46    76
              61   132   186
              75   135   180
              38    88   115
              28    36    55
              12    12    14
              18    27    30
              18    19    29
              17    15    18
              19    36    48
              32    47    10
              42    65    92
              57    66   151
              44    55    90
             114   145   257
              35    58    68
              11    12    15
              13     9    15
              10     9     7];
end
% =========================================================================
function [stat] = multiline_labels()
  stat.description = 'Test multiline labels and plot some points.';
  stat.unreliable = isOctave || isMATLAB(); %FIXME: `width` is inconsistent, see #552

  m = [0 1 1.5 1 -1];
  plot(m,'*-'); hold on;
  plot(m(end:-1:1)-0.5,'x--');

  title({'multline','title'});
  legend({sprintf('multi-line legends\ndo work 2^2=4'), ...
        sprintf('second\nplot')});
  xlabel(sprintf('one\ntwo\nthree'));
  ylabel({'one','° ∞', 'three'});

  set(gca,'YTick', []);
  set(gca,'XTickLabel',{});
end
% =========================================================================
function [stat] = plain_cos()
  stat.description = 'Plain cosine function.';

  t = linspace(0, 2*pi, 1e5);
  x = cos(t);

  % Explicitely cut the line into segments
  x([2e4, 5e4, 8e4]) = NaN;

  % Plot the cosine
  plot(t, x);
  xlim([0, 2*pi]);

  % also add some patches to test their border color reproduction
  hold on;
  h(1) = fill(pi*[1/4 1/4 1/2 1/2]   ,  [-2 1 1 -2], 'y');
  h(2) = fill(pi*[1/4 1/4 1/2 1/2]+pi, -[-2 1 1 -2], 'y');

  set(h(1), 'EdgeColor', 'none', 'FaceColor', 0.8*[1 1 1]);
  set(h(2), 'EdgeColor', 'k', 'FaceColor', 0.5*[1 1 1]);

  if isMATLAB
      uistack(h, 'bottom'); % patches below the line plot
      % this is not supported in Octave
  end

  % add some minor ticks
  set(gca, 'XMinorTick', 'on');
  set(gca, 'YTick', []);

  % Adjust the aspect ratio when in MATLAB(R) or Octave >= 3.4.
  if isOctave('<=', [3,4])
      % Octave < 3.4 doesn't have daspect unfortunately.
  else
      daspect([ 1 2 1 ])
  end
end
% =========================================================================
function [stat] = sine_with_markers ()
  % Standard example plot from MATLAB's help pages.
  stat.description = [ 'Twisted plot of the sine function. '                   ,...
         'Pay particular attention to how markers and Infs/NaNs are treated.' ];

  x = -pi:pi/10:pi;
  y = sin(x);
  y(3) = NaN;
  y(7) = Inf;
  y(11) = -Inf;
  plot(x,y,'--o', 'Color', [0.6,0.2,0.0], ...
                  'LineWidth', 1*360/127,...
                  'MarkerEdgeColor','k',...
                  'MarkerFaceColor',[0.3,0.1,0.0],...
                  'MarkerSize', 5*360/127 );

  set( gca, 'Color', [0.9 0.9 1], ...
            'XTickLabel', [], ...
            'YTickLabel', [] ...
     );

  set(gca,'XTick',[0]);
  set(gca,'XTickLabel',{'null'});
end
% =========================================================================
function [stat] = markerSizes()
  stat.description = 'Marker sizes.';

  hold on;

  h = fill([1 1 2 2],[1 2 2 1],'r');
  set(h,'LineWidth',10);

  plot([0],[0],'go','Markersize',14,'LineWidth',10)
  plot([0],[0],'bo','Markersize',14,'LineWidth',1)
end
% =========================================================================
function [stat] = markerSizes2()
  stat.description = 'Line plot with with different marker sizes.';

  hold on;
  grid on;

  n = 1:10;
  d = 10;
  s = round(linspace(6,25,10));
  e = d * ones(size(n));
  style = {'bx','rd','go','c.','m+','y*','bs','mv','k^','r<','g>','cp','bh'};
  nStyles = numel(style);

  for ii = 1:nStyles
      for jj = 1:10
        plot(n(jj), ii * e(jj),style{ii},'MarkerSize',s(jj));
      end
  end
  xlim([min(n)-1 max(n)+1]);
  ylim([0 d*(nStyles+1)]);
  set(gca,'XTick',n,'XTickLabel',s,'XTickLabelMode','manual');
end
% =========================================================================
function [stat] = sine_with_annotation ()
  stat.description = [ 'Plot of the sine function. ',...
        'Pay particular attention to how titles and annotations are treated.' ];
  stat.unreliable = isOctave || isMATLAB('>=',[8,4]) ... %FIXME: investigate
                    || isMATLAB('<=', [8,3]); %FIXME: broken since decd496 (mac vs linux)

  x = -pi:.1:pi; %TODO: the 0.1 step is probably a bad idea (not representable in float)
  y = sin(x);
  h = plot(x,y);
  set(gca,'XTick',-pi:pi/2:pi);

  set(gca,'XTickLabel',{'-pi','-pi/2','0','pi/2','pi'});

  xlabel('-\pi \leq \Theta \leq \pi');
  ylabel('sin(\Theta)');
  title({'Plot of sin(\Theta)','subtitle','and here''s one really long subtitle' });
  text(-pi/4,sin(-pi/4),'\leftarrow sin(-\pi\div4)',...
      'HorizontalAlignment','left');

  % Doesn't work in Octave
  %set(findobj(gca,'Type','line','Color',[0 0 1]),...
  %    'Color','red',...
  %    'LineWidth',10);

end
% =========================================================================
function [stat] = linesWithOutliers()
    stat.description = 'Lines with outliers.';
    stat.issues = [392,400];

    far = 200;
    x = [ -far, -1,   -1,  -far, -10, -0.5, 0.5, 10,  far, 1,   1,    far, 10,   0.5, -0.5, -10,  -far ];
    y = [ -10,  -0.5, 0.5, 10,   far, 1,    1,   far, 10,  0.5, -0.5, -10, -far, -1,  -1,   -far, -0.5 ];
    plot( x, y,'o-');
    axis( [-2,2,-2,2] );
end
% =========================================================================
function [stat] = peaks_contour()
  stat.description = 'Test contour plots.';
  stat.unreliable = isMATLAB('<', [8,4]) || isOctave; %R2014a and older
  % FIXME: see #604; contour() produces inconsistent output

  subplot(121)
  [C, h] = contour(peaks(20),10);
  clabel(C, h);

  % remove y-ticks
  set(gca,'YTickLabel',[]);
  set(gca,'YTick',[]);

  colormap winter;

  % Contour layers with predefined color
  subplot(122)
  contour(peaks(20), 10,'r', 'LineWidth', 5)
  set(gca,'YTickLabel',[]);
  set(gca,'YTick',[]);
end
% =========================================================================
function [stat] = contourPenny()
  stat.description = 'Contour plot of a US\$ Penny.';
  stat.unreliable  = isMATLAB('<', [8,4]);
  % FIXME: see #604; contour() produces inconsistent output (mac/windows of PeterPablo)
  stat.issues = [49 404];

  if ~exist('penny.mat','file')
      fprintf( 'penny data set not found. Skipping.\n\n' );
      stat.skip = true;
      return;
  end

  load penny;
  contour(flipud(P));
  axis square;

end
% =========================================================================
function [stat] = peaks_contourf ()
  stat.description = 'Test the contourfill plots.';
  stat.unreliable = isMATLAB('>=', [8,4]); % FIXME: inspect this
  stat.issues = 582;

  [trash, h] = contourf(peaks(20), 10);
  hold on
  plot(1:20)
  colorbar();
  legend(h, 'Contour');
  colormap hsv;
end
% =========================================================================
function [stat] = double_colorbar()
  stat.description = 'Double colorbar.';

  if isOctave()
      fprintf( 'Octave can''t handle tight axes.\n\n' );
      stat.skip = true;
      return
  end

  vspace = linspace(-40,40,20);
  speed_map = magic(20).';
  Q1_map = magic(20);

  subplot(1, 2, 1);
  contour(vspace(9:17),vspace(9:17),speed_map(9:17,9:17),20)
  colorbar
  axis tight
  axis square
  xlabel('$v_{2d}$')
  ylabel('$v_{2q}$')

  subplot(1, 2, 2)
  contour(vspace(9:17),vspace(9:17),Q1_map(9:17,9:17),20)
  colorbar
  axis tight
  axis square
  xlabel('$v_{2d}$')
  ylabel('$v_{2q}$')
end
% =========================================================================
function [stat] = randomWithLines()
  stat.description = 'Lissajous points with lines.';

  beta = 42.42;
  t = 1:150;
  X = [sin(t); cos(beta * t)].';

  X(:,1) = (X(:,1) * 90) + 75;
  plot(X(:,1),X(:,2),'o');
  hold on;
  M(1)=min(X(:,1));
  M(2)=max(X(:,1));
  mn = mean(X(:,2));
  s  = std(X(:,2));
  plot(M,[mean(X(:,2)) mean(X(:,2))],'k-');
  plot(M,mn + 1*[s s],'--');
  plot(M,mn - 2*[s s],'--');
  axis('tight');
end
% =========================================================================
function [stat] = many_random_points ()
  stat.description = 'Test the performance when drawing many points.';

  n = 1e3;
  alpha = 1024;
  beta = 1;
  gamma = 5.47;

  x = cos( (1:n) * alpha );
  y = sin( (1:n) * beta + gamma);

  plot ( x, y, '.r' );
  axis([ 0, 1, 0, 1 ])
end
% =========================================================================
function [stat] = double_axes()
  stat.description = 'Double axes';

  dyb = 0.1;   % normalized units, bottom offset
  dyt = 0.1;   % separation between subsequent axes bottoms

  x = [0; 24; 48; 72; 96;];
  y = [7.653 7.473 7.637 7.652 7.651];

  grid on
  h1 = plot(x,y,'Color','k');

  % following code is taken from `floatAxisX.m'

  % get position of axes
  allAxes = findobj(gcf,'type','axes');
  naxes = length(allAxes);
  ax1Pos = get(allAxes(naxes),'position');

  % rescale and reposition all axes to handle additional axes
  for an=1:naxes-1
     if isequal(rem(an,2),0)
        % even ones in array of axes handles represent axes on which lines are plotted
        set(allAxes(an),'Position',[ax1Pos(1,1) ax1Pos(1,2)+dyb ax1Pos(1,3) ax1Pos(1,4)-dyt])
     else
        % odd ones in array of axes handles represent axes on which floating x-axss exist
        axPos = get(allAxes(an),'Position');
        set(allAxes(an),'Position',[axPos(1,1) axPos(1,2)+dyb axPos(1,3) axPos(1,4)])
     end
  end
  % first axis a special case (doesn't fall into even/odd scenario of figure children)
  set(allAxes(naxes),'Position',[ax1Pos(1,1) ax1Pos(1,2)+dyb ax1Pos(1,3) ax1Pos(1,4)-dyt])
  ylimit1 = get(allAxes(naxes),'Ylim');

  % get new position for plotting area of figure
  ax1Pos = get(allAxes(naxes),'position');

  % axis to which the floating axes will be referenced
  ref_axis = allAxes(1);
  refPosition = get(ref_axis,'position');

  % overlay new axes on the existing one
  ax2 = axes('Position',ax1Pos);
  % plot data and return handle for the line
  hl1 = plot(x,y,'k');
  % make the new axes invisible, leaving only the line visible
  set(ax2,'visible','off','ylim',ylimit1)

  % set the axis limit mode so that it does not change if the
  % user resizes the figure window
  set(ax2,'xLimMode','manual')

  % set up another set of axes to act as floater
  ax3 = axes('Position',[refPosition(1) refPosition(2)-dyb refPosition(3) 0.01]);

  set(ax3,'box','off','ycolor','w','yticklabel',[],'ytick',[])
  set(ax3,'XMinorTick','on','color','none','xcolor',get(hl1,'color'))

  xlabel('secondary axis')
end
% =========================================================================
function [stat] = double_axes2()
  stat.description = 'Double overlayed axes with a flip.' ;

  ah1=axes;
  ph=plot([0 1],[0 1]);

  title('Title')
  ylabel('y')
  xlabel('x')

  % add a new set of axes
  % to make a gray grid
  ah2=axes;
  % make the background transparent
  set(ah1,'color','none')
  % move these axes to the back
  set(gcf,'Children',flipud(get(gcf,'Children')))
end
% =========================================================================
function [stat] = logplot()
  stat.description = 'Test logscaled axes.';
  % This was once unreliable (and linked to #590). Mac and Linux seem fine.

  x = logspace(-1,2);
  y = exp(x);
  loglog(x, y, '-s')

  ylim([1 1e45]);
  grid on;
  if isprop(gca,'GridColor')
      set(gca, 'GridColor', 'red');
      set(gca, 'MinorGridColor', 'blue');
  else
    %TODO equivalent HG1 settings (if those exist)
  end
end
% =========================================================================
function [stat] = colorbarLogplot()
  stat.description = 'Logscaled colorbar.';
  stat.unreliable = isOctave; % FIXME: investigate (Travis differs from Linux/Mac octave)
  % https://github.com/matlab2tikz/matlab2tikz/pull/641#issuecomment-120481564

  imagesc([1 10 100]);
  try
    set(colorbar(), 'YScale', 'log');
  catch
    warning('M2TAcid:LogColorBar',...
        'Logarithmic Colorbars are not documented in MATLAB R2014b and Octave');
    stat.skip = true;
  end
end
% =========================================================================
function [stat] = legendplot()
  stat.description = 'Test inserting of legends.';
  stat.unreliable = isMATLAB || isOctave; % FIXME: investigate

%    x = -pi:pi/20:pi;
%    plot(x,cos(x),'-ro',x,sin(x),'-.b');
%    h = legend('one pretty long legend cos_x','sin_x',2);
%    set(h,'Interpreter','none');

  x = linspace(0, 2*pi, 1e5);
  plot( x, sin(x), 'b', ...
        x, cos(x), 'r' );
  xlim( [0 2*pi] )
  ylim( [-0.9 0.9] )
  title( '{tikz test}' )
  xlabel( '{x-Values}' )
  ylabel( '{y-Values}' )
  legend( 'sin(x)', 'cos(x)', 'Location','NorthOutside', ...
                              'Orientation', 'Horizontal' );
  grid on;
end
% =========================================================================
function [stat] = legendplotBoxoff ()
  stat.description = 'Test inserting of legends.';
  stat.issues = [607,609];

  x = -pi:pi/20:pi;
  l = plot(x, cos(x),'-ro',...
           x, sin(x),'-.b');
  h = legend(l(2), 'one pretty long legend sin_x (dash-dot)', 'Location', 'northeast');
  set(h, 'Interpreter', 'none');
  legend boxoff
end
% =========================================================================
function [stat] = plotyyLegends()
  stat.description = 'More legends.';

  x = 0:.1:7;
  y1 = sin(x);
  y2 = cos(x);
  [ax,h1,h2] = plotyy(x,y1,x,y2);
  legend([h1;h2],'Sine','Cosine');
end
% =========================================================================
function [stat] = zoom()
    stat.description = ['Test function \texttt{pruneOutsideBox()} ', ...
                        'and \texttt{movePointsCloser()} ', ...
                        'of \texttt{cleanfigure()}.'];
    stat.unreliable = isOctave; %FIXME: investigate
    stat.issues = [226,392,400];

    % Setup
    subplot(311)
    plot(1:10,10:-1:1,'-r*',1:15,repmat(9,1,15),'-g*',[5.5,5.5],[1,9],'-b*')
    hold on;
    stairs(1:10,'-m*');
    plot([2,8.5,8.5,2,2],[2,2,7.5,7.5,2],'--k');
    title('setup');
    legend('cross with points','no cross','cross no points','stairs','zoom area');

    % Last comes before simple zoomin due to cleanfigure
    subplot(313)
    plot(1:10,10:-1:1,'-r*',1:10,repmat(9,1,10),'-g*',[5.5,5.5],[1,9],'-b*');
    hold on;
    stairs(1:10,'-m*');
    xlim([2, 8.5]), ylim([2,7.5]);
    cleanfigure(); % FIXME: this generates many "division by zero" in Octave
    plot([2,8.5,8.5,2,2],[2,2,7.5,7.5,2],'--k');
    xlim([0, 15]), ylim([0,10]);
    title('zoom in, cleanfigure, zoom out');

    % Simple zoom in
    subplot(312)
    plot(1:10,10:-1:1,'-r*',1:10,repmat(9,1,10),'-g*',[5.5,5.5],[1,9],'-b*');
    hold on;
    stairs(1:10,'-m*');
    xlim([2, 8.5]), ylim([2,7.5]);
    title('zoom in');
end
% =========================================================================
function [stat] = bars()
  stat.description = '2x2 Subplot with different bars';
  stat.unreliable = isOctave || isMATLAB('>=', [8,4]) || ... % FIXME: investigate
                    isMATLAB('<=', [8,3]); %FIXME: #749 (Jenkins)

  % dataset grouped
  bins = 10 * (-0.5:0.1:0.5);
  numEntries = length(bins);

  alpha = [13 11 7];
  numBars = numel(alpha);
  plotData   = zeros(numEntries, numBars);
  for iBar = 1:numBars
      plotData(:,iBar) = abs(round(100*sin(alpha(iBar)*(1:numEntries))));
  end

  % dataset stacked
  data = ACID_data;
  Y = round(abs(data(2:6,1:3))/10);

  subplot(2,2,1);
  b1 = bar(bins,plotData,'grouped','BarWidth',1.5);
  set(gca,'XLim',[1.25*min(bins) 1.25*max(bins)]);

  subplot(2,2,2);
  barh(bins, plotData, 'grouped', 'BarWidth', 1.3);

  subplot(2,2,3);
  bar(Y, 'stacked');

  subplot(2,2,4);
  b2= barh(Y,'stacked','BarWidth', 0.75);

  set(b1(1),'FaceColor','m','EdgeColor','none')
  set(b2(1),'FaceColor','c','EdgeColor','none')

end
% =========================================================================
function [stat] = stemplot()
  stat.description = 'A simple stem plot.' ;

  x = 0:25;
  y = [exp(-.07*x).*cos(x);
       exp(.05*x).*cos(x)]';
  h = stem(x, y);
  legend( 'exp(-.07x)*cos(x)', 'exp(.05*x)*cos(x)', 'Location', 'NorthWest');
  set(h(1),'MarkerFaceColor','blue');
  set(h(2),'MarkerFaceColor','red','Marker','square');

  % Octave 4 has some smart behavior: it only prints a single baseline.
  % Let's mimick this behavior everywhere else.
  baselines = findall(gca, 'Type', 'line', 'Color', [0 0 0]);
  if numel(baselines) > 1
      % We only need the last line in Octave 3.8, as that is where
      % Octave 4.0 places the baseline
      delete(baselines(1:end-1));
  end
end
% =========================================================================
function [stat] = stemplot2()
  stat.description = 'Another simple stem plot.';
  stat.unreliable = isOctave('>=', 4); %FIXME: see #759, #757/#759 and #687

  x = 0:25;
  y = [exp(-.07*x).*cos(x);
       exp(.05*x).*cos(x)]';
  h = stem(x, y, 'filled');
  legend( 'exp(-.07x)*cos(x)', 'exp(.05*x)*cos(x)', 'Location', 'NorthWest');
end
% =========================================================================
function [stat] = stairsplot()
  stat.description = 'A simple stairs plot.' ;

  X      = linspace(-2*pi,2*pi,40)';
  Yconst = [zeros(10,1); 0.5*ones(20,1);-0.5*ones(10,1)];
  Y      = [sin(X), 0.2*cos(X), Yconst];
  h = stairs(Y);
  legend(h(2),'second entry')
end
% =========================================================================
function [stat] = quiverplot()
  stat.description = 'A combined quiver/contour plot of $x\exp(-x^2-y^2)$.' ;
  stat.extraOptions = {'arrowHeadSize', 2};

  [X,Y] = meshgrid(-2:.2:2);
  Z = X.*exp(-X.^2 - Y.^2);
  [DX,DY] = gradient(Z,.2,.2);
  contour(X,Y,Z);
  hold on
  quiver(X,Y,DX,DY);
  %TODO: also show a `quiver(X,Y,DX,DY,0);` to test without scaling
  colormap hsv;
  hold off
end
% =========================================================================
function [stat] = quiver3plot()
  stat.description = 'Three-dimensional quiver plot.' ;
  stat.unreliable = isMATLAB(); %FIXME: #590

  vz = 10;            % Velocity
  a = -32;            % Acceleration

  t = 0:.1:1;
  z = vz*t + 1/2*a*t.^2;

  vx = 2;
  x = vx*t;
  vy = 3;
  y = vy*t;

  u = gradient(x);
  v = gradient(y);
  w = gradient(z);
  scale = 0;
  quiver3(x,y,z,u,v,w,scale)
  view([70 18])
end
% =========================================================================
function [stat] = quiveroverlap ()
  stat.description = 'Quiver plot with avoided overlap.';
  stat.issues = [679];
  % TODO: As indicated in #679, the native quiver scaling algorithm still isn't
  % perfect. As such, in MATLAB the arrow heads may appear extremely tiny.
  % In Octave, they look fine though. Once the scaling has been done decently,
  % this reminder can be removed.
  if isOctave
    stat.extraOptions = {'arrowHeadSize', 20};
  end

  x = [0 1];
  y = [0 0];
  u = [1 -1];
  v = [1 1];

  hold all;
  qvr1 = quiver(x,y,u,v);
  qvr2 = quiver(x,y,2*u,2*v);
  set(qvr2, 'MaxHeadSize', get(qvr1, 'MaxHeadSize')/2);
end
% =========================================================================
function [stat] = polarplot ()
  stat.description = 'A simple polar plot.' ;
  stat.extraOptions = {'showHiddenStrings',true};
  stat.unreliable = isOctave('>=', 4) || ... %FIXME: see #759, #757/#759 and #687
                    isMATLAB('<=', [8,3]); %FIXME: broken since decd496 (mac vs linux)
  t = 0:.01:2*pi;
  polar(t,sin(2*t).*cos(2*t),'--r')
end
% =========================================================================
function [stat] = roseplot ()
  stat.description = 'A simple rose plot.' ;
  stat.extraOptions = {'showHiddenStrings',true};
  stat.unreliable = isOctave('>=', 4) || ... %FIXME: see #759, #757/#759 and #687
                    isMATLAB('<=', [8,3]); %FIXME: broken since decd496 (mac vs linux)

  theta = 2*pi*sin(linspace(0,8,100));
  rose(theta);
end
% =========================================================================
function [stat] = compassplot ()
  stat.description = 'A simple compass plot.' ;
  stat.extraOptions = {'showHiddenStrings',true};
  stat.unreliable = isOctave('>=', 4) || ... %FIXME: see #759, #757/#759 and #687
                    isMATLAB('<=', [8,3]); %FIXME: broken since decd496 (mac vs linux)

  Z = (1:20).*exp(1i*2*pi*cos(1:20));
  compass(Z);
end
% =========================================================================
function [stat] = logicalImage()
  stat.description = 'An image plot of logical matrix values.' ;
  stat.unreliable = isOctave; %FIXME: investigate
  % different `width`, see issue #552# (comment 76918634); (Travis differs from Linux/Mac octave)

  plotData = magic(10);
  imagesc(plotData > mean(plotData(:)));
  colormap('hot');
end
% =========================================================================
function [stat] = imagescplot()
  stat.description = 'An imagesc plot of $\sin(x)\cos(y)$.';
  stat.unreliable = isOctave; %FIXME: investigate (Travis differs from Linux/Mac octave)

  pointsX = 10;
  pointsY = 20;
  x = 0:1/pointsX:1;
  y = 0:1/pointsY:1;
  z = sin(x)'*cos(y);
  imagesc(x,y,z);
end
% =========================================================================
function [stat] = imagescplot2()
  stat.description = 'A trimmed imagesc plot.';
  stat.unreliable = isOctave; %FIXME: investigate (Travis differs from Linux/Mac octave)

  a=magic(10);
  x=-5:1:4;
  y=10:19;
  imagesc(x,y,a)

  xlim([-3,2])
  ylim([12,15])

  grid on;
end
% =========================================================================
function [stat] = xAxisReversed ()
  stat.description = 'Reversed axes with legend.' ;

  n = 100;
  x = (0:1/n:1);
  y = exp(x);
  plot(x,y);
  set(gca,'XDir','reverse');
  set(gca,'YDir','reverse');
  if isOctave('<=', [3,8])
      % TODO: see whether we can unify this syntax for all environments
      % at the moment, the generic syntax doesn't seem to work for Octave
      % 3.8 (it doesn't even show a legend in gnuplut).
      legend( 'data1', 'Location', 'SouthWest' );
  else
      legend( 'Location', 'SouthWest' );
  end
end
% =========================================================================
function [stat] = subplot2x2b ()
  stat.description = 'Three aligned subplots on a $2\times 2$ subplot grid.' ;
  stat.unreliable = isOctave || isMATLAB();
  % FIXME: this test is unreliable because the automatic axis limits
  % differ on different test platforms. Reckon this by creating the figure
  % using `ACID(97)` and then manually slightly modify the window size.
  % We should not set the axis limits explicitly rather find a better way.
  % #591

  x = (1:5);

  subplot(2,2,1);
  y = sin(x.^3);
  plot(x,y);

  subplot(2,2,2);
  y = cos(x.^3);
  plot(x,y);

  subplot(2,2,3:4);
  y = tan(x);
  plot(x,y);
end
% =========================================================================
function [stat] = manualAlignment()
  stat.description = 'Manually aligned figures.';

  xrange = linspace(-3,4,2*1024);

  axes('Position', [0.1 0.1 0.85 0.15]);
  plot(xrange);
  ylabel('$n$');
  xlabel('$x$');

  axes('Position', [0.1 0.25 0.85 0.6]);
  plot(xrange);
  set(gca,'XTick',[]);
end
% =========================================================================
function [stat] = subplotCustom ()
  stat.description = 'Three customized aligned subplots.';
  stat.unreliable = isMATLAB(); % FIXME: #590

  x = (1:5);

  y = cos(sqrt(x));
  subplot( 'Position', [0.05 0.1 0.3 0.3] )
  plot(x,y);

  y = sin(sqrt(x));
  subplot( 'Position', [0.35 0.5 0.3 0.3] )
  plot(x,y);

  y = tan(sqrt(x));
  subplot( 'Position', [0.65 0.1 0.3 0.3] )
  plot(x,y);
end
% =========================================================================
function [stat] = errorBars()
  stat.description = 'Generic error bar plot.';

  data = ACID_data;
  plotData = 1:10;

  eH = abs(data(1:10,1))/10;
  eL = abs(data(1:10,3))/50;

  x = 1:10;
  hold all;
  errorbar(x, plotData, eL, eH, '.')
  h = errorbar(x+0.5, plotData, eL, eH);
  set(h, 'LineStyle', 'none');
  % Octave 3.8 doesn't support passing extra options to |errorbar|, but
  % it does allow for changing it after the fact
end
% =========================================================================
function [stat] = errorBars2()
  stat.description = 'Another error bar example.';
  data = ACID_data;
  y = mean( data, 2 );
  e = std( data, 1, 2 );
  errorbar( y, e, 'xr' );
end
% =========================================================================
function [stat] = legendsubplots()
  stat.description = [ 'Subplots with legends. ' , ...
    'Increase value of "length" in the code to stress-test your TeX installation.' ];
  stat.unreliable = isOctave; %FIXME: investigate
  stat.issues = 609;

  % size of upper subplot
  rows = 4;
  % number of points.  A large number here (eg 1000) will stress-test
  % matlab2tikz and your TeX installation.  Be prepared for it to run out of
  % memory
  length = 100;

  % generate some spurious data
  t = 0:(4*pi)/length:4*pi;
  x = t;
  a = t;
  y = sin(t) + 0.1*sin(134*t.^2);
  b = sin(t) + 0.1*cos(134*t.^2) + 0.05*cos(2*t);

  % plot the top figure
  subplot(rows+2,1,1:rows);

  % first line
  sigma1 = std(y);
  tracey = mean(y,1);
  plot123 = plot(x,tracey,'b-');

  hold on

  % second line
  sigma2 = std(b);
  traceb = mean(b,1);
  plot456 = plot(a,traceb,'r-');

  spec0 = ['Mean V(t)_A (\sigma \approx ' num2str(sigma1,'%0.4f') ')'];
  spec1 = ['Mean V(t)_B (\sigma \approx ' num2str(sigma2,'%0.4f') ')'];

  hold off
  %plot123(1:2)
  legend([plot123; plot456],spec0,spec1)
  legend boxoff
  xlabel('Time/s')
  ylabel('Voltage/V')
  title('Time traces');

  % now plot a differential trace
  subplot(rows+2,1,rows+1:rows+2)
  plot7 = plot(a,traceb-tracey,'k');

  legend(plot7,'\Delta V(t)')
  legend boxoff
  xlabel('Time/s')
  ylabel('\Delta V')
  title('Differential time traces');
end
% =========================================================================
function [stat] = bodeplots()
  stat.description = 'Bode plots with legends.';
  stat.unreliable = isMATLAB(); % FIXME: inconsistent axis limits and
  % tick positions; see #641 (issuecomment-106241711)

  if isempty(which('tf'))
      fprintf( 'function "tf" not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

  Rc=1;
  C=1.5e-6; %F

  % Set inductors
  L1=4e-3;
  L2=0.8e-3;

  % Resistances of inductors
  R1=4;
  R2=2;

  % Transfer functions
  % Building transfer functions
  s=tf('s');
  Zc=1/(s*C)+Rc;
  Z1=s*L1+R1;
  Z2=s*L2+R2;
  LCLd=(Z2+Zc)/(Z1+Zc);
  LCL=(s^2*C*L2+1)/(s^2*C*L1+1);

  t=logspace(3,5,1000);
  bode(LCL,t)
  hold on
  bode(LCLd,t)
  title('Voltage transfer function of a LCL filter')
  set(findall(gcf,'type','line'),'linewidth',1.5)
  grid on

  legend('Perfect LCL',' Real LCL','Location','SW')

  % Work around a peculiarity in MATLAB: when the figure is invisible,
  % the XData/YData of all plots is NaN. It gets set to the proper values when
  % the figure is actually displayed. To do so, we temporarily toggle this
  % option. This triggers the call-back (and might flicker the figure).
  isVisible = get(gcf,'visible');
  set(gcf,'visible','on')
  set(gcf,'visible',isVisible);
end
% =========================================================================
function [stat] = rlocusPlot()
  stat.description = 'rlocus plot.';
  stat.unreliable = isMATLAB(); % FIXME: radial grid is not present on all
                                % environments (see #641)

  if isempty(which('tf'))
      fprintf( 'function "tf" not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

  if isMATLAB('<', [8,4])
      % in MATLAB R2014a and below, `rlocus` plots with no background color
      % are not supported. So, force that color to white to work around
      % that bug. Newer versions don't suffer from this.
      set(gca, 'Color', 'w');
  end

  rlocus(tf([1 1],[4 3 1]))

  % Work around a peculiarity in MATLAB: when the figure is invisible,
  % the XData/YData of all plots is NaN. It gets set to the proper values when
  % the figure is actually displayed. To do so, we temporarily toggle this
  % option. This triggers the call-back (and might flicker the figure).
  isVisible = get(gcf,'visible');
  set(gcf,'visible','on')
  set(gcf,'visible',isVisible);
end
% =========================================================================
function [stat] = mandrillImage()
  stat.description = 'Picture of a mandrill.';

  if ~exist('mandrill.mat','file')
      fprintf( 'mandrill data set not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

  data = load( 'mandrill' );
  image( data.X )       % show image
  colormap( data.map )  % adapt colormap
  axis image            % pixels should be square
  axis off              % disable axis
end
% =========================================================================
function [stat] = besselImage()
  stat.description = 'Bessel function.';
  stat.unreliable = isOctave(); % FIXME (Travis differs from Linux/Mac octave)

  nu   = -5:0.25:5;
  beta = 0:0.05:2.5;

  m = length(beta);
  n = length(nu);
  trace = zeros(m,n);
  for i=1:length(beta);
      for j=1:length(nu)
          if (floor(nu(j))==nu(j))
              trace(i,j)=abs(besselj(nu(j),beta(i)));
          end
      end
  end

  imagesc(nu,beta,trace);
  colorbar()
  xlabel('Order')
  ylabel('\beta')
  set(gca,'YDir','normal')
end
% =========================================================================
function [stat] = clownImage()
  stat.description = 'Picture of a clown.';

  if ~exist('clown.mat','file')
      fprintf( 'clown data set not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

  data = load( 'clown' );
  imagesc( data.X )
  colormap( gray )
end
% =========================================================================
function [stat] = zplanePlot1()
  stat.description = 'Representation of the complex plane with zplane.';
  stat.unreliable = isMATLAB('<', [8,4]); % FIXME: investigate

  % check of the signal processing toolbox is installed
  verInfo = ver('signal');
  if isempty(verInfo) || isempty(verInfo.Name)
      fprintf( 'Signal toolbox not found. Skip.\n\n' );
      stat.skip = true;

      return
  end

  [z,p] = ellip(4,3,30,200/500);
  zplane(z,p);
  title('4th-Order Elliptic Lowpass Digital Filter');
end
% =========================================================================
function [stat] = zplanePlot2()
  stat.description = 'Representation of the complex plane with zplane.';
  stat.unreliable = isMATLAB; % FIXME: #604; only difference is `width`
  stat.closeall = true;

  % check of the signal processing toolbox is installed
  verInfo = ver('signal');
  if isempty(verInfo) || isempty(verInfo.Name)
      fprintf( 'Signal toolbox not found. Skip.\n\n' );
      stat.skip = true;
      return
  end

  [b,a] = ellip(4,3,30,200/500);
  Hd = dfilt.df1(b,a);
  zplane(Hd) % FIXME: This opens a new figure that doesn't get closed automatically
end
% =========================================================================
function [stat] = freqResponsePlot()
  stat.description = 'Frequency response plot.';
  stat.closeall = true;
  stat.issues = [409];
  stat.unreliable = isMATLAB(); % FIXME: investigate
  % See also: https://github.com/matlab2tikz/matlab2tikz/pull/759#issuecomment-138477207
  % and https://gist.github.com/PeterPablo/b01cbe8572a9e5989037 (R2014b)

  % check of the signal processing toolbox is installed
  verInfo = ver('signal');
  if isempty(verInfo) || isempty(verInfo.Name)
      fprintf( 'Signal toolbox not found. Skip.\n\n' );
      stat.skip = true;
      return
  end

  b  = fir1(80,0.5,kaiser(81,8));
  hd = dfilt.dffir(b);
  freqz(hd); % FIXME: This opens a new figure that doesn't get closed automatically
end
% =========================================================================
function [stat] = axesLocation()
  stat.description = 'Swapped axis locations.';
  stat.issues = 259;

  plot(cos(1:10));
  set(gca,'XAxisLocation','top');
  set(gca,'YAxisLocation','right');
end
% =========================================================================
function [stat] = axesColors()
  stat.description = 'Custom axes colors.';

  plot(sin(1:15));
  set(gca,'XColor','g','YColor','b');
%  set(gca,'XColor','b','YColor','k');
  box off;
end
% =========================================================================
function [stat] = multipleAxes()
  stat.description = 'Multiple axes.';

  x1 = 0:.1:40;
  y1 = 4.*cos(x1)./(x1+2);
  x2 = 1:.2:20;
  y2 = x2.^2./x2.^3;

  line(x1,y1,'Color','r');
  ax1 = gca;
  set(ax1,'XColor','r','YColor','r')

  ax2 = axes('Position',get(ax1,'Position'),...
             'XAxisLocation','top',...
             'YAxisLocation','right',...
             'Color','none',...
             'XColor','k','YColor','k');

  line(x2,y2,'Color','k','Parent',ax2);

  xlimits = get(ax1,'XLim');
  ylimits = get(ax1,'YLim');
  xinc = (xlimits(2)-xlimits(1))/5;
  yinc = (ylimits(2)-ylimits(1))/5;

  % Now set the tick mark locations.
  set(ax1,'XTick',xlimits(1):xinc:xlimits(2) ,...
          'YTick',ylimits(1):yinc:ylimits(2) )
end
% =========================================================================
function [stat] = scatterPlotRandom()
  stat.description = 'Generic scatter plot.';

  n = 1:100;

  % MATLAB: Use the default area of 36 points squared. The units for the
  %         marker area is points squared.
  % octave: If s is not given, [...] a default value of 8 points is used.
  % Try obtain similar behavior and thus apply square root: sqrt(36) vs. 8
  sArea = 1000*(1+cos(n.^1.5)); % scatter size in unit points squared
  sRadius = sqrt(sArea*pi);
  if isMATLAB()
    s = sArea;    % unit: points squared
  elseif isOctave()
    s = sRadius;  % unit: points
  end

  scatter(n, n, s, n.^8);
  colormap autumn;
end
% =========================================================================
function [stat] = scatterPlot()
  stat.description = 'Scatter plot with MATLAB(R) stat.';
  if ~exist('seamount.mat','file')
      fprintf( 'seamount data set not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

  data = load( 'seamount' );
  scatter( data.x, data.y, 5, data.z, '^' );
end
% =========================================================================
function [stat] = scatterPlotMarkers()
  stat.description = 'Scatter plot with with different marker sizes and legend.';
  % FIXME: octave: Output is empty?! Potentially fixed by #669

  n = 1:10;
  d = 10;
  e = d * ones(size(n));

  % MATLAB: Use the default area of 36 points squared. The units for the
  %         marker area is points squared.
  % octave: If s is not given, [...] a default value of 8 points is used.
  % Try obtain similar behavior and thus apply square root: sqrt(36) vs. 8
  sArea = d^2 * n; % scatter size in unit points squared
  sRadius = sqrt(sArea);
  if isMATLAB()
    s = sArea;    % unit: points squared
  elseif isOctave()
    s = sRadius;  % unit: points
  end

  grid on;
  hold on;

  style = {'bx','rd','go','c.','m+','y*','bs','mv','k^','r<','g>','cp','bh'};
  names = {'bx','rd','go','c.','m plus','y star','bs','mv',...
           'k up triangle','r left triangle','g right triangle','cp','bh'};

  nStyles = numel(style);
  for ii = 1:nStyles
      curr = style{ii};
      scatter(n, ii * e, s, curr(1), curr(2));
  end
  xlim([min(n)-1 max(n)+1]);
  ylim([0 d*(nStyles+1)]);
  set(gca,'XTick',n,'XTickLabel',sArea,'XTickLabelMode','manual');
end
% =========================================================================
function [stat] = scatter3Plot()
  stat.description = 'Scatter3 plot with MATLAB(R) stat.';

  [x,y,z] = sphere(16);
  X = [x(:)*.5 x(:)*.75 x(:)];
  Y = [y(:)*.5 y(:)*.75 y(:)];
  Z = [z(:)*.5 z(:)*.75 z(:)];
  S = repmat([1 .75 .5]*10,numel(x),1);
  C = repmat([1 2 3],numel(x),1);
  scatter3(X(:),Y(:),Z(:),S(:),C(:),'filled'), view(-60,60)
  view(40,35)
end
% =========================================================================
function [stat] = spherePlot()
  stat.description = 'Stretched sphere with unequal axis limits.';
  stat.issues = 560;

  sphere(30);
  title('a sphere: x^2+y^2+z^2');
  xlabel('x');
  ylabel('y');
  zlabel('z');
  set(gca,'DataAspectRatio',[1,1,.5],'xlim',[-1 2], 'zlim',[-1 0.8])
end
% =========================================================================
function [stat] = surfPlot()
  stat.description = 'Surface plot.';

  [X,Y,Z] = peaks(30);
  surf(X,Y,Z)
  colormap hsv
  axis([-3 3 -3 3 -10 5])
  set(gca,'View',[-37.5,36]);

  hc = colorbar('YTickLabel', ...
                {'Freezing','Cold','Cool','Neutral',...
                 'Warm','Hot','Burning','Nuclear'});
  set(get(hc,'Xlabel'),'String','Multitude');
  set(get(hc,'Ylabel'),'String','Magnitude');
  set(hc,'YTick',0:0.7:7);
  set(hc,'YTickLabel',...
         {'-0.8' '-0.6' '-0.4' '-0.2' '0.0' ...
          '0.2' '0.4' '0.6' '0.8' '0.10' '0.12'});

  set(get(hc,'Title'),...
      'String', 'k(u,v)', ...
      'FontSize', 12, ...
      'interpreter', 'tex');

  xlabel( 'x' )
  ylabel( 'y' )
  zlabel( 'z' )
end
% =========================================================================
function [stat] = surfPlot2()
  stat.description = 'Another surface plot.';
  stat.unreliable = isMATLAB || isOctave; % FIXME: investigate

  z = [ ones(15, 5) zeros(15,5);
        zeros(5, 5) zeros( 5,5)];

  surf(abs(fftshift(fft2(z))) + 1);
  set(gca,'ZScale','log');

  legend( 'legendary', 'Location', 'NorthEastOutside' );
end
% =========================================================================
function [stat] = superkohle()
  stat.description = 'Superkohle plot.';
  stat.unreliable = isMATLAB('<=', [8,3]); %FIXME: broken since decd496 (mac vs linux)

  if ~exist('initmesh')
      fprintf( 'initmesh() not found. Skipping.\n\n' );
      stat.skip = true;
      return;
  end

  x1=0;
  x2=pi;
  y1=0;
  y2=pi;
  omegashape = [2 2 2 2             % 2 = line segment; 1 = circle segment; 4 = elipse segment
              x1 x2 x2 x1         % start point x
              x2 x2 x1 x1         % end point x
              y1 y1 y2 y2         % start point y
              y1 y2 y2 y1         % end point y
              1 1 1 1
              0 0 0 0];
  [xy,edges,tri] = initmesh(omegashape,'Hgrad',1.05);
  mmin = 1;
  while size(xy,2) < mmin
      [xy,edges,tri] = refinemesh(omegashape,xy,edges,tri);
  end
  m = size(xy,2);
  x = xy(1,:)';
  y = xy(2,:)';
  y0 = cos(x).*cos(y);

  pdesurf(xy,tri,y0(:,1));
  title('y_0');
  xlabel('x1 axis');
  ylabel('x2 axis');
  axis([0 pi 0 pi -1 1]);
  grid on;
end
% =========================================================================
function [stat] = meshPlot()
  stat.description = 'Mesh plot.';

  [X,Y,Z] = peaks(30);
  mesh(X,Y,Z)
  colormap hsv
  axis([-3 3 -3 3 -10 5])

  xlabel( 'x' )
  ylabel( 'y' )
  zlabel( 'z' )
end
% =========================================================================
function [stat] = ylabels()
  stat.description = 'Separate y-labels.';

  x = 0:.01:2*pi;
  H = plotyy(x,sin(x),x,3*cos(x));

  ylabel(H(1),'sin(x)');
  ylabel(H(2),'3cos(x)');

  xlabel(H(1),'time');
end
% =========================================================================
function [stat] = spectro()
  stat.description = 'Spectrogram plot';
  stat.unreliable = isMATLAB('<', [8,4]); % FIXME: investigate

  % In the original test case, this is 0:0.001:2, but that takes forever
  % for LaTeX to process.
  if isempty(which('chirp'))
      fprintf( 'chirp() not found. Skipping.\n\n' );
      stat.description = [];
      stat.skip = true;
      return
  end

  T = 0:0.005:2;
  X = chirp(T,100,1,200,'q');
  spectrogram(X,128,120,128,1E3);
  title('Quadratic Chirp');
end
% =========================================================================
function [stat] = mixedBarLine()
  stat.description = 'Mixed bar/line plot.';
  stat.unreliable = isOctave; %FIXME: investigate (octave of egon)
  % unreliable, see issue #614 (comment 92263263)

  data = ACID_data;
  x = data(:);
  hist(x,10)
  y = ylim;
  hold on;
  plot([mean(x) mean(x)], y, '-r');
  hold off;
end
% =========================================================================
function [stat] = decayingharmonic()
  stat.description = 'Decaying harmonic oscillation with \TeX{} title.';
  stat.issues = 587;

  % Based on an example from
  % http://www.mathworks.com/help/techdoc/creating_plots/f0-4741.html#f0-28104
  A = 0.25;
  alpha = 0.007;
  beta = 0.17;
  t = 0:901;
  y = A * exp(-alpha*t) .* sin(beta*t);
  plot(t, y)
  title('{\itAe}^{-\alpha\itt}sin\beta{\itt}, \alpha<<\beta, \beta>>\alpha, \alpha<\beta, \beta>\alpha, b>a')
  xlabel('Time \musec.')
  ylabel('Amplitude |X|')
end
% =========================================================================
function [stat] = texcolor()
  stat.description = 'Multi-colored text using \TeX{} commands.';

  % Taken from an example at
  % http://www.mathworks.com/help/techdoc/creating_plots/f0-4741.html#f0-28104
  text(.1, .5, ['\fontsize{16}black {\color{magenta}magenta '...
                '\color[rgb]{0 .5 .5}teal \color{red}red} black again'])
end
% =========================================================================
function [stat] = textext()
  stat.description = 'Formatted text and special characters using \TeX{}.';

  % Taken from an example at
  % http://www.mathworks.com/help/techdoc/creating_plots/f0-4741.html#f0-28303
  txstr(1) = { 'Each cell is a quoted string' };
  txstr(2) = { 'You can specify how the string is aligned' };
  txstr(3) = { 'You can use LaTeX symbols like \pi \chi \Xi' };
  txstr(4) = { '\bfOr use bold \rm\itor italic font\rm' };
  txstr(5) = { '\fontname{courier}Or even change fonts' };
  txstr(5) = { 'and use umlauts like äöüßÄÖÜ and accents éèêŐőŰűç' };
  plot( 0:6, sin(0:6) )
  text( 5.75, sin(2.5), txstr, 'HorizontalAlignment', 'right' )
end
% =========================================================================
function [stat] = texrandom()
  stat.description = 'Random TeX symbols';

  try
      rng(42); %fix seed
      %TODO: fully test tex conversion instead of a random subsample!
  catch
      rand('seed', 42); %#ok (this is deprecated in MATLAB)
  end

  num = 20; % number of symbols per line
  symbols = {'\it', '\bf', '\rm', '\sl',                                ...
             '\alpha', '\angle', '\ast', '\beta', '\gamma', '\delta',   ...
             '\epsilon', '\zeta', '\eta', '\theta', '\vartheta',        ...
             '\iota', '\kappa', '\lambda', '\mu', '\nu', '\xi', '\pi',  ...
             '\rho', '\sigma', '\varsigma', '\tau', '\equiv', '\Im',    ...
             '\otimes', '\cap', '{\int}', '\rfloor', '\lfloor', '\perp',...
             '\wedge', '\rceil', '\vee', '\langle', '\upsilon', '\phi', ...
             '\chi', '\psi', '\omega', '\Gamma', '\Delta', '\Theta',    ...
             '\Lambda', '\Xi', '\Pi', '\Sigma', '\Upsilon', '\Phi',     ...
             '\Psi', '\Omega', '\forall', '\exists', '\ni', '{\cong}',  ...
             '\approx', '\Re', '\oplus', '\cup', '\subseteq', '\lceil', ...
             '\cdot', '\neg', '\times', '\surd', '\varpi', '\rangle',   ...
             '\sim', '\leq', '\infty', '\clubsuit', '\diamondsuit',     ...
             '\heartsuit', '\spadesuit', '\leftrightarrow',             ...
             '\leftarrow', '\Leftarrow', '\uparrow', '\rightarrow',     ...
             '\Rightarrow', '\downarrow', '\circ', '\pm', '\geq',       ...
             '\propto', '\partial', '\bullet', '\div', '\neq',          ...
             '\aleph', '\wp', '\oslash', '\supseteq', '\nabla',         ...
             '{\ldots}', '\prime', '\0', '\mid', '\copyright',          ...
             '\o', '\in', '\subset', '\supset',                         ...
             '\_', '\^', '\{', '\}', '$', '%', '#',                     ...
             '(', ')', '+', '-', '=', '/', ',', '.', '<', '>',          ...
             '!', '?', ':', ';', '*', '[', ']', '§', '"', '''',         ...
             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',          ...
             'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',     ...
             'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',     ...
             'w', 'x', 'y', 'z',                                        ...
             'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',     ...
             'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',     ...
             'W', 'X', 'Y', 'Z'                                         ...
            };
      % Note: Instead of '\ldots' the list of symbols contains the entry
      %       '{\ldots}'. This is because TeX gives an error if it
      %       encounters the sequence '$a_\ldots$' or '$a^\ldots$'. It
      %       looks like that is a TeX bug. Nevertheless this sequence
      %       could appear in the random output, therefore \ldots is
      %       wrapped in braces since '$a_{\ldots}$' and '$a^{\ldots}$'
      %       don't crash TeX.
      %       Same thing with '\cong' and '\int'.
      % \color{red} etc. isn't included
      % \fontname{Times} etc. isn't included
      % \fontsize{12} etc. isn't included

  switch getEnvironment
      case 'MATLAB'
          % MATLAB expects tilde and ampersand to be un-escaped and backslashes
          % to be escaped
          symbols = [ symbols, {'~', '&', '\\'} ];
      case 'Octave'
          % Octave expects tilde and ampersand to be escaped for regular
          % output. If either are used un-escaped, that creates odd output in
          % Octave itself, but since matlab2tikz should be able to handle
          % those cases, let's include the un-escaped symbols in the list.
          symbols = [ symbols, {'\~', '\&', '~', '&'} ];
          % Octave's backslash handling is weird to say the least. However,
          % matlab2tikz treats backslashes the same in Octave as it does in
          % MATLAB. Therefore, let's add an escaped backslash to the list
          symbols = [ symbols, {'\\'} ];
      otherwise
          error( 'Unknown environment. Need MATLAB(R) or Octave.' )
  end

  for ypos = [0.9:-.2:.1]
      % Generate `num' random indices to the list of symbols
      index = max(ceil(rand(1, num)*length(symbols)), 1);
      % Assemble symbols into one cell string array
      string = symbols(index);

      % Add random amount of balanced braces in random positions to `string'.
      % By potentially generating more than one set of braces randomly, it's
      % possible to create more complex patterns of nested braces. Increase
      % `braceprob' to get more braces, but don't use values greater than or
      % equal 1 which would result in an infinite loop.
      braceprob = 0.6;
      while rand(1,1) < braceprob
          % Generate two random numbers ranging from 1 to n with n = number
          % of symbols in `string'
          bracepos = max(ceil(rand(1, 2)*length(string)), 1);
          % Modify `string' so that an opening brace is inserted before
          % min(bracepos) symbols and a closing brace after max(bracepos)
          % symbols. That way any number of symbols from one to all in
          % `string' are wrapped in braces for min(bracepos) == max(bracepos)
          % and min(bracepos) == 1 && max(bracepos) == length(string),
          % respectively.
          string = [string(1:min(bracepos)-1), {'{'},    ...
                    string(min(bracepos):max(bracepos)), ...
                    {'}'}, string(max(bracepos)+1:end)   ];
      end
      % Clean up: remove '{}', '{{}}', etc.
      clean = false;
      while clean == false
          clean = true;
          for i = 1:length(string)-1
              if strcmp( string(i), '{' ) && strcmp( string(i+1), '}' )
                  string = [string(1:i-1), string(i+2:end)];
                  clean = false;
                  break
              end
          end
      end

      % Subscripts '_' and superscripts '^' in TeX are tricky in that certain
      % combinations are not allowed and there are some subtleties in regard
      % to more complicated combinations of sub/superscripts:
      % - ^a or _a at the beginning of a TeX math expression is permitted.
      % - a^ or a_ at the end of a TeX math expression is not.
      % - a__b, a_^b, a^_b, or a^^b is not allowed, as is any number of
      %   consecutive sub/superscript operators. Actually a^^b does not
      %   crash TeX, but it produces seemingly random output instead of `b',
      %   therefore it should be avoided, too.
      % - a^b^c or a_b_c is not allowed as it results in a "double subscript/
      %   superscript" error.
      % - a^b_c or a_b^c, however, does work.
      % - a^bc^d or a_bc_d also works.
      % - a^b_c^d or a_b^c_d is not allowed and results in a "double
      %   subscript/superscript" error.
      % - a{_}b, a{^}b, {a_}b or {a^}b is not permitted.
      % - a{_b} or a{^b} is valid TeX code.
      % - {a_b}_c produces the same output as a_{bc}. Likewise for '^'.
      % - a_{b_c} results in "a index b sub-index c". Likewise for '^'.
      % - a^{b}^c or a_{b}_c is not allowed as it results in a "double
      %   subscript/superscript" error.
      %
      % From this we can derive a number of rules:
      % 1)  The last symbol in a TeX string must not be '^' or '_'.
      % 2a) There must be at least one non-brace symbol between any '^' and '_'.
      % 2b) There must be at least one non-brace symbol between any '_' and '^'.
      % 3a) There must either be at least two non-brace, non-'_' symbols or at
      %     least one non-brace, non-'_' symbol and one brace (opening or
      %     closing) between any two '^'.
      % 3b) There must either be at least two non-brace, non-'^' symbols or at
      %     least one brace (opening or closing) between any two '_'.
      % 4)  '^' or '_' must not appear directly before '}'.
      % 5)  '^' or '_' must not appear directly after '}'.
      % 6)  Whenever braces were mentioned, that refers to non-empty braces,
      %     i.e. '{}' counts as nothing. Printable/escaped braces '\{' and '\}'
      %     also don't count as braces but as regular symbols.
      % 7)  '^' or '_' must not appear directly before '\it', '\bf', '\rm', or
      %     '\sl'.
      % 8)  '^' or '_' must not appear directly after '\it', '\bf', '\rm', or
      %     '\sl'.
      %
      % A few test cases:
      % Permitted: ^a...  _a...  a^b_c  a_b^c  a^bc^d  a_bc_d  a{_b}  a{^b}
      %            {a_b}_c  a_{bc}  {a^b}^c  a^{bc}  a_{b_c}  a^{b^c}
      % Forbidden: ...z^  ...z_  a__b  a_^b  a^_b  [a^^b]  a^b^c  a_b_c
      %            a^b_c^d  a_b^c_d  a{_}b  a{^}b  {a_}b  {a^}b
      %            a^{_b}  a_{^b}  a^{b}^c  a_{b}_c
      %
      % Now add sub/superscripts according to these rules
      subsupprob   = 0.1;  % Probability for insertion of a sub/superscript
      caretdist    = Inf;  % Distance to the last caret
      underscdist  = Inf;  % Distance to the last underscore
      bracedist    = Inf;  % Distance to the last brace (opening or closing)
      pos = 0;
      % Making sure the post-update `pos' in the while loop is less than the
      % number of symbols in `string' enforces rule 1: The last symbol in
      % a TeX string must not be '^' or '_'.
      while pos+1 < length(string)
         % Move one symbol further
         pos = pos + 1;
         % Enforce rule 7: No sub/superscript directly before '\it', '\bf',
         %                 '\rm', or '\sl'.
         if strcmp( string(pos), '\it' ) || strcmp( string(pos), '\bf' ) ...
         || strcmp( string(pos), '\rm' ) || strcmp( string(pos), '\sl' )
             continue
         end
         % Enforce rule 8: No sub/superscript directly after '\it', '\bf',
         %                 '\rm', or '\sl'.
         if (pos > 1)                           ...
         && (    strcmp( string(pos-1), '\it' ) ...
              || strcmp( string(pos-1), '\bf' ) ...
              || strcmp( string(pos-1), '\rm' ) ...
              || strcmp( string(pos-1), '\sl' ) ...
            )
             continue
         end
         bracedist = bracedist + 1;
         % Enforce rule 4: No sub/superscript directly before '}'
         if strcmp( string(pos), '}' )
             bracedist = 0; % Also update braces distance
             continue
         end
         % Enforce rule 5: No sub/superscript directly after '}'
         if (pos > 1) && strcmp( string(pos-1), '}' )
             continue
         end
         % Update distances for either braces or caret/underscore depending
         % on whether the symbol currently under scrutiny is a brace or not.
         if strcmp( string(pos), '{' )
             bracedist = 0;
         else
             caretdist = caretdist + 1;
             underscdist = underscdist + 1;
         end
         % Generate two random numbers, then check if any of them is low
         % enough, so that with probability `subsupprob' a sub/superscript
         % operator is inserted into `string' at the current position. In
         % case both random numbers are below the threshold, whether a
         % subscript or superscript operator is to be inserted depends on
         % which of the two numbers is smaller.
         randomnums = rand(1, 2);
         if min(randomnums) < subsupprob
             if randomnums(1) < randomnums(2)
                 % Enforce rule 2b: There must be at least one non-brace
                 % symbol between previous '_' and to-be-inserted '^'.
                 if underscdist < 1
                     continue
                 end
                 % Enforce rule 3a: There must either be at least two
                 % non-brace, non-'_' symbols or at least one brace (opening
                 % or closing) between any two '^'.
                 if ~( ((caretdist >= 2) && (underscdist >= 2)) ...
                       || ((bracedist < 2) && (caretdist >= 2)) )
                     continue
                 end
                 % Insert '^' before `pos'th symbol in `string' now that
                 % we've made sure all rules are honored.
                 string = [ string(1:pos-1), {'^'}, string(pos:end) ];
                 caretdist = 0;
                 pos = pos + 1;
             else
                 % Enforce rule 2a: There must be at least one non-brace
                 % symbol between previous '^' and to-be-inserted '_'.
                 if caretdist < 1
                     continue
                 end
                 % Enforce rule 3b: There must either be at least two
                 % non-brace, non-'^' symbols or at least one brace (opening
                 % or closing) between any two '_'.
                 if ~( ((caretdist >= 2) && (underscdist >= 2)) ...
                       || ((bracedist < 2) && (underscdist >= 2)) )
                     continue
                 end
                 % Insert '_' before `pos'th symbol in `string' now that
                 % we've made sure all rules are honored.
                 string = [ string(1:pos-1), {'_'}, string(pos:end) ];
                 underscdist = 0;
                 pos = pos + 1;
             end
         end
      end % while pos+1 < length(string)

      % Now convert the cell string array of symbols into one regular string
      string = [string{:}];
      % Print the string in the figure to be converted by matlab2tikz
      text( .05, ypos, string, 'interpreter', 'tex' )
      % And print it to the console, too, in order to enable analysis of
      % failed tests
      fprintf( 'Original string: %s\n', string )
  end

  title('Random TeX symbols \\\{\}\_\^$%#&')
end
% =========================================================================
function [stat] = latexInterpreter()
    stat.description = '\LaTeX{} interpreter test (display math not working)';
    stat.issues = 448;
    stat.unreliable = isMATLAB('<=', [8,3]); %FIXME: broken since decd496 (mac vs linux)

    plot(magic(3),'-x');

    % Adapted from an example at
    % http://www.mathworks.com/help/techdoc/ref/text_props.html#Interpreter
    text(1.5, 2.0, ...
        '$$\int_0^x\!\int_{\Omega} \mathrm{d}F(u,v) \mathrm{d}\omega$$', ...
        'Interpreter', 'latex', ...
        'FontSize', 26);

    title(['display math old: $$\alpha$$ and $$\sum_\alpha^\Omega$$; ', ...
    'inline math: $\alpha$ and $\sum_\alpha^\Omega$'],'Interpreter','latex');
end
% =========================================================================
function [stat] = latexmath2()
  stat.description = 'Some nice-looking formulas typeset using the \LaTeX{} interpreter.';
  stat.issues = 637;

  % Adapted from an example at
  % http://www.mathworks.com/help/techdoc/creating_plots/f0-4741.html#bq558_t
  set(gcf, 'color', 'white')
  set(gcf, 'units', 'inches')
  set(gcf, 'position', [2 2 4 6.5])
  set(gca, 'visible', 'off')

  % Note: The matrices in h(1) and h(2) cannot be compiled inside pgfplots.
  %       They are therefore disabled.
% h(1) = text( 'units', 'inch', 'position', [.2 5],                    ...
%       'fontsize', 14, 'interpreter', 'latex', 'string',              ...
%       [ '$$\hbox {magic(3) is } \left( {\matrix{ 8 & 1 & 6 \cr'      ...
%         '3 & 5 & 7 \cr 4 & 9 & 2 } } \right)$$'                      ]);
% h(2) = text( 'units', 'inch', 'position', [.2 4],                    ...
%       'fontsize', 14, 'interpreter', 'latex', 'string',              ...
%       [ '$$\left[ {\matrix{\cos(\phi) & -\sin(\phi) \cr'             ...
%         '\sin(\phi) & \cos(\phi) \cr}} \right]'                      ...
%         '\left[ \matrix{x \cr y} \right]$$'                          ]);
  h(3) = text( 'units', 'inches', 'position', [.2 3],                    ...
        'fontsize', 14, 'interpreter', 'latex', 'string',              ...
        [ '$$L\{f(t)\}  \equiv  F(s) = \int_0^\infty\!\!{e^{-st}'      ...
          'f(t)dt}$$'                                                  ]);
  h(4) = text( 'units', 'inches', 'position', [.2 2],                    ...
        'fontsize', 14, 'interpreter', 'latex', 'string',              ...
        '$$e = \sum_{k=0}^\infty {\frac{1}{k!}} $$'                   );
  h(5) = text( 'units', 'inches', 'position', [.2 1],                    ...
        'fontsize', 14, 'interpreter', 'latex', 'string',              ...
        [ '$$m \ddot y = -m g + C_D \cdot {\frac{1}{2}}'                 ...
          '\rho {\dot y}^2 \cdot A$$'                                  ]);
  h(6) = text( 'units', 'inches', 'position', [.2 0],                    ...
        'fontsize', 14, 'interpreter', 'latex', 'string',              ...
        '$$\int_{0}^{\infty} x^2 e^{-x^2} dx = \frac{\sqrt{\pi}}{4}$$' );
end
% =========================================================================
function [stat] = parameterCurve3d()
  stat.description = 'Parameter curve in 3D with text boxes in-/outside axis.';
  stat.issues = [378, 790] ;
  t = linspace(0, 20*pi, 1e5);
  plot3(t, sin(t), 50 * cos(t));
  text(0.5, 0.5, 10, 'text inside axis limits');
  text(5.0, 1.5, 50, 'text outside axis (will be removed by cleanfigure())');
end
% =========================================================================
function [stat] = parameterSurf()
  stat.description = 'Parameter and surface plot.';
  stat.unreliable = isMATLAB('<', [8,4]); % FIXME: investigate

  if ~exist('TriScatteredInterp')
      fprintf( 'TriScatteredInterp() not found. Skipping.\n\n' );
      stat.skip = true;
      return;
  end

  t = (1:100).';
  t1 = cos(5.75352*t).^2;
  t2 = abs(sin(t));

  x = t1*4 - 2;
  y = t2*4 - 2;
  z = x.*exp(-x.^2 - y.^2);

  %TODO: do we really need this TriScatteredInterp?
  % It will be removed from MATLAB

  % Construct the interpolant
  F = TriScatteredInterp(x,y,z,'linear');

  % Evaluate the interpolant at the locations (qx, qy), qz
  % is the corresponding value at these locations.
  ti = -2:.25:2;
  [qx,qy] = meshgrid(ti,ti);
  qz = F(qx,qy);

  hold on
  surf(qx,qy,qz)
  plot3(x,y,z,'o')
  view(gca,[-69 14]);
  hold off
end
% =========================================================================
function [stat] = fill3plot()
  stat.description = 'fill3 plot.';

  if ~exist('fill3','builtin')
      fprintf( 'fill3() not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

  x1 = -10:0.1:10;
  x2 = -10:0.1:10;
  p = sin(x1);
  d = zeros(1,numel(p));
  d(2:2:end) = 1;
  h = p.*d;
  grid on;
  fill3(x1,x2,h,'k');
  view(45,22.5);
  box on;
end
% =========================================================================
function [stat] = rectanglePlot()
  stat.unreliable = isMATLAB('<=', [8,3]); %FIXME: #749 (Jenkins)
  stat.description = 'Rectangle handle.';

  rectangle('Position', [0.59,0.35,3.75,1.37],...
            'Curvature', [0.8,0.4],...
            'LineWidth', 2, ...
            'LineStyle', '--' ...
           );
  daspect([1,1,1]);
end
% =========================================================================
function [stat] = herrorbarPlot()
  stat.description = 'herrorbar plot.';
  % FIXME: octave is missing the legend

  hold on;
  X = 1:10;
  Y = 1:10;
  err = repmat(0.2, 1, 10);
  h1 = errorbar(X, Y, err+X/30, 'r');
  h_vec = herrorbar(X, Y, err);
  for h=h_vec
      set(h, 'color', [1 0 0]);
  end
  h2 = errorbar(X, Y+1, err, 'g');
  h_vec = herrorbar(X, Y+1, err+Y/40);
  for h=h_vec
      set(h, 'color', [0 1 0]);
  end
  legend([h1 h2], {'test1', 'test2'})
end
% =========================================================================
function [stat] = hist3d()
  stat.description = '3D histogram plot.';

  if ~exist('hist3','builtin') && isempty(which('hist3'))
      fprintf( 'Statistics toolbox not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

%  load carbig
%  X = [MPG,Weight];
%  hist3(X,[7 7]);
%  xlabel('MPG'); ylabel('Weight');
%  set(get(gca,'child'),'FaceColor','interp','CDataMode','auto');

  load carbig
  X = [MPG,Weight];
  hist3(X,[7 7]);
  xlabel('MPG'); ylabel('Weight');
  hist3(X,[7 7],'FaceAlpha',.65);
  xlabel('MPG'); ylabel('Weight');
  % Linux crashed with OpenGL.
  %%set(gcf,'renderer','opengl');

%  load seamount
%  dat = [-y,x]; % Grid corrected for negative y-values
%  n = hist3(dat); % Extract histogram data;
%                  % default to 10x10 bins
%  view([-37.5, 30]);
end
% =========================================================================
function [stat] = myBoxplot()
  stat.description = 'Boxplot.';
  stat.unreliable = isMATLAB('<', [8,4]); % R2014a; #552 #414

  if ~exist('boxplot','builtin') && isempty(which('boxplot'))
      fprintf( 'Statistics toolbox not found. Skipping.\n\n' );
      stat.skip = true;
      return
  end

  errors =[
     0.810000   3.200000   0.059500
     0.762500  -3.200000   0.455500
     0.762500   4.000000   0.901000
     0.762500   3.600000   0.406000
     0.192500   3.600000   0.307000
     0.810000  -3.600000   0.604000
     1.000000  -2.400000   0.505000
     0.430000  -2.400000   0.455500
     1.000000   3.200000   0.158500
  ];

  boxplot(errors);
end
% =========================================================================
function [stat] = areaPlot()
  stat.description = 'Area plot.';

  M = magic(5);
  M = M(1:3,2:4);
  h = area(1:3, M);
  legend(h([1,3]),'foo', 'foobar');
end
% =========================================================================
function [stat] = customLegend()
  stat.description = 'Custom legend.';
  stat.unreliable = isMATLAB('<', [8,4]) || isOctave; %FIXME: investigate (Travis differs from Linux/Mac octave)

  x = -pi:pi/10:pi;
  y = tan(sin(x)) - sin(tan(x));
  plot(x,y,'--rs');

  lh=legend('y');
  set(lh,'Location','West')
  set(lh,'color','g')
  set(lh,'edgecolor','r')
  set(lh, 'position',[.5 .6 .1 .05])
end
% =========================================================================
function [stat] = pixelLegend()
  stat.description = 'Legend with pixel position.';

  x = linspace(0,1);
  plot(x, [x;x.^2]);
  set(gca, 'units', 'pixels')
  lh=legend('1', '2');
  set(lh, 'units','pixels','position', [100 200 65 42])
end
% =========================================================================
function [stat] = croppedImage()
  stat.description = 'Custom legend.';

  if ~exist('flujet.mat','file')
      fprintf( 'flujet data set not found. Skipping.\n\n' );
      stat.skip = true;
      return;
  end

  load('flujet','X','map');
  image(X)
  colormap(map)
  %axis off
  axis image
  xlim([50 200])
  ylim([50 200])
  % colorbar at top
  colorbar('north');
  set(gca,'Units','normalized');
end
% =========================================================================
function [stat] = pColorPlot()
  stat.description = 'pcolor() plot.';

  ylim([-1 1]); xlim([-1 1]); hold on; % prevent error on octave
  n = 6;
  r = (0:n)'/n;
  theta = pi*(-n:n)/n;
  X = r*cos(theta);
  Y = r*sin(theta);
  C = r*cos(2*theta);
  pcolor(X,Y,C)
  axis equal tight
end
% =========================================================================
function [stat] = multiplePatches()
  stat.description = 'Multiple patches.';

  xdata = [2     2     0     2     5;
           2     8     2     4     5;
           8     8     2     4     8];
  ydata = [4     4     4     2     0;
           8     4     6     2     2;
           4     0     4     0     0];
  cdata = [15     0     4     6    10;
           1     2     5     7     9;
           2     3     0     8     3];
  p = patch(xdata,ydata,cdata,'Marker','o',...
            'MarkerFaceColor','flat',...
            'FaceColor','none');
end
% =========================================================================
function [stat] = hgTransformPlot()
  stat.description = 'hgtransform() plot.';

  if isOctave
      % Octave (3.8.0) has no implementation of `hgtransform`
      stat.skip = true;
      return;
  end
  % Check out
  % http://www.mathworks.de/de/help/matlab/ref/hgtransform.html.

  ax = axes('XLim',[-2 1],'YLim',[-2 1],'ZLim',[-1 1]);
  view(3);
  grid on;
  axis equal;

  [x,y,z] = cylinder([.2 0]);
  h(1) = surface(x,y,z,'FaceColor','red');
  h(2) = surface(x,y,-z,'FaceColor','green');
  h(3) = surface(z,x,y,'FaceColor','blue');
  h(4) = surface(-z,x,y,'FaceColor','cyan');
  h(5) = surface(y,z,x,'FaceColor','magenta');
  h(6) = surface(y,-z,x,'FaceColor','yellow');

  t1 = hgtransform('Parent',ax);
  t2 = hgtransform('Parent',ax);

  set(h,'Parent',t1);
  h2 = copyobj(h,t2);

  Txy = makehgtform('translate',[-1.5 -1.5 0]);
  set(t2,'Matrix',Txy)
  drawnow
end
% =========================================================================
function [stat] = logbaseline()
  stat.description = 'Logplot with modified baseline.';

  bar([0 1 2], [1 1e-2 1e-5],'basevalue', 1e-6);
  set(gca,'YScale','log');
end
% =========================================================================
function [stat] = alphaImage()
  stat.description = 'Images with alpha channel.';
  stat.unreliable = isOctave; %FIXME: investigate

  subplot(2,1,1);
  title('Scaled Alpha Data');
  N = 20;
  h_imsc = imagesc(repmat(1:N, N, 1));
  mask = zeros(N);
  mask(N/4:3*N/4, N/4:3*N/4) = 1;
  set(h_imsc, 'AlphaData', double(~mask));
  set(h_imsc, 'AlphaDataMapping', 'scaled');
  set(gca, 'ALim', [-1,1]);
  title('');

  subplot(2,1,2);
  title('Integer Alpha Data');
  N = 2;
  line([0 N]+0.5, [0 N]+0.5, 'LineWidth', 2, 'Color','k');
  line([0 N]+0.5, [N 0]+0.5, 'LineWidth', 2, 'Color','k');
  hold on
  imagesc([0,1;2,3],'AlphaData',uint8([64,128;192,256]))
end
% =========================================================================
function stat = annotationAll()
  stat.description = 'All possible annotations with edited properties';
  stat.unreliable = isMATLAB('<', [8,4]); % TODO: R2014a and older: #604

  if isempty(which('annotation'))
      fprintf( 'annotation() not found. Skipping.\n\n' );
      stat.skip = true;
      return;
  end

  % Create plot
  X1 = -5:0.1:5;
  plot(X1,log(X1.^2+1));

  % Create line
  annotation('line',[0.21 0.26], [0.63 0.76], 'Color',[0.47 0.3 0.44],...
             'LineWidth',4, 'LineStyle',':');

  % Create arrow
  if isOctave('>=', 4)
      headStyle = 'vback3'; %Octave does not support cback2 yet (2015-09)
  else
      headStyle = 'cback2';
  end

  annotation('arrow',[0.25 0.22], [0.96 0.05], 'LineStyle','-.',...
             'HeadStyle', headStyle);

  % Create textarrow
  annotation('textarrow',[0.46 0.35], [0.41 0.50],...
             'Color',[0.92 0.69 0.12], 'TextBackgroundColor',[0.92 0.83 0.83],...
             'String',{'something'}, 'LineWidth',2, 'FontWeight','bold',...
             'FontSize',20, 'FontName','Helvetica');

  % Create doublearrow
  annotation('doublearrow',[0.33 0.7], [0.56 0.55]);

  % Create textbox
  annotation('textbox', [0.41 0.69 0.17 0.10], 'String',{'something'},...
             'FitBoxToText','off');

  % Create ellipse
  if isOctave(4)
      colorSpec = 'EdgeColor';
  else
      colorSpec = 'Color';
  end
  annotation('ellipse',  [0.70 0.44 0.15 0.51], ...
            colorSpec, [0.63 0.07 0.18],...
            'LineWidth', 3, 'FaceColor',[0.80 0.87 0.96]);

  % Create rectangle
  annotation('rectangle', [0.3 0.26 0.53 0.58], 'LineWidth',8,...
             'LineStyle',':');
end
% =========================================================================
function [stat] = annotationSubplots()
  stat.description = 'Annotated and unaligned subplots';

  if isempty(which('annotation'))
    fprintf( 'annotation() not found. Skipping.\n\n' );
    stat.skip = true;
    return;
  end

  X1 = 0:0.01:1;
  Y1 = X1.^2;
  Y2 = Y1.^2;
  Y3 = X1.^(1/4);

  set(gcf, 'Position', [100 100 1500 600]);

  axes1 = axes('Parent',gcf, 'Position',[0.07 0.4015 0.2488 0.5146]);
  box(axes1,'on');
  hold(axes1,'all');

  title('f(x)=x^2');

  plot(X1,Y1,'Parent',axes1, 'DisplayName','(0:0.05:1).^2 vs 0:0.05:1');

  axes2 = axes('Parent',gcf, 'OuterPosition',[0.4062 0 0.2765 0.6314]);
  box(axes2,'on');
  hold(axes2,'all');

  plot(X1,Y2,'Parent',axes2,'DisplayName','(0:0.05:1).^4 vs 0:0.05:1');

  axes3 = axes('Parent',gcf, 'Position',[0.7421 0.3185 0.21 0.5480]);
  box(axes3,'on');
  hold(axes3,'all');

  plot(X1,Y3,'Parent',axes3,'DisplayName','(0:0.05:1).^(1/4) vs 0:0.05:1');

  annotation(gcf,'textbox',[0.3667 0.5521 0.0124 0.0393], ...
    'String',{'f^2'}, 'FitBoxToText','off');

  annotation(gcf,'arrow',[0.3263 0.4281], [0.6606 0.3519]);

  annotation(gcf,'textarrow',[0.6766 0.7229], [0.3108 0.6333],...
    'TextEdgeColor','none', 'HorizontalAlignment','center', ...
    'String',{'invert'});
end
% =========================================================================
function [stat] = annotationText()
  stat.description = 'Variations of textual annotations';
  stat.unreliable = isMATLAB('<', [8,4]); % FIXME: investigate

  if ~exist('annotation')
    fprintf( 'annotation() not found. Skipping.\n\n' );
    stat.skip = true;
    return;
  end

  X1 = -5:0.1:5;
  Y1 = log(X1.^2+1);

  % Resize figure to fit all text inside
  set(gcf,'Position', [100 100 1000 700]);

  % Otherwise the axes is plotted wrongly
  drawnow();

  % Create axes
  axes1 = axes('Parent',gcf);
  hold(axes1,'all');

  % Create plot
  plot(X1,Y1);

  % Create text
  text('Parent',axes1,'String',' \leftarrow some point on the curve',...
    'Position',[-2.01811125485123 1.5988219895288 7.105427357601e-15]);

  % Create text
  text('Parent',axes1,'String','another point \rightarrow',...
    'Position',[1 0.693147180559945 0],...
    'HorizontalAlignment','right');

  % Create textbox
  annotation(gcf,'textbox',...
    [0.305611222444885 0.292803442287824 0.122244488977956 0.0942562592047128],...
    'String',{'This boxes size','should adjust to','the text size'});

  % Create textbox
  annotation(gcf,'textbox',...
    [0.71643086172344 0.195876288659794 0.10020240480962 0.209240982129118],...
    'String',{'Multiple Lines due to fixed width'},...
    'FitBoxToText','off');

  % Create textbox
  annotation(gcf,'textbox',...
    [0.729456913827655 0.608247422680412 0.0851723446893787 0.104257797902974],...
    'String',{'Overlapping','and italic'},...
    'FontAngle','italic',...
    'FitBoxToText','off',...
    'BackgroundColor',[0.756862759590149 0.866666674613953 0.776470601558685]);

  % Create textbox
  annotation(gcf,'textbox',...
    [0.420000437011093 0.680170575692964 0.155149863590109 0.192171438527209],...
    'VerticalAlignment','middle',...
    'String',{'Text with a','thick and','dotted','border'},...
    'HorizontalAlignment','center',...
    'FitBoxToText','off',...
    'LineStyle',':',...
    'LineWidth',4);

  % Create textarrow
  annotation(gcf,'textarrow',[0.21943887775551 0.2625250501002],...
    [0.371002132196162 0.235640648011782],'TextEdgeColor','none',...
    'TextBackgroundColor',[0.678431391716003 0.921568632125854 1],...
    'TextRotation',30,...
    'VerticalAlignment','bottom',...
    'HorizontalAlignment','center',...
    'String',{'Rotated Text'});

  % Create textarrow
  annotation(gcf,'textarrow',[0.238436873747493 0.309619238476953],...
    [0.604315828808828 0.524300441826215],'TextEdgeColor','none',...
    'TextColor',[1 1 1],...
    'TextBackgroundColor',[0 0 1],...
    'TextRotation',30,...
    'VerticalAlignment','bottom',...
    'HorizontalAlignment','center',...
    'String',{'Rotated Text 2'},...
    'HeadStyle','diamond',...
    'Color',[1 0 0]);
end
% =========================================================================
function [stat] = annotationTextUnits()
  stat.description = 'Text with changed Units';
  stat.unreliable = isMATLAB('<', [8,4]); % FIXME: investigate

  if ~exist('annotation')
    fprintf( 'annotation() not found. Skipping.\n\n' );
    stat.skip = true;
    return;
  end

  X1 = -5:0.1:5;
  Y1 = log(X1.^2+1);

  % Resize figure to fit all text inside
  set(gcf,'Units', 'inches');
  set(gcf,'Position', [1.03125, 1.03125, 10.416666666666666, 7.291666666666666 ]);

  % Otherwise the axes is plotted wrongly
  drawnow();

  % Create axes
  axes1 = axes('Parent',gcf,'Units','centimeters',...
    'Position',[3.4369697916666664, 2.035743645833333 20.489627604166664 15.083009739583332]);
  hold(axes1,'all');

  % Create plot
  plot(X1,Y1);

  % Create text
  text('Parent',axes1,'Units','normalized',...
    'String',' \leftarrow some point on the curve',...
    'Position',[0.295865633074935 0.457364341085271 0]);

  % Create text
  text('Parent',axes1,'Units','centimeters',...
    'String','another point \rightarrow',...
    'Position',[12.2673383333333 2.98751989583333 0],...
    'HorizontalAlignment','right');

  % Create textbox
  annotation(gcf,'textbox',...
    [0.305611222444885 0.292803442287824 0.122244488977956 0.0942562592047128],...
    'String',{'This boxes size','should adjust to','the text size'},...
    'FitBoxToText','off',...
    'Units','pixels');

  % Create textarrow
  annotation(gcf,'textarrow',[0.21943887775551 0.2625250501002],...
    [0.371002132196162 0.235640648011782],'TextEdgeColor','none',...
    'TextBackgroundColor',[0.678431391716003 0.921568632125854 1],...
    'TextRotation',30,...
    'HorizontalAlignment','center',...
    'String',{'Rotated Text'},...
    'Units','points');

  % Create textarrow
  annotation(gcf,'textarrow',[0.238436873747493 0.309619238476953],...
    [0.604315828808828 0.524300441826215],'TextEdgeColor','none',...
    'TextColor',[1 1 1],...
    'TextBackgroundColor',[0 0 1],...
    'TextRotation',30,...
    'HorizontalAlignment','center',...
    'String',{'Rotated Text 2'},...
    'HeadStyle','diamond',...
    'Color',[1 0 0]);

  % Create textbox
  if ~isOctave(4)
      annotation(gcf,'textbox',...
        [0.71643086172344 0.195876288659794 0.10020240480962 0.209240982129118],...
        'String',{'Multiple Lines due to fixed width'},...
        'FitBoxToText','off',...
        'Units','characters');
  else
      % Octave 4 doesn't seem to like the "'Units','Characters'" in there
      % so just remove the object altogether.
      % This is strange, since it is documented: https://www.gnu.org/software/octave/doc/interpreter/Plot-Annotations.html#Plot-Annotations
  end

  % Create textbox
  annotation(gcf,'textbox',...
    [0.420000437011093 0.680170575692964 0.155149863590109 0.192171438527209],...
    'VerticalAlignment','middle',...
    'String',{'Text with a','thick and','dotted','border'},...
    'HorizontalAlignment','center',...
    'FitBoxToText','off',...
    'LineStyle',':',...
    'LineWidth',4);

  % Create textbox
  annotation(gcf,'textbox',...
    [0.729456913827655 0.608247422680412 0.0851723446893787 0.104257797902974],...
    'String',{'Overlapping','and italic'},...
    'FontAngle','italic',...
    'FitBoxToText','off',...
    'BackgroundColor',[0.756862759590149 0.866666674613953 0.776470601558685]);
end
% =========================================================================
function [stat] = imageOrientation_inline()
% Run test and save pictures as inline TikZ code
    [stat] = imageOrientation(false);
    stat.unreliable = isOctave; % FIXME
end
function [stat] = imageOrientation_PNG()
% Run test and save pictures as external PNGs
    [stat] = imageOrientation(true);
    stat.unreliable = isOctave; % FIXME
end
function [stat] = imageOrientation(imagesAsPng)
% Parameter 'imagesAsPng' is boolean
    stat.description = ['Systematic test of different axis', ...
      ' orientations and visibility (imagesAsPng = ', ...
      num2str(imagesAsPng), ').'];
    stat.extraOptions = {'imagesAsPng', imagesAsPng};

    data = magic(3);
    data = [[0,0,9]; data]; % ensure non-quadratic matrix

    subplot(3,2,1);
    imagesc(data); colormap(hot);
    set(gca,'XDir','normal');
    xlabel('XDir normal');
    set(gca,'YDir','normal');
    ylabel('YDir normal');

    subplot(3,2,2);
    imagesc(data); colormap(hot);
    set(gca,'XDir','reverse');
    xlabel('XDir reverse');
    set(gca,'YDir','normal');
    ylabel('YDir normal');

    subplot(3,2,3);
    imagesc(data); colormap(hot);
    set(gca,'XDir','normal');
    xlabel('XDir normal');
    set(gca,'YDir','reverse');
    ylabel('YDir reverse');

    subplot(3,2,4);
    imagesc(data); colormap(hot);
    set(gca,'XDir','reverse');
    xlabel('XDir reverse');
    set(gca,'YDir','reverse');
    ylabel('YDir reverse');

    subplot(3,2,5);
    imagesc(data); colormap(hot);
    set(gca,'XDir','normal');
    xlabel('XDir normal');
    set(gca,'YDir','reverse');
    ylabel('YDir reverse');
    axis off;
    title('like above, but axis off');

    subplot(3,2,6);
    imagesc(data); colormap(hot);
    set(gca,'XDir','reverse');
    xlabel('XDir reverse');
    set(gca,'YDir','reverse');
    ylabel('YDir reverse');
    axis off;
    title('like above, but axis off');
end
% =========================================================================
function [stat] = texInterpreter()
    stat.description = 'Combinations of tex commands';
    axes
    text(0.1,0.9, {'\bfBold text before \alpha and also afterwards.', 'Even the next line is bold \itand a bit italic.'});
    text(0.1,0.75, {'Changing \bfthe\fontname{Courier} font or \color[rgb]{0,0.75,0}color doesn''t', 'change the style. Resetting \rmthe style', 'doesn''t change the font or color.'});
    text(0.1,0.6, 'Styles can be {\bflimited} using \{ and \}.');
    text(0.1,0.45, {'But what happens to the output if there is', '{\bfuse an \alpha inside} the limitted style.'});
    text(0.1,0.3, 'Or if the\fontsize{14} size\color{red} and color are \fontsize{10}changed at different\color{blue} points.');
    text(0.1,0.15, {'Also_{some \bf subscripts} and^{superscripts} are possible.', 'Without brackets, it l^o_oks like t_his.' });
end
% =========================================================================
function [stat] = stackedBarsWithOther()
  stat.description = 'stacked bar plots and other plots';
  stat.issues = [442,648];
  stat.unreliable = isOctave || isMATLAB(); % FIXME: #614
  % details: https://github.com/matlab2tikz/matlab2tikz/pull/614#issuecomment-91844506

  % dataset stacked
  data = ACID_data;
  Y = round(abs(data(7:-1:3,1:3))/10);
  n = size(Y,1);
  xVals = (1:n).';
  yVals = min((xVals).^2, sum(Y,2));

  subplot(2,1,1); hold on;
  bar(Y,'stacked');
  plot(xVals, yVals, 'Color', 'r', 'LineWidth', 2);
  legend('show');

  subplot(2,1,2); hold on;
  b2 = barh(Y,'stacked','BarWidth', 0.75);
  plot(yVals, xVals, 'Color', 'b', 'LineWidth', 2);

  set(b2(1),'FaceColor','c','EdgeColor','none')
end
% =========================================================================
function [stat] = colorbarLabelTitle()
    stat.description = 'colorbar with label and title';
    stat.unreliable = isOctave; %FIXME: investigate
    stat.issues = 429;

    % R2014b handles colorbars smart:  `XLabel` and `YLabel` merged into `Label`
    % Use colormap 'jet' to create comparable output with MATLAB R2014b
    % * Check horizontal/vertical colorbar (subplots)
    % * Check if 'direction' is respected
    % * Check if multiline label and title works
    % * Check if latex interpreter works in label and title

    subplot(1,2,1)
    imagesc(magic(3));
    hc = colorbar;
    colormap('jet');
    title(hc,'title $\beta$','Interpreter','latex');
    ylabel(hc,'label $a^2$','Interpreter','latex');
    set(hc,'YDir','reverse');

    subplot(1,2,2)
    label_multiline = {'first','second','third'};
    title_multiline = {'title 1','title 2'};
    imagesc(magic(3));
    hc = colorbar('southoutside');
    colormap('jet');
    title(hc,title_multiline);
    xlabel(hc,label_multiline);
end
% =========================================================================
function [stat] = textAlignment()
    stat.description = 'alignment of text boxes and position relative to axis';
    stat.issues = 378;
    stat.unreliable = isOctave; %FIXME: investigate

    plot([0.0 2.0], [1.0 1.0],'k'); hold on;
    plot([0.0 2.0], [0.5 0.5],'k');
    plot([0.0 2.0], [1.5 1.5],'k');
    plot([1.0 1.0], [0.0 2.0],'k');
    plot([1.5 1.5], [0.0 2.0],'k');
    plot([0.5 0.5], [0.0 2.0],'k');

    text(1.0,1.0,'h=c, v=m', ...
        'HorizontalAlignment','center','VerticalAlignment','middle');
    text(1.5,1.0,'h=l, v=m', ...
        'HorizontalAlignment','left','VerticalAlignment','middle');
    text(0.5,1.0,'h=r, v=m', ...
        'HorizontalAlignment','right','VerticalAlignment','middle');

    text(0.5,1.5,'h=r, v=b', ...
        'HorizontalAlignment','right','VerticalAlignment','bottom');
    text(1.0,1.5,'h=c, v=b', ...
        'HorizontalAlignment','center','VerticalAlignment','bottom');
    text(1.5,1.5,'h=l, v=b', ...
        'HorizontalAlignment','left','VerticalAlignment','bottom');

    text(0.5,0.5,'h=r, v=t', ...
        'HorizontalAlignment','right','VerticalAlignment','top');
    text(1.0,0.5,'h=c, v=t', ...
        'HorizontalAlignment','center','VerticalAlignment','top');
    h_t = text(1.5,0.5,{'h=l, v=t','multiline'}, ...
        'HorizontalAlignment','left','VerticalAlignment','top');
    set(h_t,'BackgroundColor','g');

    text(0.5,2.1, 'text outside axis (will be removed by cleanfigure())');
    text(1.8,0.7, {'text overlapping', 'axis limits'});
    text(-0.2,0.7, {'text overlapping', 'axis limits'});
    text(0.9,0.0, {'text overlapping', 'axis limits'});
    h_t = text(0.9,2.0, {'text overlapping', 'axis limits'});

    % Set different units to test if they are properly handled
    set(h_t, 'Units', 'centimeters');
end
% =========================================================================
function [stat] = overlappingPlots()
    stat.description = 'Overlapping plots with zoomed data and varying background.';
    stat.unreliable = isMATLAB();
    % FIXME: this test is unreliable because the automatic axis limits of `ax2`
    % differ on different test platforms. Reckon this by creating the figure
    % using `ACID(97)` and then manually slightly modify the window size.
    % We should not set the axis limits explicitly rather find a better way.
    % Workaround: Slightly adapt width and height of `ax2`.
    % #591, #641 (issuecomment-106241711)
    stat.issues = 6;

    % create pseudo random data and convert it from matrix to vector
    l = 256;
    l_zoom = 64;
    wave = sin(linspace(1,10*2*pi,l));

    % plot data
    ax1 = axes();
    plot(ax1, wave);

    % overlapping plots with zoomed data
    ax3 = axes('Position', [0.2, 0.6, 0.3, 0.4]);
    ax4 = axes('Position', [0.7, 0.2, 0.2, 0.4]);
    ax2 = axes('Position', [0.25, 0.3, 0.3, 0.4]);

    plot(ax2, 1:l_zoom, wave(1:l_zoom), 'r');
    plot(ax3, 1:l_zoom, wave(1:l_zoom), 'k');
    plot(ax4, 1:l_zoom, wave(1:l_zoom), 'k');

    % set x-axis limits of main plot and first subplot
    xlim(ax1, [1,l]);
    xlim(ax3, [1,l_zoom]);

    % axis background color: ax2 = default, ax3 = green, ax4 = transparent
    set(ax3, 'Color', 'green');
    set(ax4, 'Color', 'none');
end
% =========================================================================
function [stat] = histogramPlot()
  if isOctave || isMATLAB('<', [8,4])
      % histogram() was introduced in Matlab R2014b.
      % TODO: later replace by 'isHG2()'
      fprintf('histogram() not found. Skipping.\n' );
      stat.skip = true;
      return;
  end
  stat.description = 'overlapping histogram() plots and custom size bins';
  stat.issues      = 525;

  x     = [-0.2, -0.484, 0.74, 0.632, -1.344, 0.921, -0.598, -0.727,...
           -0.708, 1.045, 0.37, -1.155, -0.807, 1.027, 0.053, 0.863,...
           1.131, 0.134, -0.017, -0.316];
  y     = x.^2;
  edges = [-2 -1:0.25:3];
  histogram(x,edges);
  hold on
  h = histogram(y);
  set(h, 'orientation', 'horizontal');
end
% =========================================================================
function [stat] = alphaTest()
  stat.description = 'overlapping objects with transparency and other properties';
  stat.issues      = 593;

  contourf(peaks(5)); hold on;              % background

  % rectangular patch with different properties
  h = fill([2 2 4 4], [2 3 3 2], 'r');
  set(h, 'FaceColor', 'r');
  set(h, 'FaceAlpha', 0.2);
  set(h, 'EdgeColor', 'g');
  set(h, 'EdgeAlpha', 0.4);
  set(h, 'LineStyle', ':');
  set(h, 'LineWidth', 4);
  set(h, 'Marker', 'x');
  set(h, 'MarkerSize', 16);
  set(h, 'MarkerEdgeColor', [1 0.5 0]);
  set(h, 'MarkerFaceColor', [1 0 0]);       % has no visual effect

  % line with different properties
  h = line([3 3.5], [1.5 3.5]);
  set(h, 'Color', [1 1 1]);
  if isMATLAB('>=', [8,4])
      % TODO: later replace by 'isHG2()'
      fprintf('Note: RGBA (with alpha channel) only in HG2.\n' );
      set(h, 'Color', [1 1 1 0.3]);
  end
  set(h, 'LineStyle', ':');
  set(h, 'LineWidth', 6);
  set(h, 'Marker', 'o');
  set(h, 'MarkerSize', 14);
  set(h, 'MarkerEdgeColor', [1 1 0]);
  set(h, 'MarkerFaceColor', [1 0 0]);
end
% =========================================================================
function [stat] = removeOutsideMarker()
  stat.description = 'remove markers outside of the box';
  stat.issues      = 788;

  % Create the data and plot it
  xdata          = -1 : 0.5 : 1.5;
  ydata_marker   = 1.5 * ones(size(xdata));
  ydata_line     = 1   * ones(size(xdata));
  ydata_combined = 0.5 * ones(size(xdata));
  plot(xdata, ydata_marker, '*', ...
       xdata, ydata_line, '-', ...
       xdata, ydata_combined, '*-');
  title('Markers at -1 and 0.5 should be removed, the line shortened');

  % Change the limits, so one marker is outside the box
  ylim([0, 2]);
  xlim([0, 2]);

  % Remove it
  cleanfigure;

  % Change the limits back to check result
  xlim([-1, 2]);
end
% =========================================================================
function [stat] = colorbars()
  stat.description = 'Manual positioning of colorbars';
  stat.issues      = [933 937];
  stat.unreliable  = isOctave(); %FIXME: positions differ between Octave 3.2 and 4.0.

  shift = [0.2 0.8 0.2 0.8];
  axLoc = {'in','out','out','in'};

  for iAx = 1:4
    hAx(iAx) = subplot(2,2,iAx);
    axPos    = get(hAx(iAx), 'Position');
    cbPos    = [axPos(1)+shift(iAx)*axPos(3), axPos(2), 0.02, 0.2];

    hCb(iAx) = colorbar('Position', cbPos);
    try
        % only in HG2
        set(hCb(iAx), 'AxisLocation', axLoc{iAx});
    end
    title(['AxisLocation = ' axLoc{iAx}]);
    grid('on');
  end
end
% =========================================================================
function [stat] = colorbarManualLocationRightOut()
  stat.description = 'Manual positioning of colorbars - Right Out';
  stat.issues      = [933 937];

  axLoc      = 'out';
  figPos     = [1  , 1, 11  ,10];
  axPos(1,:) = [1  , 1,  8  , 3];
  axPos(2,:) = [1  , 5,  8  , 3];
  cbPos      = [9.5, 1,  0.5, 7];

  colorbarManualLocationHelper_(figPos, axPos, cbPos, axLoc);
end
function [stat] = colorbarManualLocationRightIn()
  stat.description = 'Manual positioning of colorbars - Right In';
  stat.issues      = [933 937];

  axLoc      = 'in';
  figPos     = [ 1  , 1, 11  ,10];
  axPos(1,:) = [ 1  , 1,  8  , 3];
  axPos(2,:) = [ 1  , 5,  8  , 3];
  cbPos      = [10.5, 1,  0.5, 7];

  colorbarManualLocationHelper_(figPos, axPos, cbPos, axLoc);
end
function [stat] = colorbarManualLocationLeftOut()
  stat.description = 'Manual positioning of colorbars - Left Out';
  stat.issues      = [933 937];

  axLoc      = 'out';
  figPos     = [1  , 1, 11  , 10];
  axPos(1,:) = [2.5, 1,  8  ,  3];
  axPos(2,:) = [2.5, 5,  8  ,  3];
  cbPos      = [1.5, 1,  0.5,  7];

  colorbarManualLocationHelper_(figPos, axPos, cbPos, axLoc);
end
function [stat] = colorbarManualLocationLeftIn()
  stat.description = 'Manual positioning of colorbars - Left In';
  stat.issues      = [933 937];

  axLoc      = 'in';
  figPos     = [1  , 1, 11  , 10];
  axPos(1,:) = [2.5, 1,  8  ,  3];
  axPos(2,:) = [2.5, 5,  8  ,  3];
  cbPos      = [0.5, 1,  0.5,  7];

  colorbarManualLocationHelper_(figPos, axPos, cbPos, axLoc);
end
function colorbarManualLocationHelper_(figPos, axPos, cbPos, axLoc)
  % this is a helper function, not a test case
  set(gcf, 'Units','centimeters','Position', figPos);

  hAx(1) = axes('Units', 'centimeters', 'Position', axPos(1,:));
  imagesc([1,2,3], [4,5,6], magic(3)/9, [0,1]);

  hAx(2) = axes('Units', 'centimeters', 'Position', axPos(2,:));
  imagesc([1,2,3], [4,5,6], magic(3)/9, [0,1]);

  hCb = colorbar('Units', 'centimeters', 'Position', cbPos);
  try
      % only in HG2
      %TODO: check if there are HG1 / Octave counterparts for this property
      set(hCb, 'AxisLocation', axLoc);
  end

  labelProperty = {'Label', 'YLabel'}; %YLabel as fallback for
  idxLabel      = find(cellfun(@(p) isprop(hCb, p), labelProperty), 1);
  if ~isempty(idxLabel)
      hLabel = get(hCb, labelProperty{idxLabel});
      set(hLabel, 'String', ['AxisLocation = ' axLoc]);
  end
end
% =========================================================================


text:
function [warnings,errors] = svargplvmCheckSNR(SNR, errLimit, warLimit, throwError,displ)
% SVARGPLVMCHECKSNR Check Signal to Noise Ratio after
% optimisation, to ensure that the trivial local minimum
% of learning only noise is avoided.
% DESC Check SNR of optimised model
% FORMAT
% ARG SNR: the SNR of optiomised model in a cell array (one cell per
% modality)
% ARG errLimit: Optional, the limit below which an error message
% is printed
% ARG warLimit: Optional, the limit below which a warning message
% is printed
% RETURN warnings: in an array, representing all modalities where
% the SNR is low enough to be considered a warning
%
% COPYRIGHT: Andreas C. Damianou, 2013
%
% VARGPLVM

if nargin < 5 || isempty(displ), displ = true; end
if nargin < 4 || isempty(throwError), throwError = true; end
if nargin < 3 || isempty(warLimit), warLimit = 10; end
if nargin < 2 || isempty(errLimit), errLimit = 2; end
if nargin < 1, error('Not enough arguments given'); end

errStr = sprintf(['\nThis means that a bad local minimum has been reached\n', ...
    'where everything is explained by noise. Please try a different\n', ...
    'initialisation and/or consult the manual.\n']);
warStr = sprintf(['\nThis means that a bad local minimum has been reached\n', ...
    'where most signal is explained by noise. Consider trying a different\n', ...
    'initialisation and/or consult the manual.\n']);

errors = [];
warnings = [];
for i = 1:length(SNR)
    if ~isempty(SNR{i}) && SNR{i} <= errLimit
        errors = [errors i];
    end
end

if ~isempty(errors)
    errMsg = 'Error! Low SNR in modalities: ';
    errMsg = [errMsg num2str(errors)];
    errMsg = [errMsg errStr];
    if displ
        for j=1:length(SNR)
            fprintf('# SNR%d = %.6f\n', j, SNR{j})
        end
    end
    if throwError
        error(errMsg);
    end
else
    for i = 1:length(SNR)
        if ~isempty(SNR{i}) && SNR{i} <= warLimit
            warnings = [warnings i];
        end
    end
end

if ~isempty(warnings) && displ
    warMsg = 'WARNING! Low SNR in modalities: ';
    warMsg = [warMsg num2str(warnings)];
    warMsg = [warMsg warStr];
    warning(warMsg);
end

author: SheffieldML

repo: vargplvm