1Limits(3) User Contributed Perl Documentation Limits(3)
2
3
4
6 PDL::Graphics::Limits - derive limits for display purposes
7
9 Functions to derive limits for data for display purposes
10
12 use PDL::Graphics::Limits;
13
15 limits
16 limits derives global limits for one or more multi-dimensional sets of
17 data for display purposes. It obtains minimum and maximum limits for
18 each dimension based upon one of several algorithms.
19
20 @limits = limits( @datasets );
21 @limits = limits( @datasets, \%attr );
22 $limits = limits( @datasets );
23 $limits = limits( @datasets, \%attr );
24
25 Data Sets
26
27 A data set is represented as a set of one dimensional vectors, one per
28 dimension. All data sets must have the same dimensions. Multi-
29 dimensional data sets are packaged as arrays or hashs; one dimensional
30 data sets need not be. The different representations may be mixed, as
31 long as the dimensions are presented in the same order. Vectors may be
32 either scalars or ndarrays.
33
34 One dimensional data sets
35 One dimensional data sets may be passed directly, with no
36 additional packaging:
37
38 limits( $scalar, $ndarray );
39
40 Data sets as arrays
41 If the data sets are represented by arrays, each vectors in
42 each array must have the same order:
43
44 @ds1 = ( $x1_pdl, $y1_pdl );
45 @ds2 = ( $x2_pdl, $y2_pdl );
46
47 They are passed by reference:
48
49 limits( \@ds1, \@ds2 );
50
51 Data sets as hashes
52 Hashes are passed by reference as well, but must be further
53 embedded in arrays (also passed by reference), in order that
54 the last one is not confused with the optional trailing
55 attribute hash. For example:
56
57 limits( [ \%ds4, \%ds5 ], \%attr );
58
59 If each hash uses the same keys to identify the data, the keys
60 should be passed as an ordered array via the "VecKeys"
61 attribute:
62
63 limits( [ \%h1, \%h2 ], { VecKeys => [ 'x', 'y' ] } );
64
65 If the hashes use different keys, each hash must be accompanied
66 by an ordered listing of the keys, embedded in their own
67 anonymous array:
68
69 [ \%h1 => ( 'x', 'y' ) ], [ \%h2 => ( 'u', 'v' ) ]
70
71 Keys which are not explicitly identified are ignored.
72
73 Errors
74
75 Error bars must be taken into account when determining limits; care is
76 especially needed if the data are to be transformed before plotting
77 (for logarithmic plots, for example). Errors may be symmetric (a
78 single value indicates the negative and positive going errors for a
79 data point) or asymmetric (two values are required to specify the
80 errors).
81
82 If the data set is specified as an array of vectors, vectors with
83 errors should be embedded in an array. For symmetric errors, the error
84 is given as a single vector (ndarray or scalar); for asymmetric errors,
85 there should be two values (one of which may be "undef" to indicate a
86 one-sided error bar):
87
88 @ds1 = ( $x, # no errors
89 [ $y, $yerr ], # symmetric errors
90 [ $z, $zn, $zp ], # asymmetric errors
91 [ $u, undef, $up ], # one-sided error bar
92 [ $v, $vn, undef ], # one-sided error bar
93 );
94
95 If the data set is specified as a hash of vectors, the names of the
96 error bar keys are appended to the names of the data keys in the
97 "VecKeys" designations. The error bar key names are always prefixed
98 with a character indicating what kind of error they represent:
99
100 < negative going errors
101 > positive going errors
102 = symmetric errors
103
104 (Column names may be separated by commas or white space.)
105
106 For example,
107
108 %ds1 = ( x => $x, xerr => $xerr, y => $y, yerr => $yerr );
109 limits( [ \%ds1 ], { VecKeys => [ 'x =xerr', 'y =yerr' ] } );
110
111 To specify asymmetric errors, specify both the negative and positive
112 going errors:
113
114 %ds1 = ( x => $x, xnerr => $xn, xperr => $xp,
115 y => $y );
116 limits( [ \%ds1 ], { VecKeys => [ 'x <xnerr >xperr', 'y' ] } );
117
118 For one-sided error bars, specify a column just for the side to be
119 plotted:
120
121 %ds1 = ( x => $x, xnerr => $xn,
122 y => $y, yperr => $yp );
123 limits( [ \%ds1 ], { VecKeys => [ 'x <xnerr', 'y >yperr' ] } );
124
125 Data in hashes with different keys follow the same paradigm:
126
127 [ \%h1 => ( 'x =xerr', 'y =yerr' ) ], [ \%h2 => ( 'u =uerr', 'v =verr' ) ]
128
129 In this case, the column names specific to a single data set override
130 those specified via the "VecKeys" option.
131
132 limits( [ \%h1 => 'x =xerr' ], { VecKeys => [ 'x <xn >xp' ] } )
133
134 In the case of a multi-dimensional data set, one must specify all of
135 the keys:
136
137 limits( [ \%h1 => ( 'x =xerr', 'y =yerr' ) ],
138 { VecKeys => [ 'x <xn >xp', 'y <yp >yp' ] } )
139
140 One can override only parts of the specifications:
141
142 limits( [ \%h1 => ( '=xerr', '=yerr' ) ],
143 { VecKeys => [ 'x <xn >xp', 'y <yp >yp' ] } )
144
145 Use "undef" as a placeholder for those keys for which nothing need by
146 overridden:
147
148 limits( [ \%h1 => undef, 'y =yerr' ],
149 { VecKeys => [ 'x <xn >xp', 'y <yp >yp' ] } )
150
151 Data Transformation
152
153 Normally the data passed to limits should be in their final,
154 transformed, form. For example, if the data will be displayed on a
155 logarithmic scale, the logarithm of the data should be passed to
156 limits. However, if error bars are also to be displayed, the
157 untransformed data must be passed, as
158
159 log(data) + log(error) != log(data + error)
160
161 Since the ranges must be calculated for the transformed values, range
162 must be given the transformation function.
163
164 If all of the data sets will undergo the same transformation, this may
165 be done with the Trans attribute, which is given a list of subroutine
166 references, one for each element of a data set. An "undef" value may
167 be used to indicate no transformation is to be performed. For example,
168
169 @ds1 = ( $x, $y );
170
171 # take log of $x
172 limits( \@ds1, { trans => [ \&log10 ] } );
173
174 # take log of $y
175 limits( \@ds1, { trans => [ undef, \&log10 ] } );
176
177 If each data set has a different transformation, things are a bit more
178 complicated. If the data sets are specified as arrays of vectors,
179 vectors with transformations should be embedded in an array, with the
180 last element the subroutine reference:
181
182 @ds1 = ( [ $x, \&log10 ], $y );
183
184 With error bars, this looks like this:
185
186 @ds1 = ( [ $x, $xerr, \&log10 ], $y );
187 @ds1 = ( [ $x, $xn, $xp, \&log10 ], $y );
188
189 If the "Trans" attribute is used in conjunction with individual data
190 set transformations, the latter will override it. To explicitly
191 indicate that a specific data set element has no transformation
192 (normally only needed if "Trans" is used to specify a default) set the
193 transformation subroutine reference to "undef". In this case, the
194 entire quad of data element, negative error, positive error, and
195 transformation subroutine must be specified to avoid confusion:
196
197 [ $x, $xn, $xp, undef ]
198
199 Note that $xn and $xp may be undef. For symmetric errors, simply set
200 both $xn and $xp to the same value.
201
202 For data sets passed as hashes, the subroutine reference is an element
203 in the hashes; the name of the corresponding key is added to the list
204 of keys, preceded by the "&" character:
205
206 %ds1 = ( x => $x, xerr => $xerr, xtrans => \&log10,
207 y => $y, yerr => $yerr );
208
209 limits( [ \%ds1, \%ds2 ],
210 { VecKeys => [ 'x =xerr &xtrans', 'y =yerr' ] });
211 limits( [ \%ds1 => 'x =xerr &xtrans', 'y =yerr' ] );
212
213 If the "Trans" attribute is specified, and a key name is also specified
214 via the "VecKeys" attribute or individually for a data set element, the
215 latter will take precedence. For example,
216
217 $ds1{trans1} = \&log10;
218 $ds1{trans2} = \&sqrt;
219
220 # resolves to exp
221 limits( [ \%ds1 ], { Trans => [ \&exp ] });
222
223 # resolves to sqrt
224 limits( [ \%ds1 ], { Trans => [ \&exp ],
225 VecKeys => [ 'x =xerr &trans2' ] });
226
227 # resolves to log10
228 limits( [ \%ds1 => '&trans1' ], { Trans => [ \&exp ],
229 VecKeys => [ 'x =xerr &trans2' ] });
230
231 To indicate that a particular vector should have no transformation, use
232 a blank key:
233
234 limits( [ \%ds1 => ( 'x =xerr &', 'y =yerr' ) ], [\%ds2],
235 { Trans => [ \&log10 ] } );
236
237 or set the hash element to "undef":
238
239 $ds1{xtrans} = undef;
240
241 Range Algorithms
242
243 Sometimes all you want is to find the minimum and maximum values.
244 However, for display purposes, it's often nice to have "clean" range
245 bounds. To that end, limits produces a range in two steps. First it
246 determines the bounds, then it cleans them up.
247
248 To specify the bounding algorithm, set the value of the "Bounds" key in
249 the %attr hash to one of the following values:
250
251 MinMax This indicates the raw minima and maxima should be used. This
252 is the default.
253
254 Zscale This is valid for two dimensional data only. The "Y" values
255 are sorted, then fit to a line. The minimum and maximum values
256 of the evaluated line are used for the "Y" bounds; the raw
257 minimum and maximum values of the "X" data are used for the "X"
258 bounds. This method is good in situations where there are
259 "spurious" spikes in the "Y" data which would generate too
260 large a dynamic range in the bounds. (Note that the "Zscale"
261 algorithm is found in IRAF and DS9; its true origin is unknown
262 to the author).
263
264 To specify the cleaning algorithm, set the value of the "Clean" key in
265 the %attr hash to one of the following values:
266
267 None Perform no cleaning of the bounds.
268
269 RangeFrac
270 This is based upon the "PGPLOT" pgrnge function. It
271 symmetrically expands the bounds (determined above) by a
272 fractional amount:
273
274 $expand = $frac * ( $axis->{max} - $axis->{min} );
275 $min = $axis->{min} - $expand;
276 $max = $axis->{max} + $expand;
277
278 The fraction may be specified in the %attr hash with the
279 "RangeFrac" key. It defaults to 0.05.
280
281 Because this is a symmetric expansion, a limit of 0.0 may be
282 transformed into a negative number, which may be inappropriate.
283 If the "ZeroFix" key is set to a non-zero value in the %attr
284 hash, the cleaned boundary is set to 0.0 if it is on the other
285 side of 0.0 from the above determined bounds. For example, If
286 the minimum boundary value is 0.1, and the cleaned boundary
287 value is -0.1, the cleaned value will be set to 0.0.
288 Similarly, if the maximum value is -0.1 and the cleaned value
289 is 0.1, it will be set to 0.0.
290
291 This is the default clean algorithm.
292
293 RoundPow
294 This is based upon the "PGPLOT" pgrnd routine. It determines a
295 "nice" value, where "nice" is the closest round number to the
296 boundary value, where a round number is 1, 2, or 5 times a
297 power of 10.
298
299 User Specified Limits
300
301 To fully or partially override the automatically determined limits, use
302 the Limits attribute. These values are used as input to the range
303 algorithms.
304
305 The Limits attribute value may be either an array of arrayrefs, or a
306 hash.
307
308 Arrays
309 The Limits value may be a reference to an array of arrayrefs, one
310 per dimension, which contain the requested limits.
311
312 The dimensions should be ordered in the same way as the datasets.
313 Each arrayref should contain two ordered values, the minimum and
314 maximum limits for that dimension. The limits may have the
315 undefined value if that limit is to be automatically determined.
316 The limits should be transformed (or not) in the same fashion as
317 the data.
318
319 For example, to specify that the second dimension's maximum limit
320 should be fixed at a specified value:
321
322 Limits => [ [ undef, undef ], [ undef, $max ] ]
323
324 Note that placeholder values are required for leading dimensions
325 which are to be handled automatically. For convenience, if limits
326 for a dimension are to be fully automatically determined, the
327 placeholder arrayref may be empty. Also, trailing undefined limits
328 may be omitted. The above example may be rewritten as:
329
330 Limits => [ [], [ undef, $max ] ]
331
332 If the minimum value was specified instead of the maximum, the
333 following would be acceptable:
334
335 Limits => [ [], [ $min ] ]
336
337 If the data has but a single dimension, nested arrayrefs are not
338 required:
339
340 Limits => [ $min, $max ]
341
342 Hashes
343 Th Limits attribute value may be a hash; this can only be used in
344 conjunction with the VecKeys attribute. If the data sets are
345 represented by hashes which do not have common keys, then the user
346 defined limits should be specified with arrays. The keys in the
347 Limits hash should be the names of the data vectors in the VecKeys.
348 Their values should be hashes with keys "min" and "max",
349 representing the minimum and maximum limits. Limits which have the
350 value "undef" or which are not specified will be determined from
351 the data. For example,
352
353 Limits => { x => { min => 30 }, y => { max => 22 } }
354
355 Return Values
356
357 When called in a list context, it returns the minimum and maximum
358 bounds for each axis:
359
360 @limits = ( $min_1, $max_1, $min_2, $max_2, ... );
361
362 which makes life easier when using the env method:
363
364 $window->env( @limits );
365
366 When called in a scalar context, it returns a hashref with the keys
367
368 axis1, ... axisN
369
370 where "axisN" is the name of the Nth axis. If axis names have not been
371 specified via the "VecKeys" element of %attr, names are concocted as
372 "q1", "q2", etc. The values are hashes with keys "min" and "max". For
373 example:
374
375 { q1 => { min => 1, max => 2},
376 q2 => { min => -33, max => 33 } }
377
378 Miscellaneous
379
380 Normally limits complains if hash data sets don't contain specific keys
381 for error bars or transformation functions. If, however, you'd like to
382 specify default values using the %attr argument, but there are data
383 sets which don't have the data and you'd rather not have to explicitly
384 indicate that, set the "KeyCroak" attribute to zero. For example,
385
386 limits( [ { x => $x }, { x => $x1, xerr => $xerr } ],
387 { VecKeys => [ 'x =xerr' ] } );
388
389 will generate an error because the first data set does not have an
390 "xerr" key. Resetting "KeyCroak" will fix this:
391
392 limits( [ { x => $x }, { x => $x1, xerr => $xerr } ],
393 { VecKeys => [ 'x =xerr' ], KeyCroak => 0 } );
394
396 Diab Jerius, <djerius@cpan.org>
397
399 Copyright (C) 2004 by the Smithsonian Astrophysical Observatory
400
401 This software is released under the GNU General Public License. You
402 may find a copy at <http://www.fsf.org/copyleft/gpl.html>.
403
404
405
406perl v5.38.0 2023-07-21 Limits(3)