~ubuntu-branches/ubuntu/saucy/python-scipy/saucy

« back to all changes in this revision

Viewing changes to Lib/sandbox/xplt/quadmesh.py

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik
  • Date: 2008-06-16 22:58:01 UTC
  • mfrom: (2.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080616225801-irdhrpcwiocfbcmt
Tags: 0.6.0-12
* The description updated to match the current SciPy (Closes: #489149).
* Standards-Version bumped to 3.8.0 (no action needed)
* Build-Depends: netcdf-dev changed to libnetcdf-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
## Automatically adapted for scipy Oct 31, 2005 by
2
 
 
3
 
# Copyright (c) 1996, 1997, The Regents of the University of California.
4
 
# All rights reserved.  See Legal.htm for full text and disclaimer.
5
 
 
6
 
# The following is so I know about arrays:
7
 
from scipy import *
8
 
from numpy.core.umath import *
9
 
from shapetest import *
10
 
from graftypes import *
11
 
from gistfuncs import *
12
 
from numpy import *
13
 
from gist import *
14
 
 
15
 
class QuadMesh :
16
 
    """This class is for Gist and possibly other graphics packages;
17
 
    it creates a class consisting of a QuadMesh, which can then
18
 
    be given to and plotted by a graph2d object.
19
 
 
20
 
    q = QuadMesh ( <keyword arguments> ) will create a QuadMesh
21
 
    object. The keyword arguments are:
22
 
    y and x, matching two-dimensional sequences of floating point
23
 
      values. These arguments are required and give the coordinates of
24
 
      the nodes of the mesh.
25
 
      --OR--
26
 
      x, y, and z can also be given as one-dimensional and
27
 
      of equal lengths. (In this case, all three arguments are
28
 
      required.) Then this will be assumed to be a random
29
 
      distribution of points (x, y) and values z on those points.
30
 
      In this case, a regular QuadMesh will be created, with nx
31
 
      equally spaced x's and ny equally spaced y's, with an nx
32
 
      by ny array of z's interpolated from the originals by
33
 
      Hardy's multiquadric fit. nx and ny can be specified by
34
 
      keyword values, lacking which they will be determined from
35
 
      ireg (if it is present), otherwise they will be defaulted
36
 
      to 50. xmax, xmin, ymax, and ymin for the new mesh may
37
 
      be specified by the corresponding keywords, or otherwise will
38
 
      by default be created by the maxima and minima of the variables
39
 
      x and y.
40
 
    ireg, optional two-dimensional sequence of integer values with
41
 
      the same dimensions as x and y, giving positive region numbers
42
 
      for the cells of the mesh, zero where the mesh does not exist.
43
 
      the first row and column of ireg are always zero, since there
44
 
      are one fewer cells in each direction than there are nodes.
45
 
    boundary = 0/1 0: plot entire mesh; 1: plot only the boundary of
46
 
      the selected region. if ktype and ltype are not "none",
47
 
      then the boundary will be plotted, then the k and l lines
48
 
      with their own types.
49
 
    boundary_type, boundary_color: these matter only if boundary = 1,
50
 
      and tell how the boundary will be plotted and what its color
51
 
      will be.
52
 
    region = n if n = 0, plot entire mesh; if any other number, plot
53
 
      the region specified (according to the settings in ireg).
54
 
    regions: "all" or a number or a list of numbers. Gives which
55
 
      regions to plot. If absent, defaults to [region], or "all"
56
 
      if region is 0. If present, and region is present also, then
57
 
      region is ignored.
58
 
    inhibit = 0/1/2 1: do not plot the (x [, j], y [, j]) lines;
59
 
      2: do not plot the (x [i, ], y[i, ]) lines.
60
 
    tri, optional two-dimensional sequence of values with
61
 
      the same dimensions as ireg, triangulation array used for
62
 
      contour plotting.
63
 
    z = optional two-dimensional sequence of floating point
64
 
      values. (Unless x and y are one-dimensional, in which case it
65
 
      must be present and match them in size. See above under x and y.)
66
 
      z has the same shape as x and y. If z is present, the
67
 
      contours of z will be plotted (default: 8 contours unless
68
 
      levels specifies otherwise), or a filled mesh will be
69
 
      plotted if filled = 1. In the latter case, z may be one
70
 
      smaller than x and y in each direction, and represents
71
 
      a zone-centered quantity.
72
 
    levels = optional one-dimensional sequence of floating point
73
 
      values. If present, a list of the values of z at which you
74
 
      want contours.
75
 
    filled = 0/1 If 1, plot a filled mesh using the values of z.
76
 
      If z is not present, the mesh zones will be filled with the
77
 
      background color, which allows plotting of a wire frame.
78
 
    contours = 0/1 only pertinent when filled = 1; if contours ia
79
 
      also 1, then will draw contours as specified by type, width,
80
 
      color, and levels.
81
 
    edges, if nonzero when filled=1, draw a solid edge around
82
 
      each zone.
83
 
    ecolor, ewidth--the color and width of the mesh lines when
84
 
      filled = 1 and adges is nonzero.
85
 
    vx, vy optional two-dimensional sequences of floating point
86
 
      values. Has the same shape as x and y. If present, represents
87
 
      a vector field to be plotted on the mesh.
88
 
    scale = floating point value. When plotting a vector field,
89
 
      a conversion factor from the units of (vx, vy) to the
90
 
      units of (x, y).
91
 
    z_scale = specifies "log", "lin", or "normal" for how z is to be plotted.
92
 
    ktype, ltype: can have the same values as type, and allow the
93
 
      k and l mesh lines to be plotted differently.
94
 
    #### eventually, we can add kcolor, lcolor, kwidth, lwidth ####
95
 
    type, color, width, label, hide, marks, marker as for
96
 
      curves.
97
 
    """
98
 
 
99
 
    def type (self) :
100
 
        return QuadMeshType
101
 
 
102
 
    _QuadMeshSpecError = "QuadMeshSpecError"
103
 
 
104
 
    def __init__ ( self , * kwds , ** keywords ) :
105
 
        if len (kwds) == 1 :
106
 
            keywords = kwds[0]
107
 
        if not keywords.has_key ("x") or not keywords.has_key ("y") :
108
 
            raise self._QuadMeshSpecError , \
109
 
               "A QuadMesh requires both x and y keywords."
110
 
        self.x = keywords ["x"]
111
 
        self.y = keywords ["y"]
112
 
        if len (self.x.shape) == 2 :
113
 
            self.dimsofx = 2
114
 
            if self.x.shape != self.y.shape :
115
 
                raise self._QuadMeshSpecError , \
116
 
                   "x and y must have the same shape."
117
 
            self.nx = self.x.shape [0]
118
 
            self.ny = self.x.shape [1]
119
 
        elif len (self.x.shape) == len (self.y.shape) == 1:
120
 
            self.dimsofx = 1
121
 
            if len (x) != len (y) :
122
 
                raise self._QuadMeshSpecError , \
123
 
                   "If x and y are one dimensional, their lengths must agree."
124
 
            if keywords.has_key ("nx") :
125
 
                nx = keywords ["nx"]
126
 
            else :
127
 
                nx = None
128
 
            if keywords.has_key ("ny") :
129
 
                ny = keywords ["ny"]
130
 
            else :
131
 
                ny = None
132
 
            if keywords.has_key ("xmax") :
133
 
                xmax = keywords ["xmax"]
134
 
            else :
135
 
                xmax = max (x)
136
 
            if keywords.has_key ("ymax") :
137
 
                ymax = keywords ["ymax"]
138
 
            else :
139
 
                ymax = max (y)
140
 
            if keywords.has_key ("xmin") :
141
 
                xmin = keywords ["xmin"]
142
 
            else :
143
 
                xmin = min (x)
144
 
            if keywords.has_key ("ymin") :
145
 
                ymin = keywords ["ymin"]
146
 
            else :
147
 
                ymin = min (y)
148
 
            if keywords.has_key ("rsq") :
149
 
                rsq = keywords ["rsq"]
150
 
            else :
151
 
                rsq = 4. * (xmax - xmin) * (ymax - ymin) / len (x)
152
 
        else :
153
 
            raise self._QuadMeshSpecError , \
154
 
               "can't handle x (shape " + `self.x.shape` + ") and y " + \
155
 
               "(shape " + `self.y.shape` + "."
156
 
        if keywords.has_key ("boundary") :
157
 
            self.boundary = keywords ["boundary"]
158
 
        else :
159
 
            self.boundary = 0
160
 
        if keywords.has_key ("boundary_type") :
161
 
            self.boundary_type = keywords ["boundary_type"]
162
 
        else :
163
 
            self.boundary_type = "solid"
164
 
        if keywords.has_key ("boundary_color") :
165
 
            self.boundary_color = keywords ["boundary_color"]
166
 
        else :
167
 
            self.boundary_color = "fg"
168
 
        if keywords.has_key ("inhibit") :
169
 
            self.inhibit = keywords ["inhibit"]
170
 
        else :
171
 
            self.inhibit = 0
172
 
        if keywords.has_key ("label") :
173
 
            self.label = keywords ["label"]
174
 
        else :
175
 
            self.label = " "
176
 
        if keywords.has_key ("hide") :
177
 
            self.hide = keywords ["hide"]
178
 
        else :
179
 
            self.hide = 0
180
 
        if self.boundary == 1 :
181
 
            self.ktype = self.ltype = "none"
182
 
        else :
183
 
            self.ktype = self.ltype = "solid"
184
 
        if keywords.has_key ("type") :
185
 
            self.line_type = keywords ["type"]
186
 
        else :
187
 
            self.line_type = "solid"
188
 
        if keywords.has_key ("ktype") :
189
 
            self.ktype = keywords ["ktype"]
190
 
        if keywords.has_key ("ltype") :
191
 
            self.ltype = keywords ["ltype"]
192
 
        if keywords.has_key ("width") :
193
 
            self.width = keywords ["width"]
194
 
        else :
195
 
            self.width = 1
196
 
        if keywords.has_key ("color") :
197
 
            self.color = keywords ["color"]
198
 
        else :
199
 
            self.color = "fg"
200
 
        if keywords.has_key ("region") :
201
 
            self.region = keywords ["region"]
202
 
        else :
203
 
            self.region = 0
204
 
        if keywords.has_key ("tri") :
205
 
            self.tri = keywords ["tri"]
206
 
            if shape (tri) != shape (x) :
207
 
                raise self._QuadMeshSpecError , \
208
 
                   "tri, x, and y must have the same shape."
209
 
        else :
210
 
            n1 = shape (self.x) [0]
211
 
            n2 = shape (self.x) [1]
212
 
            self.tri = zeros ( (n1, n2))
213
 
        if keywords.has_key ("ireg") and keywords ["ireg"] is not None :
214
 
            self.ireg = keywords ["ireg"]
215
 
            if self.dimsofx == 2 :
216
 
                if self.ireg.shape != self.x.shape :
217
 
                    raise self._QuadMeshSpecError , \
218
 
                       "ireg, x, and y must have the same shape."
219
 
            else: # dimsofx has to be 1
220
 
                if self.nx is None :
221
 
                    self.nx = self.ireg.shape [0]
222
 
                if self.ny is None :
223
 
                    self.ny = self.ireg.shape [1]
224
 
                if self.ireg.shape != (nx, ny) :
225
 
                    raise self._QuadMeshSpecError , \
226
 
                       "shape of ireg must be nx by ny."
227
 
        else :
228
 
            if self.dimsofx == 2:
229
 
                self.ireg = array (self.x).astype (Int)
230
 
            else :
231
 
                if self.nx is None :
232
 
                    self.nx = 50
233
 
                if self.ny is None :
234
 
                    self.ny = 50
235
 
                self.ireg = array ( (self.nx, self.ny), Int)
236
 
            self.ireg [0:self.nx, 0] = 0
237
 
            self.ireg [0, 0:self.ny] = 0
238
 
            self.ireg [1:self.nx, 1:self.ny] = 1
239
 
        if keywords.has_key ("filled") :
240
 
            self.filled = keywords ["filled"]
241
 
        else :
242
 
            self.filled = 0
243
 
        if keywords.has_key ("edges") :
244
 
            self.edges = keywords ["edges"]
245
 
        else :
246
 
            self.edges = 0
247
 
        if keywords.has_key ("contours") :
248
 
            self.contours = keywords ["contours"]
249
 
        elif self.filled == 0 and self.edges == 0 :
250
 
            self.contours = 1
251
 
        else :
252
 
            self.contours = 0
253
 
        if keywords.has_key ("ewidth") :
254
 
            self.ewidth = keywords ["ewidth"]
255
 
        else :
256
 
            self.ewidth = 1
257
 
        if keywords.has_key ("ecolor") :
258
 
            self.ecolor = keywords ["ecolor"]
259
 
        else :
260
 
            self.ecolor = "fg"
261
 
        if keywords.has_key ("levels") :
262
 
            self.levels = keywords ["levels"]
263
 
        else :
264
 
            self.levels = None
265
 
        if keywords.has_key ("z") :
266
 
            self.z = keywords ["z"]
267
 
        else :
268
 
            self.z = None
269
 
        if keywords.has_key ("z_scale") and keywords ["z_scale"] is not None :
270
 
            self.z_scale = keywords ["z_scale"]
271
 
        else :
272
 
            self.z_scale = "lin"
273
 
        if self.dimsofx == 1 :
274
 
            if self.z is None or len (self.z.shape) != 1 \
275
 
               or len (self.z) != len (self.x) :
276
 
                raise self._QuadMeshSpecError , \
277
 
                   "If x and y are one-dimensional, " + \
278
 
                   "then z must be too, and must be the same length."
279
 
            # Compute regular mesh and interpolated values
280
 
            dx = (xmax - xmin) / nx
281
 
            dy = (ymax - ymin) / ny
282
 
            xcplot = span (xmin, xmax - dx, nx)
283
 
            ycplot = span (ymin, ymax - dy, ny)
284
 
            del xmin, xmax, ymin, ymax, dx, dy
285
 
            xt = subtract.outer (self.x, self.x)
286
 
            yt = subtract.outer (self.y, self.y)
287
 
            aa = sqrt (xt * xt + yt * yt + rsq)
288
 
            del xt, yt
289
 
            alpha = array (self.z, copy = 1)
290
 
            alpha = solve_linear_equations (aa, alpha)
291
 
            self.z = mfit (alpha, self.x, xcplot, self.y,
292
 
               ycplot, rsq)
293
 
            del aa, alpha, rsq
294
 
            # Expand coordinates to 2d arrays to match zcplot
295
 
            self.x = multiply.outer (xcplot, ones (ny, Float))
296
 
            self.y = multiply.outer (ones (nx, Float), ycplot)
297
 
            del xcplot, ycplot, nx, ny
298
 
        if self.dimsofx == 2 and self.z is not None : # check for shape
299
 
            if self.filled == 0 :
300
 
                if self.z.shape != self.x.shape :
301
 
                    raise self._QuadMeshSpecError , \
302
 
                       "z, x, and y must be the same shape."
303
 
            else :
304
 
                n1 = self.z.shape [0]
305
 
                n2 = self.z.shape [1]
306
 
                m1 = self.x.shape [0]
307
 
                m2 = self.x.shape [1]
308
 
                if n1 == m1 and n2 == m2 or n1 == m1 - 1 and n2 == m2 - 1 :
309
 
                    pass
310
 
                else :
311
 
                    raise self._QuadMeshSpecError , \
312
 
                       "z, x, and y must be the same shape, or z one smaller" + \
313
 
                       " in each dimension."
314
 
        if keywords.has_key ("vx") and not is_scalar (keywords ["vx"]) and \
315
 
           len (keywords ["vx"]) > 0 :
316
 
            if not keywords.has_key ("vy") :
317
 
                raise self._QuadMeshSpecError , \
318
 
                   "vx and vy must both be present."
319
 
            self.vx = keywords ["vx"]
320
 
            self.vy = keywords ["vy"]
321
 
        else :
322
 
            self.vx = None
323
 
            self.vy = None
324
 
        if keywords.has_key ("scale") :
325
 
            self.scale = keywords ["scale"]
326
 
        else :
327
 
            self.scale = None
328
 
        if keywords.has_key ("marks") :
329
 
            self.marks = keywords ["marks"]
330
 
        else :
331
 
            self.marks = 0
332
 
        if keywords.has_key ( "marker" ) :
333
 
            self.marker = keywords [ "marker" ]
334
 
        else :
335
 
            self.marker = "unspecified"
336
 
        if keywords.has_key ( "regions" ) :
337
 
            self.regions = keywords ["regions"]
338
 
            if is_scalar (self.regions) and self.regions != "all" :
339
 
                self.regions = [self.regions]
340
 
        else :
341
 
            if self.region == 0 :
342
 
                self.regions = "all"
343
 
            else:
344
 
                self.regions = [self.region]
345
 
 
346
 
    def new ( self, ** keywords ) :
347
 
        """ new (...keyword arguments...) allows you to reuse a
348
 
        previously existing quadmesh.
349
 
        """
350
 
        self.__init__ ( keywords )
351
 
 
352
 
    def set ( self , ** keywords ) :
353
 
        """ set (...keyword arguments...) allows you to set individual
354
 
        quadmesh characteristics. Very little error checking is done.
355
 
        """
356
 
        # The following allopws vx and vy to be cleared by sending in []
357
 
        if keywords.has_key ("vx") :
358
 
            self.vx = keywords ["vx"]
359
 
            del keywords ["vx"]
360
 
        if keywords.has_key ("vy") :
361
 
            self.vy = keywords ["vy"]
362
 
            del keywords ["vy"]
363
 
        for k in keywords.keys ():
364
 
            if k == "type" :
365
 
                self.line_type = keywords ["type"]
366
 
            else :
367
 
                setattr (self, k, keywords [k])