X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=octave_packages%2Fm%2Fplot%2Fsubplot.m;fp=octave_packages%2Fm%2Fplot%2Fsubplot.m;h=5f5673419057887327f5dded119fa6dfaa7d4c88;hb=1c0469ada9531828709108a4882a751d2816994a;hp=0000000000000000000000000000000000000000;hpb=63de9f36673d49121015e3695f2c336ea92bc278;p=CreaPhase.git diff --git a/octave_packages/m/plot/subplot.m b/octave_packages/m/plot/subplot.m new file mode 100644 index 0000000..5f56734 --- /dev/null +++ b/octave_packages/m/plot/subplot.m @@ -0,0 +1,365 @@ +## Copyright (C) 1995-2012 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} subplot (@var{rows}, @var{cols}, @var{index}) +## @deftypefnx {Function File} {} subplot (@var{rcn}) +## Set up a plot grid with @var{rows} by @var{cols} subwindows and plot +## in location given by @var{index}. +## +## If only one argument is supplied, then it must be a three digit value +## specifying the location in digits 1 (rows) and 2 (columns) and the plot +## index in digit 3. +## +## The plot index runs row-wise. First all the columns in a row are filled +## and then the next row is filled. +## +## For example, a plot with 2 by 3 grid will have plot indices running as +## follows: +## @tex +## \vskip 10pt +## \hfil\vbox{\offinterlineskip\hrule +## \halign{\vrule#&&\qquad\hfil#\hfil\qquad\vrule\cr +## height13pt&1&2&3\cr height12pt&&&\cr\noalign{\hrule} +## height13pt&4&5&6\cr height12pt&&&\cr\noalign{\hrule}}} +## \hfil +## \vskip 10pt +## @end tex +## @ifnottex +## +## @example +## @group +## +-----+-----+-----+ +## | 1 | 2 | 3 | +## +-----+-----+-----+ +## | 4 | 5 | 6 | +## +-----+-----+-----+ +## @end group +## @end example +## +## @var{index} may be a vector. In which case, the new axis will enclose +## the grid locations specified. The first demo illustrates an example: +## +## @example +## demo ("subplot", 1) +## @end example +## +## @end ifnottex +## @seealso{axes, plot} +## @end deftypefn + +## Author: Vinayak Dutt +## Adapted-By: jwe + +function h = subplot (varargin) + + align_axes = false; + replace_axes = false; + have_position = false; + initial_args_decoded = false; + + if (nargin > 2) + ## R, C, N? + arg1 = varargin{1}; + arg2 = varargin{2}; + arg3 = varargin{3}; + if (isnumeric (arg1) && isscalar (arg1) && isnumeric (arg2) + && isscalar (arg2) && isnumeric (arg3)) + rows = arg1; + cols = arg2; + index = arg3; + varargin(1:3)= []; + initial_args_decoded = true; + endif + endif + + if (! initial_args_decoded && nargin > 1) + ## check for 'position', pos, ... + if (strcmpi (varargin{1}, "position")) + arg = varargin{2}; + if (isnumeric (arg) && numel (arg) == 4) + pos = arg; + varargin(1:2) = []; + have_position = true; + initial_args_decoded = true; + else + error ("expecting position to be a 4-element numeric array"); + endif + endif + endif + + if (! initial_args_decoded && nargin > 0) + arg = varargin{1}; + if (nargin == 1 && ishandle (arg)) + ## Axes handle? + axes (arg); + cf = get (0, "currentfigure"); + set (cf, "nextplot", "add"); + return; + elseif (isscalar (arg) && arg >= 0) + ## RCN? + index = rem (arg, 10); + arg = (arg - index) / 10; + cols = rem (arg, 10); + arg = (arg - cols) / 10; + rows = rem (arg, 10); + varargin(1) = []; + initial_args_decoded = true; + else + error ("subplot: expecting axes handle or RCN argument"); + endif + endif + + if (! initial_args_decoded) + print_usage (); + endif + + if (! have_position) + cols = round (cols); + rows = round (rows); + index = round (index); + + if (any (index < 1) || any (index > rows*cols)) + error ("subplot: INDEX value must be greater than 1 and less than ROWS*COLS"); + endif + + if (cols < 1 || rows < 1 || index < 1) + error ("subplot: COLS, ROWS, and INDEX must be be positive"); + endif + endif + + nargs = numel (varargin); + while (nargs > 0) + arg = varargin{1}; + if (strcmpi (arg, "align")) + align_axes = true; + elseif (strcmpi (arg, "replace")) + replace_axes = true; + else + break; + endif + varargin(1) = []; + nargs--; + endwhile + + axesunits = get (0, "defaultaxesunits"); + cf = gcf (); + figureunits = get (cf, "units"); + unwind_protect + units = "normalized"; + set (0, "defaultaxesunits", units); + set (cf, "units", "pixels"); + + ## FIXME: At the moment we force gnuplot to use the aligned mode + ## which will set "activepositionproperty" to "position". + ## Τhis can yield to text overlap between labels and titles + ## see bug #31610 + if (strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")) + align_axes = true; + endif + + if (! have_position) + if (align_axes) + pos = subplot_position (rows, cols, index, "position"); + elseif (strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")) + pos = subplot_position (rows, cols, index, "outerpositiontight"); + else + pos = subplot_position (rows, cols, index, "outerposition"); + endif + endif + + set (cf, "nextplot", "add"); + + found = false; + kids = get (cf, "children"); + for child = reshape (kids, 1, numel (kids)) + ## Check whether this child is still valid; this might not be the + ## case anymore due to the deletion of previous children (due to + ## "deletefcn" callback or for legends/colorbars that are deleted + ## with their corresponding axes). + if (! ishandle (child)) + continue; + endif + if (strcmp (get (child, "type"), "axes")) + ## Skip legend and colorbar objects. + if (strcmp (get (child, "tag"), "legend") + || strcmp (get (child, "tag"), "colorbar")) + continue; + endif + if (align_axes) + objpos = get (child, "position"); + else + objpos = get (child, "outerposition"); + endif + if (all (objpos == pos) && ! replace_axes) + ## If the new axes are in exactly the same position as an + ## existing axes object, use the existing axes. + found = true; + tmp = child; + else + ## If the new axes overlap an old axes object, delete the old + ## axes. + x0 = pos(1); + x1 = x0 + pos(3); + y0 = pos(2); + y1 = y0 + pos(4); + objx0 = objpos(1); + objx1 = objx0 + objpos(3); + objy0 = objpos(2); + objy1 = objy0 + objpos(4); + if (! (x0 >= objx1 || x1 <= objx0 || y0 >= objy1 || y1 <= objy0)) + delete (child); + endif + endif + endif + endfor + + if (found) + set (cf, "currentaxes", tmp); + elseif (align_axes) + tmp = axes ("box", "off", "position", pos, varargin{:}); + elseif (strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")) + tmp = axes ("box", "off", "outerposition", pos, varargin{:}); + else + tmp = axes ("looseinset", [0 0 0 0], "box", "off", "outerposition", pos, + "autopos_tag", "subplot", varargin{:}); + endif + + unwind_protect_cleanup + set (0, "defaultaxesunits", axesunits); + set (cf, "units", figureunits); + end_unwind_protect + + if (nargout > 0) + h = tmp; + endif + +endfunction + +function pos = subplot_position (rows, cols, index, position_property) + + if (rows == 1 && cols == 1) + ## Trivial result for subplot (1,1,1) + if (strcmpi (position_property, "position")) + pos = get (0, "defaultaxesposition"); + else + pos = get (0, "defaultaxesouterposition"); + endif + return + endif + + if (strcmp (position_property, "outerposition") + || strcmp (position_property, "outerpositiontight")) + margins.left = 0.05; + margins.bottom = 0.05; + margins.right = 0.05; + margins.top = 0.05; + if (strcmp (position_property, "outerpositiontight")) + margins.column = 0.; + margins.row = 0.; + else + margins.column = 0.04 / cols; + margins.row = 0.04 / rows; + endif + width = 1 - margins.left - margins.right - (cols-1)*margins.column; + width = width / cols; + height = 1 - margins.top - margins.bottom - (rows-1)*margins.row; + height = height / rows; + else + defaultaxesposition = get (0, "defaultaxesposition"); + + ## The outer margins surrounding all subplot "positions" are independent + ## of the number of rows and/or columns + margins.left = defaultaxesposition(1); + margins.bottom = defaultaxesposition(2); + margins.right = 1.0 - margins.left - defaultaxesposition(3); + margins.top = 1.0 - margins.bottom - defaultaxesposition(4); + + ## Fit from Matlab experiments + pc = 1 ./ [0.1860, (margins.left + margins.right - 1)]; + margins.column = 1 ./ polyval (pc , cols); + pr = 1 ./ [0.2282, (margins.top + margins.bottom - 1)]; + margins.row = 1 ./ polyval (pr , rows); + + ## Calculate the width/height of the subplot axes "position". + ## This is also consistent with Matlab + width = 1 - margins.left - margins.right - (cols-1)*margins.column; + width = width / cols; + height = 1 - margins.top - margins.bottom - (rows-1)*margins.row; + height = height / rows; + endif + + ## Index offsets from the lower left subplot + yi = fix ((index(:)-1)/cols); + xi = index(:) - yi*cols - 1; + yi = (rows - 1) - yi; + + ## Lower left corner of the subplot, i.e. position(1:2) + x0 = xi .* (width + margins.column) + margins.left; + y0 = yi .* (height + margins.row) + margins.bottom; + + if (numel(x0) > 1) + ## subplot (row, col, m:n) + x1 = max (x0(:)) + width; + y1 = max (y0(:)) + height; + x0 = min (x0(:)); + y0 = min (y0(:)); + pos = [x0, y0, x1-x0, y1-y0]; + else + ## subplot (row, col, num) + pos = [x0, y0, width, height]; + endif + +endfunction + +%!demo +%! clf +%! r = 3; +%! c = 3; +%! fmt = {'horizontalalignment', 'center', 'verticalalignment', 'middle'}; +%! for n = 1:(r*c) +%! subplot (r, c, n) +%! xlabel (sprintf ("xlabel #%d", n)) +%! ylabel (sprintf ("ylabel #%d", n)) +%! title (sprintf ("title #%d", n)) +%! text (0.5, 0.5, sprintf('subplot(%d,%d,%d)', r, c, n), fmt{:}) +%! axis ([0 1 0 1]) +%! endfor +%! subplot (r, c, 1:3) +%! xlabel (sprintf ("xlabel #%d:%d", 1, 3)) +%! ylabel (sprintf ("ylabel #%d:%d", 1, 3)) +%! title (sprintf ("title #%d:%d", 1, 3)) +%! text (0.5, 0.5, sprintf('subplot(%d,%d,%d:%d)', r, c, 1, 3), fmt{:}) +%! axis ([0 1 0 1]) + +%!demo +%! clf +%! x = 0:1; +%! for n = 1:4 +%! subplot (2, 2, n, "align") +%! plot (x, x) +%! xlabel (sprintf ("xlabel (2,2,%d)", n)) +%! ylabel (sprintf ("ylabel (2,2,%d)", n)) +%! title (sprintf ("title (2,2,%d)", n)) +%! endfor +%! subplot (1, 2, 1, "align") +%! plot (x, x) +%! xlabel ("xlabel (1,2,1)") +%! ylabel ("ylabel (1,2,1)") +%! title ("title (1,2,1)") +