File: quadmesh.py

package info (click to toggle)
python-scipy 0.5.2-0.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 33,888 kB
  • ctags: 44,231
  • sloc: ansic: 156,256; cpp: 90,347; python: 89,604; fortran: 73,083; sh: 1,318; objc: 424; makefile: 342
file content (367 lines) | stat: -rw-r--r-- 15,387 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
## Automatically adapted for scipy Oct 31, 2005 by

# Copyright (c) 1996, 1997, The Regents of the University of California.
# All rights reserved.  See Legal.htm for full text and disclaimer.

# The following is so I know about arrays:
from scipy import *
from numpy.core.umath import *
from shapetest import *
from graftypes import *
from gistfuncs import *
from numpy import *
from gist import *

class QuadMesh :
    """This class is for Gist and possibly other graphics packages;
    it creates a class consisting of a QuadMesh, which can then
    be given to and plotted by a graph2d object.

    q = QuadMesh ( <keyword arguments> ) will create a QuadMesh
    object. The keyword arguments are:
    y and x, matching two-dimensional sequences of floating point
      values. These arguments are required and give the coordinates of
      the nodes of the mesh.
      --OR--
      x, y, and z can also be given as one-dimensional and
      of equal lengths. (In this case, all three arguments are
      required.) Then this will be assumed to be a random
      distribution of points (x, y) and values z on those points.
      In this case, a regular QuadMesh will be created, with nx
      equally spaced x's and ny equally spaced y's, with an nx
      by ny array of z's interpolated from the originals by
      Hardy's multiquadric fit. nx and ny can be specified by
      keyword values, lacking which they will be determined from
      ireg (if it is present), otherwise they will be defaulted
      to 50. xmax, xmin, ymax, and ymin for the new mesh may
      be specified by the corresponding keywords, or otherwise will
      by default be created by the maxima and minima of the variables
      x and y.
    ireg, optional two-dimensional sequence of integer values with
      the same dimensions as x and y, giving positive region numbers
      for the cells of the mesh, zero where the mesh does not exist.
      the first row and column of ireg are always zero, since there
      are one fewer cells in each direction than there are nodes.
    boundary = 0/1 0: plot entire mesh; 1: plot only the boundary of
      the selected region. if ktype and ltype are not "none",
      then the boundary will be plotted, then the k and l lines
      with their own types.
    boundary_type, boundary_color: these matter only if boundary = 1,
      and tell how the boundary will be plotted and what its color
      will be.
    region = n if n = 0, plot entire mesh; if any other number, plot
      the region specified (according to the settings in ireg).
    regions: "all" or a number or a list of numbers. Gives which
      regions to plot. If absent, defaults to [region], or "all"
      if region is 0. If present, and region is present also, then
      region is ignored.
    inhibit = 0/1/2 1: do not plot the (x [, j], y [, j]) lines;
      2: do not plot the (x [i, ], y[i, ]) lines.
    tri, optional two-dimensional sequence of values with
      the same dimensions as ireg, triangulation array used for
      contour plotting.
    z = optional two-dimensional sequence of floating point
      values. (Unless x and y are one-dimensional, in which case it
      must be present and match them in size. See above under x and y.)
      z has the same shape as x and y. If z is present, the
      contours of z will be plotted (default: 8 contours unless
      levels specifies otherwise), or a filled mesh will be
      plotted if filled = 1. In the latter case, z may be one
      smaller than x and y in each direction, and represents
      a zone-centered quantity.
    levels = optional one-dimensional sequence of floating point
      values. If present, a list of the values of z at which you
      want contours.
    filled = 0/1 If 1, plot a filled mesh using the values of z.
      If z is not present, the mesh zones will be filled with the
      background color, which allows plotting of a wire frame.
    contours = 0/1 only pertinent when filled = 1; if contours ia
      also 1, then will draw contours as specified by type, width,
      color, and levels.
    edges, if nonzero when filled=1, draw a solid edge around
      each zone.
    ecolor, ewidth--the color and width of the mesh lines when
      filled = 1 and adges is nonzero.
    vx, vy optional two-dimensional sequences of floating point
      values. Has the same shape as x and y. If present, represents
      a vector field to be plotted on the mesh.
    scale = floating point value. When plotting a vector field,
      a conversion factor from the units of (vx, vy) to the
      units of (x, y).
    z_scale = specifies "log", "lin", or "normal" for how z is to be plotted.
    ktype, ltype: can have the same values as type, and allow the
      k and l mesh lines to be plotted differently.
    #### eventually, we can add kcolor, lcolor, kwidth, lwidth ####
    type, color, width, label, hide, marks, marker as for
      curves.
    """

    def type (self) :
        return QuadMeshType

    _QuadMeshSpecError = "QuadMeshSpecError"

    def __init__ ( self , * kwds , ** keywords ) :
        if len (kwds) == 1 :
            keywords = kwds[0]
        if not keywords.has_key ("x") or not keywords.has_key ("y") :
            raise self._QuadMeshSpecError , \
               "A QuadMesh requires both x and y keywords."
        self.x = keywords ["x"]
        self.y = keywords ["y"]
        if len (self.x.shape) == 2 :
            self.dimsofx = 2
            if self.x.shape != self.y.shape :
                raise self._QuadMeshSpecError , \
                   "x and y must have the same shape."
            self.nx = self.x.shape [0]
            self.ny = self.x.shape [1]
        elif len (self.x.shape) == len (self.y.shape) == 1:
            self.dimsofx = 1
            if len (x) != len (y) :
                raise self._QuadMeshSpecError , \
                   "If x and y are one dimensional, their lengths must agree."
            if keywords.has_key ("nx") :
                nx = keywords ["nx"]
            else :
                nx = None
            if keywords.has_key ("ny") :
                ny = keywords ["ny"]
            else :
                ny = None
            if keywords.has_key ("xmax") :
                xmax = keywords ["xmax"]
            else :
                xmax = max (x)
            if keywords.has_key ("ymax") :
                ymax = keywords ["ymax"]
            else :
                ymax = max (y)
            if keywords.has_key ("xmin") :
                xmin = keywords ["xmin"]
            else :
                xmin = min (x)
            if keywords.has_key ("ymin") :
                ymin = keywords ["ymin"]
            else :
                ymin = min (y)
            if keywords.has_key ("rsq") :
                rsq = keywords ["rsq"]
            else :
                rsq = 4. * (xmax - xmin) * (ymax - ymin) / len (x)
        else :
            raise self._QuadMeshSpecError , \
               "can't handle x (shape " + `self.x.shape` + ") and y " + \
               "(shape " + `self.y.shape` + "."
        if keywords.has_key ("boundary") :
            self.boundary = keywords ["boundary"]
        else :
            self.boundary = 0
        if keywords.has_key ("boundary_type") :
            self.boundary_type = keywords ["boundary_type"]
        else :
            self.boundary_type = "solid"
        if keywords.has_key ("boundary_color") :
            self.boundary_color = keywords ["boundary_color"]
        else :
            self.boundary_color = "fg"
        if keywords.has_key ("inhibit") :
            self.inhibit = keywords ["inhibit"]
        else :
            self.inhibit = 0
        if keywords.has_key ("label") :
            self.label = keywords ["label"]
        else :
            self.label = " "
        if keywords.has_key ("hide") :
            self.hide = keywords ["hide"]
        else :
            self.hide = 0
        if self.boundary == 1 :
            self.ktype = self.ltype = "none"
        else :
            self.ktype = self.ltype = "solid"
        if keywords.has_key ("type") :
            self.line_type = keywords ["type"]
        else :
            self.line_type = "solid"
        if keywords.has_key ("ktype") :
            self.ktype = keywords ["ktype"]
        if keywords.has_key ("ltype") :
            self.ltype = keywords ["ltype"]
        if keywords.has_key ("width") :
            self.width = keywords ["width"]
        else :
            self.width = 1
        if keywords.has_key ("color") :
            self.color = keywords ["color"]
        else :
            self.color = "fg"
        if keywords.has_key ("region") :
            self.region = keywords ["region"]
        else :
            self.region = 0
        if keywords.has_key ("tri") :
            self.tri = keywords ["tri"]
            if shape (tri) != shape (x) :
                raise self._QuadMeshSpecError , \
                   "tri, x, and y must have the same shape."
        else :
            n1 = shape (self.x) [0]
            n2 = shape (self.x) [1]
            self.tri = zeros ( (n1, n2))
        if keywords.has_key ("ireg") and keywords ["ireg"] is not None :
            self.ireg = keywords ["ireg"]
            if self.dimsofx == 2 :
                if self.ireg.shape != self.x.shape :
                    raise self._QuadMeshSpecError , \
                       "ireg, x, and y must have the same shape."
            else: # dimsofx has to be 1
                if self.nx is None :
                    self.nx = self.ireg.shape [0]
                if self.ny is None :
                    self.ny = self.ireg.shape [1]
                if self.ireg.shape != (nx, ny) :
                    raise self._QuadMeshSpecError , \
                       "shape of ireg must be nx by ny."
        else :
            if self.dimsofx == 2:
                self.ireg = array (self.x).astype (Int)
            else :
                if self.nx is None :
                    self.nx = 50
                if self.ny is None :
                    self.ny = 50
                self.ireg = array ( (self.nx, self.ny), Int)
            self.ireg [0:self.nx, 0] = 0
            self.ireg [0, 0:self.ny] = 0
            self.ireg [1:self.nx, 1:self.ny] = 1
        if keywords.has_key ("filled") :
            self.filled = keywords ["filled"]
        else :
            self.filled = 0
        if keywords.has_key ("edges") :
            self.edges = keywords ["edges"]
        else :
            self.edges = 0
        if keywords.has_key ("contours") :
            self.contours = keywords ["contours"]
        elif self.filled == 0 and self.edges == 0 :
            self.contours = 1
        else :
            self.contours = 0
        if keywords.has_key ("ewidth") :
            self.ewidth = keywords ["ewidth"]
        else :
            self.ewidth = 1
        if keywords.has_key ("ecolor") :
            self.ecolor = keywords ["ecolor"]
        else :
            self.ecolor = "fg"
        if keywords.has_key ("levels") :
            self.levels = keywords ["levels"]
        else :
            self.levels = None
        if keywords.has_key ("z") :
            self.z = keywords ["z"]
        else :
            self.z = None
        if keywords.has_key ("z_scale") and keywords ["z_scale"] is not None :
            self.z_scale = keywords ["z_scale"]
        else :
            self.z_scale = "lin"
        if self.dimsofx == 1 :
            if self.z is None or len (self.z.shape) != 1 \
               or len (self.z) != len (self.x) :
                raise self._QuadMeshSpecError , \
                   "If x and y are one-dimensional, " + \
                   "then z must be too, and must be the same length."
            # Compute regular mesh and interpolated values
            dx = (xmax - xmin) / nx
            dy = (ymax - ymin) / ny
            xcplot = span (xmin, xmax - dx, nx)
            ycplot = span (ymin, ymax - dy, ny)
            del xmin, xmax, ymin, ymax, dx, dy
            xt = subtract.outer (self.x, self.x)
            yt = subtract.outer (self.y, self.y)
            aa = sqrt (xt * xt + yt * yt + rsq)
            del xt, yt
            alpha = array (self.z, copy = 1)
            alpha = solve_linear_equations (aa, alpha)
            self.z = mfit (alpha, self.x, xcplot, self.y,
               ycplot, rsq)
            del aa, alpha, rsq
            # Expand coordinates to 2d arrays to match zcplot
            self.x = multiply.outer (xcplot, ones (ny, Float))
            self.y = multiply.outer (ones (nx, Float), ycplot)
            del xcplot, ycplot, nx, ny
        if self.dimsofx == 2 and self.z is not None : # check for shape
            if self.filled == 0 :
                if self.z.shape != self.x.shape :
                    raise self._QuadMeshSpecError , \
                       "z, x, and y must be the same shape."
            else :
                n1 = self.z.shape [0]
                n2 = self.z.shape [1]
                m1 = self.x.shape [0]
                m2 = self.x.shape [1]
                if n1 == m1 and n2 == m2 or n1 == m1 - 1 and n2 == m2 - 1 :
                    pass
                else :
                    raise self._QuadMeshSpecError , \
                       "z, x, and y must be the same shape, or z one smaller" + \
                       " in each dimension."
        if keywords.has_key ("vx") and not is_scalar (keywords ["vx"]) and \
           len (keywords ["vx"]) > 0 :
            if not keywords.has_key ("vy") :
                raise self._QuadMeshSpecError , \
                   "vx and vy must both be present."
            self.vx = keywords ["vx"]
            self.vy = keywords ["vy"]
        else :
            self.vx = None
            self.vy = None
        if keywords.has_key ("scale") :
            self.scale = keywords ["scale"]
        else :
            self.scale = None
        if keywords.has_key ("marks") :
            self.marks = keywords ["marks"]
        else :
            self.marks = 0
        if keywords.has_key ( "marker" ) :
            self.marker = keywords [ "marker" ]
        else :
            self.marker = "unspecified"
        if keywords.has_key ( "regions" ) :
            self.regions = keywords ["regions"]
            if is_scalar (self.regions) and self.regions != "all" :
                self.regions = [self.regions]
        else :
            if self.region == 0 :
                self.regions = "all"
            else:
                self.regions = [self.region]

    def new ( self, ** keywords ) :
        """ new (...keyword arguments...) allows you to reuse a
        previously existing quadmesh.
        """
        self.__init__ ( keywords )

    def set ( self , ** keywords ) :
        """ set (...keyword arguments...) allows you to set individual
        quadmesh characteristics. Very little error checking is done.
        """
        # The following allopws vx and vy to be cleared by sending in []
        if keywords.has_key ("vx") :
            self.vx = keywords ["vx"]
            del keywords ["vx"]
        if keywords.has_key ("vy") :
            self.vy = keywords ["vy"]
            del keywords ["vy"]
        for k in keywords.keys ():
            if k == "type" :
                self.line_type = keywords ["type"]
            else :
                setattr (self, k, keywords [k])