comparison scripts/plot/util/linkaxes.m @ 18894:d1750be79dee

linkaxes.m: Implement new function linkaxes. * scripts/plot/util/linkaxes.m: New function * scripts/plot/util/module.mk: Add function to build system. * NEWS: Announce new function * plot.txi: Add function to manual. * __unimplemented__.m: Remove from unimplemented list. * linkprop.m: Use same style for demo as linkaxes.
author Willem Atsma <willem.atsma@tanglebridge.com>
date Tue, 18 Mar 2014 13:05:40 -0700
parents
children 65f19ac3cd1b
comparison
equal deleted inserted replaced
18892:868dcab453bd 18894:d1750be79dee
1 ## Copyright (C) 2014 Willem Atsma
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} linkaxes (@var{hax})
21 ## @deftypefnx {Function File} linkaxes (@var{hax}, @var{optstr})
22 ## Link the axis limits of 2-D plots such that a change in one is
23 ## propagated to the others.
24 ##
25 ## The axes handles to be linked are passed as the first argument @var{hax}.
26 ##
27 ## The optional second argument is a string which defines which axis limits
28 ## will be linked. The possible values for @var{optstr} are:
29 ##
30 ## @table @asis
31 ## @item @qcode{"x"}
32 ## Link x-axes
33 ##
34 ## @item @qcode{"y"}
35 ## Link y-axes
36 ##
37 ## @item @qcode{"xy"} (default)
38 ## Link both axes
39 ##
40 ## @item @qcode{"off"}
41 ## Turn off linking
42 ## @end table
43 ##
44 ## If unspecified the default is to link both X and Y axes.
45 ##
46 ## When linking, the limits from the first axes in @var{hax} are applied to the
47 ## other axes in the list. Subsequent changes to any one of the axes will be
48 ## propagated to the others.
49 ##
50 ## @seealso{linkprop, addproperty}
51 ## @end deftypefn
52
53 ## Author: Willem Atsma willem.atsma at tanglebridge.com
54 ## Created: 2014-03-18
55
56 function linkaxes (hax, optstr = "xy")
57
58 if (nargin < 1 || nargin > 2)
59 print_usage ();
60 endif
61
62 if (numel (hax) < 2)
63 error ("linkaxes: HAX must contain at least 2 handles");
64 elseif (! all (isaxes (hax(:))))
65 error ("linkaxes: HAX must be a vector of axes handles");
66 endif
67
68 ## Check if axes are linked already and clear if found.
69 ## Otherwise, add the necessary linkaxes_data property.
70 for i = 1:length (hax)
71 if (isprop (hax(i), "linkaxes_data"))
72 hld = get (hax(i), "linkaxes_data");
73 try
74 rmappdata (hld, "linkprop_data");
75 end_try_catch
76 else
77 addproperty ("linkaxes_data", hax(i), "any");
78 endif
79 endfor
80
81 switch (optstr)
82 case "x"
83 hlink = linkprop (hax, "xlim");
84 case "y"
85 hlink = linkprop (hax, "ylim");
86 case "xy"
87 hlink = linkprop (hax, {"xlim" "ylim"});
88 case "off"
89 ## do nothing - link already deleted
90 hlink = [];
91 otherwise
92 error ("linkaxes: unrecognized OPTSTR '%s'", optstr);
93 endswitch
94
95 if (! isempty (hlink))
96 setappdata (hax(1), "linkprop_data", hlink);
97 set (hax, "linkaxes_data", hax(1));
98 else
99 set (hax, "linkaxes_data", []);
100 endif
101
102 endfunction
103
104
105 %!demo
106 %! clf;
107 %! hax1 = subplot (3,1,1);
108 %! bar (rand (4, 1), 'facecolor', 'r');
109 %! hax2 = subplot (3,1,2);
110 %! bar (5*rand (4, 1), 'facecolor', 'g');
111 %! hax3 = subplot (3,1,3);
112 %! bar (10*rand (4, 1), 'facecolor', 'b');
113 %! input ('Type <RETURN> to link axes');
114 %! linkaxes ([hax1, hax2, hax3]);
115 %! input ('Type <RETURN> to change ylim');
116 %! ylim (hax3, [0 10]);
117
118 %!test
119 %! hf1 = figure ("visible", "off");
120 %! hax1 = axes ();
121 %! plot (1:10);
122 %! hf2 = figure ("visible", "off");
123 %! hax2 = axes ();
124 %! plot (10:-1:1, "-*g");
125 %! hf3 = figure ("visible", "off");
126 %! hax3 = axes ();
127 %! plot (1:10:100, "-xb");
128 %! unwind_protect
129 %! linkaxes ([hax1, hax2, hax3]);
130 %! ## Test initial values taken from first object in list
131 %! assert (xlim (hax3), [0 10]);
132 %! assert (ylim (hax3), [0 10]);
133 %! ## Test linking
134 %! xlim (hax2, [2 8]);
135 %! assert (xlim (hax1), [2 8]);
136 %! assert (xlim (hax3), [2 8]);
137 %! ylim (hax3, "auto");
138 %! assert (ylim (hax1), [0 100]);
139 %! assert (ylim (hax2), [0 100]);
140 %! ## Test re-linking removes old link
141 %! linkaxes ([hax1, hax2]);
142 %! ylim (hax3, [0 50]);
143 %! assert (ylim (hax1), [0 100]);
144 %! assert (ylim (hax2), [0 100]);
145 %! xlim (hax1, [0 4]);
146 %! assert (xlim (hax2), [0 4]);
147 %! ## Test linking of remaining objects after deletion of one object
148 %! linkaxes ([hax1, hax2, hax3]);
149 %! xlim (hax2, [0 1]);
150 %! assert (xlim (hax1), [0 1]);
151 %! assert (xlim (hax3), [0 1]);
152 %! delete (hax2);
153 %! xlim (hax3, [0 2]);
154 %! assert (xlim (hax1), [0 2]);
155 %! ## Test deletion of link
156 %! linkaxes ([hax1, hax3], "off");
157 %! xlim (hax3, [0 3]);
158 %! assert (xlim (hax1), [0 2]);
159 %! unwind_protect_cleanup
160 %! close ([hf1 hf2 hf3]);
161 %! end_unwind_protect
162
163 %% Test input validation
164 %!error linkaxes ()
165 %!error linkaxes (1,2,3)
166 %!error <HAX must be a vector of axes handles> linkaxes ([pi, e])
167