Mercurial > hg > octave-nkf
comparison scripts/plot/stemleaf.m @ 16180:3e6d15a2a50b
Update stemleaf to provide new features and minor fix to printd
author | Michael Godfrey <michaeldgodfrey@gmail.com> |
---|---|
date | Sat, 02 Mar 2013 18:01:47 -0500 |
parents | 2b994ee38b1c |
children | 0f0e970723ec |
comparison
equal
deleted
inserted
replaced
16179:025393bef399 | 16180:3e6d15a2a50b |
---|---|
18 ## License along with Octave; see the file COPYING. If not, | 18 ## License along with Octave; see the file COPYING. If not, |
19 ## see <http://www.gnu.org/licenses/>. | 19 ## see <http://www.gnu.org/licenses/>. |
20 | 20 |
21 | 21 |
22 ## -*- texinfo -*- | 22 ## -*- texinfo -*- |
23 ## @deftypefn {Function File} {} stemleaf (@var{x}) | 23 ## @deftypefn {Function File} {} stemleaf (@var{x}, @var{caption}) |
24 ## @deftypefnx {Function File} {@var{plot} =} stemleaf (@var{x}, @var{opt}) | 24 ## @deftypefnx {Function File} {} stemleaf (@var{x}, @var{caption}, @var{stem_sz}) |
25 ## | 25 ## @deftypefnx {Function File} {@var{plotstr} =} stemleaf (@dots{}) |
26 ## Compute and display a stem and leaf plot of the vector @var{x}. | 26 ## Compute and display a stem and leaf plot of the vector @var{x}. |
27 ## | 27 ## |
28 ## The @var{x} vector is converted to integer by @var{x} = @code{fix} (@var{x}). | 28 ## The input @var{x} should be a vector of integers. Any non-integer values |
29 ## If an output argument is provided, the plot is returned as | 29 ## will be converted to integer by @code{@var{x} = fix (@var{x})}. By default |
30 ## an array of strings. The first element is the heading | 30 ## each element of @var{x} will be plotted with the last digit of the element |
31 ## followed by an element for each stem. | 31 ## as a leaf value and the remaining digits as the stem. For example, 123 |
32 ## The default stem step is 10. | 32 ## will be plotted with the stem @samp{12} and the leaf @samp{3}. The second |
33 ## The @var{x} vector should be integers. It will be treated so that | 33 ## argument, @var{caption}, should be a char array which provides a description |
34 ## the last digit is the leaf value and the other digits are | 34 ## of the data. It is included as a heading for the output. |
35 ## the stems. | 35 ## |
36 ## The leaf digits are not sorted. If sorted leaf values | 36 ## The optional input @var{stem_sz} sets the width of each stem. |
37 ## are wanted, use @code{sort} (@var{x}) before calling @code{stemleaf} (@var{x}). | 37 ## The stem width is determined by @code{10^(@var{stem_sz} + 1)}. |
38 ## The stem and leaf plot is described in: Ch. 3, | 38 ## The default stem width is 10. |
39 ## Exploratory Data Analysis by J. W. Tukey, Addison-Wesley, 1977. | 39 ## |
40 ## The output of stemleaf is composed of two parts: a "Fenced Letter Display," | |
41 ## followed by the stem-and-leaf plot itself. The Fenced Letter Display is | |
42 ## described in @cite{Exploratory Data Analysis}. Briefly, the entries | |
43 ## are as shown: | |
44 ## @example | |
45 ## @group | |
46 ## | |
47 ## Fenced Letter Display | |
48 ## #% nx|___________________ nx = numel (x) | |
49 ## M% mi| md | mi median index, md median | |
50 ## H% hi|hl hu| hs hi lower hinge index, hl,hu hinges, hs h_spread | |
51 ## 1 |x(1) x(nx)| x(1), x(nx) first and last data value | |
52 ## _______ | |
53 ## ______|step |_______ step 1.5*h_spread | |
54 ## f|ifl ifh| inner fence, lower and higher | |
55 ## |nfl nfh| # data points within fences | |
56 ## F|ofl ofh| outer fence, lower and higher | |
57 ## |nFl nFh| # data points outside outer fences | |
58 ## @end group | |
59 ## @end example | |
60 ## | |
61 ## The stem-and-leaf plot shows on each line the stem value followed by the | |
62 ## string made up of the leaf digits. If the @var{stem_sz} is not 1 the | |
63 ## successive leaf values are separated by ",". | |
64 ## | |
65 ## With no return argument, the plot is immediately displayed. If an output | |
66 ## argument is provided, the plot is returned as an array of strings. | |
67 ## | |
68 ## The leaf digits are not sorted. If sorted leaf values are desired, use | |
69 ## @code{@var{xs} = sort (@var{x})} before calling @code{stemleaf (@var{xs})}. | |
70 ## | |
71 ## The stem and leaf plot and associated displays are described in: | |
72 ## Ch. 3, @cite{Exploratory Data Analysis} by J. W. Tukey, Addison-Wesley, 1977. | |
40 ## @seealso{hist, printd} | 73 ## @seealso{hist, printd} |
41 ## @end deftypefn | 74 ## @end deftypefn |
42 | 75 |
43 ## Author: Michael D. Godfrey <michaeldgodfrey@gmail.com> | 76 ## Author: Michael D. Godfrey <michaeldgodfrey@gmail.com> |
44 ## Description: Compute stem and leaf plot | 77 ## Description: Compute stem and leaf plot |
45 | 78 |
46 function varargout = stemleaf (x, stem_unit) | 79 function plotstr = stemleaf (x, caption, stem_sz) |
47 ## Compute and display a stem and leaf plot of the vector x. The x | 80 ## Compute and display a stem and leaf plot of the vector x. The x |
48 ## vector is converted to integer by x = fix(x). If an output argument | 81 ## vector is converted to integer by x = fix(x). If an output argument |
49 ## is provided, the plot is returned as an array of strings. The | 82 ## is provided, the plot is returned as an array of strings. The |
50 ## first element is the heading followed by an element for each stem. | 83 ## first element is the heading followed by an element for each stem. |
51 ## | 84 ## |
52 ## The default stem step is 10. If stem_unit is provided the stem | 85 ## The default stem step is 10. If stem_sz is provided the stem |
53 ## step is set to: 10^(stem_unit+1) The x vector should be integers. | 86 ## step is set to: 10^(stem_sz+1). The x vector should be integers. |
54 ## It will be treated so that the last digit is the leaf value and the | 87 ## It will be treated so that the last digit is the leaf value and the |
55 ## other digits are the stems. | 88 ## other digits are the stems. |
56 ## | 89 ## |
57 ## When we first implemented stem and leaf plots in the early 1960's | 90 ## When we first implemented stem and leaf plots in the early 1960's |
58 ## there was some discussion about sorting vs. leaving the leaf | 91 ## there was some discussion about sorting vs. leaving the leaf |
59 ## entries in the original order in the data. We decided in favor or | 92 ## entries in the original order in the data. We decided in favor of |
60 ## sorting the leaves for most purposes. This is the choice | 93 ## sorting the leaves for most purposes. This is the choice |
61 ## implemented in the SNAP/IEDA system that was written at that time. | 94 ## implemented in the SNAP/IEDA system that was written at that time. |
62 ## | 95 ## |
63 ## SNAP/IEDA and particularly its stem and leaf plotting were further | 96 ## SNAP/IEDA, and particularly its stem and leaf plotting, were further |
64 ## developed by Hale Trotter, David Hoagland (at Princeton and MIT) | 97 ## developed by Hale Trotter, David Hoagland (at Princeton and MIT), |
65 ## and others. | 98 ## and others. |
66 ## | 99 ## |
67 ## Tukey, in EDA, generally uses unsorted leaves. In addition, he | 100 ## Tukey, in EDA, generally uses unsorted leaves. In addition, he |
68 ## described a wide range of additional display formats. This | 101 ## described a wide range of additional display formats. This |
69 ## implementation does not sort the leaves, but if the x vector is | 102 ## implementation does not sort the leaves, but if the x vector is |
76 ## array of strings with each row containing a line of the plot | 109 ## array of strings with each row containing a line of the plot |
77 ## preceded by the lines of header text as the first row. This | 110 ## preceded by the lines of header text as the first row. This |
78 ## facilitates annotation. | 111 ## facilitates annotation. |
79 ## | 112 ## |
80 ## Note that the code has some added complexity due to the need to | 113 ## Note that the code has some added complexity due to the need to |
81 ## distinguish both + and - 0 stems. The +- stem values are essential | 114 ## distinguish both + and - 0 stems. The +- stem values are essential |
82 ## for all plots which span 0. After dealing with +-0 stems, the added | 115 ## for all plots which span 0. After dealing with +-0 stems, the added |
83 ## complexity of putting +- data values in the correct stem is minor, | 116 ## complexity of putting +- data values in the correct stem is minor, |
84 ## but the sign of 0 leaves must be checked. And, the cases where the | 117 ## but the sign of 0 leaves must be checked. And, the cases where the |
85 ## stems start or end at +- 0 must also be considered. | 118 ## stems start or end at +- 0 must also be considered. |
86 ## | 119 ## |
87 ## The fact that IEEE floating point defines +- 0 helps make this | 120 ## The fact that IEEE floating point defines +- 0 helps make this |
88 ## easier. | 121 ## easier. |
89 ## | 122 ## |
90 ## | |
91 ## Michael D. Godfrey January 2013 | 123 ## Michael D. Godfrey January 2013 |
92 | 124 |
93 ## More could be implemented for better data scaling. And, of course, | 125 ## More could be implemented for better data scaling. And, of course, |
94 ## other options for the kinds of plots described by Tukey could be | 126 ## other options for the kinds of plots described by Tukey could be |
95 ## provided. This may best be left to users. | 127 ## provided. This may best be left to users. |
96 | 128 |
97 if (nargin >= 2) | 129 if (nargin < 2 || nargin > 3) |
98 stem_step = 10^(stem_unit+1); | 130 print_usage (); |
131 endif | |
132 | |
133 if (! isvector (x)) | |
134 error ("stemleaf: X must be a vector"); | |
135 endif | |
136 | |
137 if (! ischar (caption)) | |
138 error ("stemleaf: CAPTION must be a character array"); | |
139 endif | |
140 | |
141 if (isinteger (x)) | |
142 ## Avoid use of integers because rounding rules do not use fix(): | |
143 ## Example: floor (int32 (-44)/10) == -4, floor (int32 (-46)/10) = -5 !!! | |
144 x = single (x); | |
145 elseif (isfloat (x)) | |
146 xint = fix (x); | |
147 if (any (x != xint)) | |
148 warning ("stemleaf: X truncated to integer values"); | |
149 x = xint; | |
150 endif | |
99 else | 151 else |
152 error ("stemleaf: X must be a numeric vector"); | |
153 endif | |
154 | |
155 if (nargin == 2) | |
156 stem_sz = 0; | |
100 stem_step = 10; | 157 stem_step = 10; |
101 endif | 158 else |
102 if (any (x == int32 (x)) == 0) | 159 if (isscalar (stem_sz) && stem_sz >= 0 && isreal (stem_sz)) |
103 printf ('Input vector truncated to integer values.\n') | 160 stem_sz = fix (stem_sz); |
104 x = fix (x); | 161 stem_step = 10^(stem_sz+1); |
105 endif | 162 else |
106 | 163 error ("stemleaf: STEM_SZ must be a real integer >= 0"); |
107 ## Avoid use of int32 due to: | 164 endif |
108 | 165 endif |
109 ## floor (int32 (-44)/10) == -4 and floor (int32 (-46)/10) = -5 !!! | |
110 ## x = sort (fix (x)); % User can decide about sorting x. | |
111 ## x = fix (x); | |
112 ## %Adjust scale if too small. | |
113 ## while any(abs((fix(x) - x)) >= abs(x/100)) | |
114 ## x =10*x; | |
115 ## endwhile | |
116 | 166 |
117 ## Note that IEEE 754 states that -+ 0 should compare equal. This has | 167 ## Note that IEEE 754 states that -+ 0 should compare equal. This has |
118 ## led to C sort (and therefore Octave) treating them as equal. Thus, | 168 ## led to C sort (and therefore Octave) treating them as equal. Thus, |
119 ## sort([ -1 0 -0 1]) yields: -1 0 -0 1. and, sort([-1 -0 0 1]) | 169 ## sort([-1 0 -0 1]) yields [-1 0 -0 1], and sort([-1 -0 0 1]) |
120 ## yields: -1 -0 0 1. This means that stem-and-leaf plotting cannot | 170 ## yields: [-1 -0 0 1]. This means that stem-and-leaf plotting cannot |
121 ## rely on sort to order the data as needed for display. | 171 ## rely on sort to order the data as needed for display. |
122 | 172 ## This also applies to min()/max() so these routines can't be relied |
123 if (all((sort(x) == x)) == 1) | 173 ## upon if the max or min is -+ 0. |
124 hsort = 'sorted.'; | 174 |
175 ## Compute hinges and fences based on ref: EDA pgs. 33 and 44. | |
176 ## Note that these outlier estimates are meant to be "distribution free". | |
177 | |
178 nx = numel (x); | |
179 xs = sort (x); # Note that sort preserves -0 | |
180 mdidx = fix ((nx + 1)/2); # median index | |
181 hlidx = fix ((mdidx + 1)/2); # lower hinge index | |
182 huidx = fix (nx + 1 - hlidx); # upper hinge index | |
183 md = xs(mdidx); # median | |
184 hl = xs(hlidx); # lower hinge | |
185 hu = xs(huidx); # upper hinge | |
186 h_spread = hu - hl; # h_spread: difference between hinges | |
187 step = 1.5*h_spread; # step: 1.5 * h_spread | |
188 i_fence_l = hl - step; # inner fences: outside hinges + step | |
189 o_fence_l = hl - 2*step; # outer fences: outside hinges + 2*step | |
190 i_fence_h = hu + step; | |
191 o_fence_h = hu + 2*step; | |
192 n_out_l = sum (x<i_fence_l) - sum (x<o_fence_l); | |
193 n_out_h = sum (x>i_fence_h) - sum (x>o_fence_h); | |
194 n_far_l = sum (x<o_fence_l); | |
195 n_far_h = sum (x>o_fence_h); | |
196 | |
197 # display table similar to that on pg. 33 | |
198 plot_out = sprintf(" Data: %s", caption); | |
199 plot_out = [plot_out; sprintf(" ")]; | |
200 plot_out = [plot_out; sprintf(" Fenced Letter Display")]; | |
201 plot_out = [plot_out; sprintf(" ")]; | |
202 plot_out = [plot_out; sprintf(" #%3d|___________________", nx)]; | |
203 plot_out = [plot_out; sprintf(" M%3d| %5d |", mdidx, md)]; | |
204 plot_out = [plot_out; sprintf(" H%3d|%5d %5d| %d", hlidx, hl, hu, h_spread)]; | |
205 plot_out = [plot_out; sprintf(" 1 |%5d %5d|", xs(1), xs(nx))]; | |
206 plot_out = [plot_out; sprintf(" _______")]; | |
207 plot_out = [plot_out; sprintf(" ______|%5d|_______",step)]; | |
208 plot_out = [plot_out; sprintf(" f|%5d %5d|", i_fence_l, i_fence_h)]; | |
209 plot_out = [plot_out; sprintf(" |%5d %5d| out", n_out_l, n_out_h)]; | |
210 plot_out = [plot_out; sprintf(" F|%5d %5g|", o_fence_l, o_fence_h)]; | |
211 plot_out = [plot_out; sprintf(" |%5d %5d| far",n_far_l,n_far_h)]; | |
212 plot_out = [plot_out; " "]; | |
213 | |
214 ## Determine stem values | |
215 min_x = min (x); | |
216 max_x = max (x); | |
217 if (min_x > 0) # all stems > 0 | |
218 stems = [fix(min(x)/stem_step) : (fix(max(x)/stem_step)+1)]; | |
219 elseif (max_x < 0) # all stems < 0 | |
220 stems = [(fix(min_x/stem_step)-1) : fix(max_x/stem_step)]; | |
221 if (stems(end) == 0) | |
222 stems(end) = -0; # Fix signbit on 0 lost by ':' operator | |
223 endif | |
224 elseif (min_x < 0 && max_x > 0) # range crosses 0 | |
225 stems = [(fix(min_x/stem_step)-1) : -1 , -0]; | |
226 stems = [stems, 0 : fix(max_x/stem_step)+1 ]; | |
227 else # one endpoint is a zero which may be +0 or -0 | |
228 if (min_x == 0) | |
229 if (any (x == 0 & signbit (x))) | |
230 min_x = -0; | |
231 else | |
232 min_x = +0; | |
233 endif | |
234 endif | |
235 if (max_x == 0) | |
236 if (any (x == 0 & ! signbit (x))) | |
237 max_x = +0; | |
238 else | |
239 max_x = -0; | |
240 endif | |
241 endif | |
242 stems = []; | |
243 if (signbit (min_x)) | |
244 stems = [(fix(min_x/stem_step)-1) : -1 , -0]; | |
245 endif | |
246 if (! signbit (max_x)) | |
247 stems = [stems, 0 : fix(max_x/stem_step)+1 ]; | |
248 endif | |
249 endif | |
250 | |
251 if (issorted (x)) | |
252 hsort = "sorted."; | |
125 else | 253 else |
126 hsort = 'unsorted.'; | 254 hsort = "unsorted."; |
127 endif | 255 endif |
128 nx = max (size (x)); | 256 |
129 ## Determine stem values | 257 ## Vectorized version provided by Rik Webring (Rik@ortave.org) |
130 if (min(x) < 0) | 258 ## Determine leaves for each stem: |
131 if (signbit(max(x)) == 0) # max is positive | 259 prev_line = "none"; |
132 stems = [fix(min(x)/stem_step)-1 : -1 -0]; | 260 new_line = 1; |
133 stems = [stems 0 : fix(max(x)/stem_step)+1 ]; | 261 for kx = 2: numel (stems) |
262 | |
263 stem_sign = signbit (stems(kx)); | |
264 if (stems(kx) <= 0) | |
265 idx = ((x <= stems(kx)*stem_step) & (x > (stems(kx-1)*stem_step)) | |
266 & (signbit (x) == stem_sign)); | |
267 xlf = abs (x(idx) - stems(kx)*stem_step); | |
134 else | 268 else |
135 if (max(x) < 0) | 269 idx = ((x < stems(kx)*stem_step) & (x >= (stems(kx-1)*stem_step)) |
136 stems = [(fix(min(x)/stem_step)-1) : fix(max(x)/stem_step)]; | 270 & (signbit (x) == stem_sign)); |
137 else | 271 xlf = abs (x(idx) - stems(kx-1)*stem_step); |
138 stems = [(fix(min(x)/stem_step)-1) : -1 -0]; | 272 endif |
139 stems = [stems 0 : fix(max(x)/stem_step)]; | 273 ## Convert leaves to a string |
140 endif | 274 if (stem_sz == 0) |
141 endif | 275 lf_str = sprintf ("%d", xlf); |
142 else # All stems are > 0 | |
143 stems = [fix(min(x)/stem_step) : fix(max(x)/stem_step) + 1]; | |
144 endif | |
145 ##stems | |
146 ##x | |
147 nstems = max(size(stems)); | |
148 ## compute hinges at +- 1.5 * quartiles | |
149 ## this requires sorted data! | |
150 xs = sort (x); # Note that sort preserves -0 | |
151 threeh = 1.5; | |
152 two = 2.0; | |
153 j = idivide(nx, 4, "fix") + 1; # Use F95 truncation. | |
154 k = nx - j + 1; | |
155 hl = xs (j); | |
156 hu = xs (k); | |
157 if ( (nx + 1) == (4 * j) ) | |
158 hl = (xs (j + 1) + hl) / two; | |
159 hu = (xs (k - 1) + hu) / two; | |
160 endif | |
161 | |
162 ## :::::::: determine h-spread (dh) and fences :::::::: | |
163 dh = hu - hl; | |
164 fu = hu + threeh * dh; | |
165 fl = hl - threeh * dh; | |
166 | |
167 ## :::::::: find value adjacent to lower fence :::::::: | |
168 for i = 1:j | |
169 if ( xs (i) >= fl ) | |
170 continue; | |
171 endif | |
172 endfor | |
173 ilow = i; | |
174 xlo = xs (ilow); | |
175 | |
176 ## :::::::: find value adjacent to upper fence :::::::: | |
177 for i = 1:j | |
178 if ( xs (nx -i + 1) <= fu ) | |
179 continue; | |
180 endif | |
181 endfor | |
182 | |
183 ihi = nx - i + 1; | |
184 xhi = xs (ihi); | |
185 | |
186 ## Heading for output: | |
187 plot_out = ""; | |
188 plot_out = [plot_out sprintf("stem step: %i, data: %s\nHinges: lo: %g, hi: %g\n", | |
189 stem_step, hsort, xlo, xhi)]; | |
190 | |
191 ## This may appear to be a good place to use vectorization using the | |
192 ## stem and data arrays but the necessary special case treatment of 0 | |
193 ## and -0 seems to result in little reduction of complexity, and since | |
194 ## this algorithm is for small data vectors only there would be | |
195 ## practically no performance improvement. | |
196 | |
197 ## Determine leaves for each stem: | |
198 for kx = 2:nstems | |
199 line_out = ""; | |
200 steml = ""; | |
201 ## Build a string of leaf digits for stem(kx) if stem(kx) <= 0, or | |
202 ## stem(kx-1) if stem(kx) > 0 | |
203 | |
204 ## stems -+ 0 have to be handled as special cases. | |
205 for xi = 1:nx | |
206 if(signbit(stems(kx)) != 0) | |
207 t1 = ((x(xi) <= stems(kx)*10) && (x(xi) > (stems(kx-1)*10))); | |
208 else | |
209 t1 = ((x(xi) < stems(kx)*10) && (x(xi) >= (stems(kx-1)*10))); | |
210 endif | |
211 ## Special tests for stem -+ 0 | |
212 if ((stems(kx) == 0) && signbit(stems(kx)) && (x(xi) == 0)) && !signbit(x(xi)) | |
213 t1 = 0; | |
214 endif | |
215 if ((stems(kx-1) == 0) && !signbit(stems(kx-1)) && (x(xi) == 0)) && signbit(x(xi)) | |
216 t1 = 0; | |
217 endif | |
218 ## Create line as a string | |
219 if t1 | |
220 if (stems(kx) <= 0) | |
221 xz = abs (x(xi) - stems(kx)*10); | |
222 else | |
223 xz = abs (x(xi) - stems(kx-1)*10); | |
224 endif | |
225 if ((stems(kx) == 0) && signbit(stems(kx))) | |
226 steml = [steml sprintf("%d", abs(x(xi) - stems(kx)*10))]; | |
227 else | |
228 steml = [steml sprintf("%d", xz)]; | |
229 endif | |
230 endif % t1 | |
231 endfor % xi = 1:nx | |
232 | |
233 ## Set correct -0 | |
234 if ((stems(kx) == 0) && signbit(stems(kx))) | |
235 line_out = [line_out sprintf(" -0 | %s", steml)]; % -0 stem. | |
236 else | 276 else |
237 if( stems(kx) < 0) | 277 lf_str = ""; |
238 line_out = [line_out sprintf("%4d | %s", stems(kx), steml)]; | 278 if (numel(xlf) > 0) |
239 else | 279 lf_str = sprintf ("%d", xlf(1,1)); |
240 if stems(kx) > 0 | 280 if (numel (xlf) > 1) |
241 line_out = [line_out sprintf("%4d | %s", stems(kx-1), steml)]; | 281 lf_str = [lf_str sprintf(",%d", xlf(1,2:numel(xlf)))]; |
242 endif | 282 endif |
243 endif | 283 endif |
244 endif | 284 endif |
245 plot_out = [plot_out; line_out]; | 285 |
246 endfor % kx = 2:nstems | 286 ## Set correct -0 |
287 if (stems(kx) == 0 && signbit (stems(kx))) | |
288 line = sprintf (" -0 | %s", lf_str); # -0 stem. | |
289 elseif (stems(kx) < 0) | |
290 line = sprintf ("%4d | %s", stems(kx), lf_str); | |
291 elseif (stems(kx) > 0) | |
292 line = sprintf ("%4d | %s", stems(kx-1), lf_str); | |
293 else | |
294 line = ""; | |
295 endif | |
296 | |
297 if ((!strcmp (lf_str, "")) || (stems(kx) == 0)|| stems(kx-1) == 0) | |
298 plot_out = [plot_out; line]; | |
299 new_line = 1; | |
300 else | |
301 if (new_line == 1) | |
302 plot_out = [plot_out; " :"]; # just print one : if no leaves | |
303 new_line = 0; | |
304 endif | |
305 endif | |
306 | |
307 endfor # kx = 2: numel (stems) | |
247 if (nargout == 0) | 308 if (nargout == 0) |
248 rows = size (plot_out)(1); | 309 disp (plot_out); |
249 cols = size (plot_out)(2); | |
250 for k = 1:rows | |
251 printf("%s\n", plot_out(k,1:cols)); | |
252 endfor | |
253 else | 310 else |
254 varargout{1} = plot_out; | 311 plotstr = plot_out; |
255 endif | 312 endif |
256 endfunction | 313 endfunction |
314 | |
257 | 315 |
258 %!demo | 316 %!demo |
259 %! ## Unsorted plot: | 317 %! ## Unsorted plot: |
260 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44]; | 318 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44]; |
261 %! stemleaf (x, 0); | 319 %! stemleaf (x, "Unsorted plot"); |
262 | 320 |
263 %!demo | 321 %!demo |
264 %! ## Sorted leaves: | 322 %! ## Sorted leaves: |
265 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44]; | 323 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44]; |
266 %! y = sort(x); | 324 %! y = sort (x); |
267 %! stemleaf (y, 0); | 325 %! stemleaf (y, "Sorted leaves"); |
268 | 326 |
269 %!demo | 327 %!demo |
270 %! ## More data (sorted) | 328 %! ## Sorted leaves (large dataset): |
271 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0 ]; | 329 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 \ |
272 %! y = sort(x); | 330 %! 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 \ |
273 %! stemleaf (y, 0); | 331 %! 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 \ |
332 %! 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 \ | |
333 %! 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57\ | |
334 %! 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 \ | |
335 %! 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0]; | |
336 %! y = sort (x); | |
337 %! stemleaf (y, "Sorted leaves (large dataset)"); | |
338 | |
339 %!demo | |
340 %! ## Gaussian leaves: | |
341 %! x = fix (30 * randn (300,1)); | |
342 %! stemleaf (x); | |
274 | 343 |
275 %!test | 344 %!test |
276 %! ## test minus to plus | 345 %! ## test minus to plus |
277 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0 ]; | 346 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 \ |
278 %! x = sort(x); | 347 %! 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 \ |
279 %! r2 = ["stem step: 10, data: sorted.\nHinges: lo: 30, hi: 116\n";... | 348 %! 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 \ |
280 %! " -2 | 82";" -1 | 3";" -0 | 2";" 0 | 00177";... | 349 %! 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 \ |
281 %! " 1 | 00112288";" 2 | 001133577777899";... | 350 %! 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57\ |
282 %! " 3 | 000111123456777889";" 4 | 00122233344456788";... | 351 %! 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 \ |
283 %! " 5 | 223788";" 6 | 138";" 7 | 11";" 8 | ";... | 352 %! 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0]; |
284 %! " 9 | 69";" 10 | 04555567999";" 11 | 0133344455566667777899";... | 353 %! x = sort (x); |
285 %! " 12 | 0011223444555677788";" 13 | 1239";" 14 | 16"]; | 354 %! rexp = char ( |
286 %! rx = stemleaf (x, 0); | 355 %! " Data: test minus to plus" , |
287 %! assert(r2, rx); | 356 %! " " , |
357 %! " Fenced Letter Display" , | |
358 %! " " , | |
359 %! " #138|___________________" , | |
360 %! " M 69| 52 |" , | |
361 %! " H 35| 30 116| 86" , | |
362 %! " 1 | -28 146|" , | |
363 %! " _______" , | |
364 %! " ______| 129|_______" , | |
365 %! " f| -99 245|" , | |
366 %! " | 0 0| out" , | |
367 %! " F| -228 374|" , | |
368 %! " | 0 0| far" , | |
369 %! " " , | |
370 %! " -2 | 82" , | |
371 %! " -1 | 3" , | |
372 %! " -0 | 2" , | |
373 %! " 0 | 00177" , | |
374 %! " 1 | 00112288" , | |
375 %! " 2 | 001133577777899" , | |
376 %! " 3 | 000111123456777889" , | |
377 %! " 4 | 00122233344456788" , | |
378 %! " 5 | 223788" , | |
379 %! " 6 | 138" , | |
380 %! " 7 | 11" , | |
381 %! " : " , | |
382 %! " 9 | 69" , | |
383 %! " 10 | 04555567999" , | |
384 %! " 11 | 0133344455566667777899", | |
385 %! " 12 | 0011223444555677788" , | |
386 %! " 13 | 1239" , | |
387 %! " 14 | 16" ); | |
388 %! r = stemleaf (x, "test minus to plus", 0); | |
389 %! assert (r, rexp); | |
390 | |
288 %!test | 391 %!test |
289 %! ## positive values above 0 | 392 %! ## positive values above 0 |
290 %! x = [22 12 28 52 39 12 11 11 42 38 44 18 44 ]; | 393 %! x = [5 22 12 28 52 39 12 11 11 42 38 44 18 44]; |
291 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: 12, hi: 42\n";... | 394 %! rexp = char ( |
292 %! " 1 | 22118";" 2 | 28";" 3 | 98";" 4 | 244";" 5 | 2"]; | 395 %! " Data: positive values above 0" , |
293 %! rx = stemleaf (x, 0); | 396 %! " " , |
294 %! assert(r2, rx); | 397 %! " Fenced Letter Display" , |
398 %! " " , | |
399 %! " # 14|___________________" , | |
400 %! " M 7| 22 |" , | |
401 %! " H 4| 12 42| 30" , | |
402 %! " 1 | 5 52|" , | |
403 %! " _______" , | |
404 %! " ______| 45|_______" , | |
405 %! " f| -33 87|" , | |
406 %! " | 0 0| out" , | |
407 %! " F| -78 132|" , | |
408 %! " | 0 0| far" , | |
409 %! " " , | |
410 %! " 0 | 5" , | |
411 %! " 1 | 22118" , | |
412 %! " 2 | 28" , | |
413 %! " 3 | 98" , | |
414 %! " 4 | 244" , | |
415 %! " 5 | 2" ); | |
416 %! r = stemleaf (x, "positive values above 0"); | |
417 %! assert (r, rexp); | |
418 | |
295 %!test | 419 %!test |
296 %! ## negative values below 0 | 420 %! ## negative values below 0 |
297 %! x = [22 12 28 52 39 12 11 11 42 38 44 18 44]; | 421 %! x = [5 22 12 28 52 39 12 11 11 42 38 44 18 44]; |
298 %! x = -x; | 422 %! x = -x; |
299 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: -42, hi: -12\n";... | 423 %! rexp = char ( |
300 %! " -5 | 2";" -4 | 244";" -3 | 98";" -2 | 28";" -1 | 22118"]; | 424 %! " Data: negative values below 0" , |
301 %! rx = stemleaf (x, 0); | 425 %! " " , |
302 %! assert(r2, rx); | 426 %! " Fenced Letter Display" , |
427 %! " " , | |
428 %! " # 14|___________________" , | |
429 %! " M 7| -28 |" , | |
430 %! " H 4| -42 -12| 30" , | |
431 %! " 1 | -52 -5|" , | |
432 %! " _______" , | |
433 %! " ______| 45|_______" , | |
434 %! " f| -87 33|" , | |
435 %! " | 0 0| out" , | |
436 %! " F| -132 78|" , | |
437 %! " | 0 0| far" , | |
438 %! " " , | |
439 %! " -5 | 2" , | |
440 %! " -4 | 244" , | |
441 %! " -3 | 98" , | |
442 %! " -2 | 28" , | |
443 %! " -1 | 22118" , | |
444 %! " -0 | 5" ); | |
445 %! r = stemleaf (x, "negative values below 0"); | |
446 %! assert (r, rexp); | |
447 | |
303 %!test | 448 %!test |
304 %! ## positive values from 0 | 449 %! ## positive values from 0 |
305 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44]; | 450 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44]; |
306 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: 11, hi: 42\n";... | 451 %! rexp = char ( |
307 %! " 0 | 20";" 1 | 22118";" 2 | 28";" 3 | 98";" 4 | 244";" 5 | 2"]; | 452 %! " Data: positive values from 0" , |
308 %! rx = stemleaf (x, 0); | 453 %! " " , |
309 %! assert(r2, rx); | 454 %! " Fenced Letter Display" , |
455 %! " " , | |
456 %! " # 15|___________________" , | |
457 %! " M 8| 22 |" , | |
458 %! " H 4| 11 42| 31" , | |
459 %! " 1 | 0 52|" , | |
460 %! " _______" , | |
461 %! " ______| 46|_______" , | |
462 %! " f| -35 88|" , | |
463 %! " | 0 0| out" , | |
464 %! " F| -82 135|" , | |
465 %! " | 0 0| far" , | |
466 %! " " , | |
467 %! " 0 | 20" , | |
468 %! " 1 | 22118" , | |
469 %! " 2 | 28" , | |
470 %! " 3 | 98" , | |
471 %! " 4 | 244" , | |
472 %! " 5 | 2" ); | |
473 %! r = stemleaf (x, "positive values from 0"); | |
474 %! assert (r, rexp); | |
475 | |
310 %!test | 476 %!test |
311 %! ## negative values from 0 | 477 %! ## negative values from 0 |
312 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44]; | 478 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44]; |
313 %! x = -x; | 479 %! x = -x; |
314 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: -42, hi: -11\n";... | 480 %! rexp = char ( |
315 %! " -5 | 2";" -4 | 244";" -3 | 98";" -2 | 28";" -1 | 22118";" -0 | 20"]; | 481 %! " Data: negative values from 0" , |
316 %! rx = stemleaf (x, 0); | 482 %! " " , |
317 %! assert(r2, rx); | 483 %! " Fenced Letter Display" , |
318 | 484 %! " " , |
485 %! " # 15|___________________" , | |
486 %! " M 8| -22 |" , | |
487 %! " H 4| -42 -11| 31" , | |
488 %! " 1 | -52 0|" , | |
489 %! " _______" , | |
490 %! " ______| 46|_______" , | |
491 %! " f| -88 35|" , | |
492 %! " | 0 0| out" , | |
493 %! " F| -135 82|" , | |
494 %! " | 0 0| far" , | |
495 %! " " , | |
496 %! " -5 | 2" , | |
497 %! " -4 | 244" , | |
498 %! " -3 | 98" , | |
499 %! " -2 | 28" , | |
500 %! " -1 | 22118" , | |
501 %! " -0 | 20" ); | |
502 %! r = stemleaf (x, "negative values from 0"); | |
503 %! assert (r, rexp); | |
504 | |
505 %!test | |
506 %! ## both +0 and -0 present | |
507 %! x = [-9 -7 -0 0 -0]; | |
508 %! rexp = char ( | |
509 %! " Data: both +0 and -0 present" , | |
510 %! " " , | |
511 %! " Fenced Letter Display" , | |
512 %! " " , | |
513 %! " # 5|___________________" , | |
514 %! " M 3| 0 |" , | |
515 %! " H 2| -7 0| 7" , | |
516 %! " 1 | -9 0|" , | |
517 %! " _______" , | |
518 %! " ______| 10|_______" , | |
519 %! " f| -17 10|" , | |
520 %! " | 0 0| out" , | |
521 %! " F| -28 21|" , | |
522 %! " | 0 0| far" , | |
523 %! " " , | |
524 %! " -0 | 9700" , | |
525 %! " 0 | 0" ); | |
526 %! r = stemleaf (x, "both +0 and -0 present"); | |
527 %! assert (r, rexp); | |
528 | |
529 %!test | |
530 %! ## both <= 0 and -0 present | |
531 %! x = [-9 -7 0 -0]; | |
532 %! rexp = char ( | |
533 %! " Data: both <= 0 and -0 present" , | |
534 %! " " , | |
535 %! " Fenced Letter Display" , | |
536 %! " " , | |
537 %! " # 4|___________________" , | |
538 %! " M 2| -7 |" , | |
539 %! " H 1| -9 0| 9" , | |
540 %! " 1 | -9 0|" , | |
541 %! " _______" , | |
542 %! " ______| 13|_______" , | |
543 %! " f| -22 13|" , | |
544 %! " | 0 0| out" , | |
545 %! " F| -36 27|" , | |
546 %! " | 0 0| far" , | |
547 | |
548 %! " " , | |
549 %! " -0 | 970" , | |
550 %! " 0 | 0" ); | |
551 %! r = stemleaf (x, "both <= 0 and -0 present"); | |
552 %! assert (r, rexp); | |
553 | |
554 %!test | |
555 %! ## Example from EDA: Chevrolet Prices pg. 30 | |
556 %! x = [150 250 688 695 795 795 895 895 895 1099 1166 1333 1499 1693 1699 1775 1995]; | |
557 %! rexp = char ( | |
558 %! " Data: Chevrolet Prices EDA pg.30", | |
559 %! " " , | |
560 %! " Fenced Letter Display" , | |
561 %! " " , | |
562 %! " # 17|___________________" , | |
563 %! " M 9| 895 |" , | |
564 %! " H 5| 795 1499| 704" , | |
565 %! " 1 | 150 1995|" , | |
566 %! " _______" , | |
567 %! " ______| 1056|_______" , | |
568 %! " f| -261 2555|" , | |
569 %! " | 0 0| out" , | |
570 %! " F|-1317 3611|" , | |
571 %! " | 0 0| far" , | |
572 %! " " , | |
573 %! " 1 | 50" , | |
574 %! " 2 | 50" , | |
575 %! " :" , | |
576 %! " 6 | 88,95" , | |
577 %! " 7 | 95,95" , | |
578 %! " 8 | 95,95,95" , | |
579 %! " :" , | |
580 %! " 10 | 99" , | |
581 %! " 11 | 66" , | |
582 %! " :" , | |
583 %! " 13 | 33" , | |
584 %! " 14 | 99" , | |
585 %! " :" , | |
586 %! " 16 | 93,99" , | |
587 %! " 17 | 75" , | |
588 %! " :" , | |
589 %! " 19 | 95" ); | |
590 | |
591 %! r = stemleaf(x, "Chevrolet Prices EDA pg.30", 1); | |
592 %! assert (r, rexp); | |
593 | |
594 ## Test input validation | |
595 %!error stemleaf () | |
596 %!error stemleaf (1, 2, 3, 4) | |
597 %!error <X must be a vector> stemleaf (ones (2,2), "") | |
598 %!warning <X truncated to integer values> tmp = stemleaf ([0 0.5 1],""); | |
599 %!error <X must be a numeric vector> stemleaf ("Hello World", "data") | |
600 %!error <STEM_SZ must be a real integer> stemleaf (1, "", ones (2,2)) | |
601 %!error <STEM_SZ must be a real integer> stemleaf (1, "", -1) | |
602 %!error <STEM_SZ must be a real integer> stemleaf (1, "", 1+i) |