@@ -3356,124 +3356,131 @@ def newfunc(val, mask, mval):
3356
3356
if opened :
3357
3357
fh .close ()
3358
3358
3359
- def griddata (x ,y ,z ,xi ,yi ,interp = 'nn' ):
3360
- """
3361
- ``zi = griddata(x,y,z,xi,yi)`` fits a surface of the form *z* =
3362
- *f*(*x*, *y*) to the data in the (usually) nonuniformly spaced
3363
- vectors (*x*, *y*, *z*). :func:`griddata` interpolates this
3364
- surface at the points specified by (*xi*, *yi*) to produce
3365
- *zi*. *xi* and *yi* must describe a regular grid, can be either 1D
3366
- or 2D, but must be monotonically increasing.
3367
-
3368
- A masked array is returned if any grid points are outside convex
3369
- hull defined by input data (no extrapolation is done).
3370
-
3371
- If interp keyword is set to '`nn`' (default),
3372
- uses natural neighbor interpolation based on Delaunay
3373
- triangulation. By default, this algorithm is provided by the
3374
- :mod:`matplotlib.delaunay` package, written by Robert Kern. The
3375
- triangulation algorithm in this package is known to fail on some
3376
- nearly pathological cases. For this reason, a separate toolkit
3377
- (:mod:`mpl_tookits.natgrid`) has been created that provides a more
3378
- robust algorithm fof triangulation and interpolation. This
3379
- toolkit is based on the NCAR natgrid library, which contains code
3380
- that is not redistributable under a BSD-compatible license. When
3381
- installed, this function will use the :mod:`mpl_toolkits.natgrid`
3382
- algorithm, otherwise it will use the built-in
3383
- :mod:`matplotlib.delaunay` package.
3384
-
3385
- If the interp keyword is set to '`linear`', then linear interpolation
3386
- is used instead of natural neighbor. In this case, the output grid
3387
- is assumed to be regular with a constant grid spacing in both the x and
3388
- y directions. For regular grids with nonconstant grid spacing, you
3389
- must use natural neighbor interpolation. Linear interpolation is only valid if
3390
- :mod:`matplotlib.delaunay` package is used - :mod:`mpl_tookits.natgrid`
3391
- only provides natural neighbor interpolation.
3392
-
3393
- The natgrid matplotlib toolkit can be downloaded from
3394
- http://sourceforge.net/project/showfiles.php?group_id=80706&package_id=142792
3395
- """
3396
- try :
3397
- from mpl_toolkits .natgrid import _natgrid , __version__
3398
- _use_natgrid = True
3399
- except ImportError :
3400
- import matplotlib .delaunay as delaunay
3401
- from matplotlib .delaunay import __version__
3402
- _use_natgrid = False
3403
- if not griddata ._reported :
3404
- if _use_natgrid :
3405
- verbose .report ('using natgrid version %s' % __version__ )
3406
- else :
3407
- verbose .report ('using delaunay version %s' % __version__ )
3408
- griddata ._reported = True
3359
+
3360
+ def griddata (x , y , z , xi , yi , interp = 'nn' ):
3361
+ """Interpolates from a nonuniformly spaced grid to some other
3362
+ grid.
3363
+
3364
+ Fits a surface of the form z = f(`x`, `y`) to the data in the
3365
+ (usually) nonuniformly spaced vectors (`x`, `y`, `z`), then
3366
+ interpolates this surface at the points specified by
3367
+ (`xi`, `yi`) to produce `zi`.
3368
+
3369
+ Parameters
3370
+ ----------
3371
+ x, y, z : 1d array_like
3372
+ Coordinates of grid points to interpolate from.
3373
+ xi, yi : 1d or 2d array_like
3374
+ Coordinates of grid points to interpolate to.
3375
+ interp : string key from {'nn', 'linear'}
3376
+ Interpolation algorithm, either 'nn' for natural neighbor, or
3377
+ 'linear' for linear interpolation.
3378
+
3379
+ Returns
3380
+ -------
3381
+ 2d float array
3382
+ Array of values interpolated at (`xi`, `yi`) points. Array
3383
+ will be masked is any of (`xi`, `yi`) are outside the convex
3384
+ hull of (`x`, `y`).
3385
+
3386
+ Notes
3387
+ -----
3388
+ If `interp` is 'nn' (the default), uses natural neighbor
3389
+ interpolation based on Delaunay triangulation. This option is
3390
+ only available if the mpl_toolkits.natgrid module is installed.
3391
+ This can be downloaded from https://github.com/matplotlib/natgrid.
3392
+ The (`xi`, `yi`) grid must be regular and monotonically increasing
3393
+ in this case.
3394
+
3395
+ If `interp` is 'linear', linear interpolation is used via
3396
+ matplotlib.tri.LinearTriInterpolator.
3397
+
3398
+ Instead of using `griddata`, more flexible functionality and other
3399
+ interpolation options are available using a
3400
+ matplotlib.tri.Triangulation and a matplotlib.tri.TriInterpolator.
3401
+ """
3402
+ # Check input arguments.
3403
+ x = np .asanyarray (x , dtype = np .float64 )
3404
+ y = np .asanyarray (y , dtype = np .float64 )
3405
+ z = np .asanyarray (z , dtype = np .float64 )
3406
+ if x .shape != y .shape or x .shape != z .shape or x .ndim != 1 :
3407
+ raise ValueError ("x, y and z must be equal-length 1-D arrays" )
3408
+
3409
+ xi = np .asanyarray (xi , dtype = np .float64 )
3410
+ yi = np .asanyarray (yi , dtype = np .float64 )
3409
3411
if xi .ndim != yi .ndim :
3410
- raise TypeError ("inputs xi and yi must have same number of dimensions (1 or 2)" )
3411
- if xi .ndim != 1 and xi .ndim != 2 :
3412
- raise TypeError ("inputs xi and yi must be 1D or 2D." )
3413
- if not len (x )== len (y )== len (z ):
3414
- raise TypeError ("inputs x,y,z must all be 1D arrays of the same length" )
3415
- # remove masked points.
3416
- if hasattr (z ,'mask' ):
3417
- # make sure mask is not a scalar boolean array.
3418
- if z .mask .ndim :
3419
- x = x .compress (z .mask == False )
3420
- y = y .compress (z .mask == False )
3421
- z = z .compressed ()
3422
- if _use_natgrid : # use natgrid toolkit if available.
3423
- if interp != 'nn' :
3424
- raise ValueError ("only natural neighor interpolation"
3425
- " allowed when using natgrid toolkit in griddata." )
3412
+ raise ValueError ("xi and yi must be arrays with the same number of "
3413
+ "dimensions (1 or 2)" )
3414
+ if xi .ndim == 2 and xi .shape != yi .shape :
3415
+ raise ValueError ("if xi and yi are 2D arrays, they must have the same "
3416
+ "shape" )
3417
+ if xi .ndim == 1 :
3418
+ xi , yi = np .meshgrid (xi , yi )
3419
+
3420
+ if interp == 'nn' :
3421
+ use_nn_interpolation = True
3422
+ elif interp == 'linear' :
3423
+ use_nn_interpolation = False
3424
+ else :
3425
+ raise ValueError ("interp keyword must be one of 'linear' (for linear "
3426
+ "interpolation) or 'nn' (for natural neighbor "
3427
+ "interpolation). Default is 'nn'." )
3428
+
3429
+ # Remove masked points.
3430
+ mask = np .ma .getmask (z )
3431
+ if not (mask is np .ma .nomask ):
3432
+ x = x .compress (~ mask )
3433
+ y = y .compress (~ mask )
3434
+ z = z .compressed ()
3435
+
3436
+ if use_nn_interpolation :
3437
+ try :
3438
+ from mpl_toolkits .natgrid import _natgrid
3439
+ except ImportError :
3440
+ raise RuntimeError ("To use interp='nn' (Natural Neighbor "
3441
+ "interpolation) in griddata, natgrid must be installed. "
3442
+ "Either install it from http://sourceforge.net/projects/"
3443
+ "matplotlib/files/matplotlib-toolkits, or use interp='linear' "
3444
+ "instead." )
3445
+
3426
3446
if xi .ndim == 2 :
3427
- xi = xi [0 ,:]
3428
- yi = yi [:,0 ]
3429
- # override default natgrid internal parameters.
3430
- _natgrid .seti ('ext' ,0 )
3431
- _natgrid .setr ('nul' ,np .nan )
3432
- # cast input arrays to doubles (this makes a copy)
3433
- x = x .astype (np .float )
3434
- y = y .astype (np .float )
3435
- z = z .astype (np .float )
3436
- xo = xi .astype (np .float )
3437
- yo = yi .astype (np .float )
3438
- if min (xo [1 :]- xo [0 :- 1 ]) < 0 or min (yo [1 :]- yo [0 :- 1 ]) < 0 :
3439
- raise ValueError ('output grid defined by xi,yi must be monotone increasing' )
3440
- # allocate array for output (buffer will be overwritten by nagridd)
3441
- zo = np .empty ((yo .shape [0 ],xo .shape [0 ]), np .float )
3442
- _natgrid .natgridd (x ,y ,z ,xo ,yo ,zo )
3443
- else : # use Robert Kern's delaunay package from scikits (default)
3444
- if xi .ndim != yi .ndim :
3445
- raise TypeError ("inputs xi and yi must have same number of dimensions (1 or 2)" )
3446
- if xi .ndim != 1 and xi .ndim != 2 :
3447
- raise TypeError ("inputs xi and yi must be 1D or 2D." )
3448
- if xi .ndim == 1 :
3449
- xi ,yi = np .meshgrid (xi ,yi )
3450
- # triangulate data
3451
- tri = delaunay .Triangulation (x ,y )
3452
- # interpolate data
3453
- if interp == 'nn' :
3454
- interp = tri .nn_interpolator (z )
3455
- zo = interp (xi ,yi )
3456
- elif interp == 'linear' :
3457
- # make sure grid has constant dx, dy
3458
- dx = xi [0 ,1 :]- xi [0 ,0 :- 1 ]
3459
- dy = yi [1 :,0 ]- yi [0 :- 1 ,0 ]
3460
- epsx = np .finfo (xi .dtype ).resolution
3461
- epsy = np .finfo (yi .dtype ).resolution
3462
- if dx .max ()- dx .min () > epsx or dy .max ()- dy .min () > epsy :
3463
- raise ValueError ("output grid must have constant spacing"
3464
- " when using interp='linear'" )
3465
- interp = tri .linear_interpolator (z )
3466
- zo = interp [yi .min ():yi .max ():complex (0 ,yi .shape [0 ]),
3467
- xi .min ():xi .max ():complex (0 ,xi .shape [1 ])]
3468
- else :
3469
- raise ValueError ("interp keyword must be one of"
3470
- " 'linear' (for linear interpolation) or 'nn'"
3471
- " (for natural neighbor interpolation). Default is 'nn'." )
3472
- # mask points on grid outside convex hull of input data.
3473
- if np .any (np .isnan (zo )):
3474
- zo = np .ma .masked_where (np .isnan (zo ),zo )
3475
- return zo
3476
- griddata ._reported = False
3447
+ # natgrid expects 1D xi and yi arrays.
3448
+ xi = xi [0 , :]
3449
+ yi = yi [:, 0 ]
3450
+
3451
+ # Override default natgrid internal parameters.
3452
+ _natgrid .seti ('ext' , 0 )
3453
+ _natgrid .setr ('nul' , np .nan )
3454
+
3455
+ if np .min (np .diff (xi )) < 0 or np .min (np .diff (yi )) < 0 :
3456
+ raise ValueError ("Output grid defined by xi,yi must be monotone "
3457
+ "increasing" )
3458
+
3459
+ # Allocate array for output (buffer will be overwritten by natgridd)
3460
+ zi = np .empty ((yi .shape [0 ], xi .shape [0 ]), np .float64 )
3461
+
3462
+ # Natgrid requires each array to be contiguous rather than e.g. a view
3463
+ # that is a non-contiguous slice of another array. Use numpy.require
3464
+ # to deal with this, which will copy if necessary.
3465
+ x = np .require (x , requirements = ['C' ])
3466
+ y = np .require (y , requirements = ['C' ])
3467
+ z = np .require (z , requirements = ['C' ])
3468
+ xi = np .require (xi , requirements = ['C' ])
3469
+ yi = np .require (yi , requirements = ['C' ])
3470
+ _natgrid .natgridd (x , y , z , xi , yi , zi )
3471
+
3472
+ # Mask points on grid outside convex hull of input data.
3473
+ if np .any (np .isnan (zi )):
3474
+ zi = np .ma .masked_where (np .isnan (zi ), zi )
3475
+ return zi
3476
+ else :
3477
+ # Linear interpolation performed using a matplotlib.tri.Triangulation
3478
+ # and a matplotlib.tri.LinearTriInterpolator.
3479
+ from .tri import Triangulation , LinearTriInterpolator
3480
+ triang = Triangulation (x , y )
3481
+ interpolator = LinearTriInterpolator (triang , z )
3482
+ return interpolator (xi , yi )
3483
+
3477
3484
3478
3485
##################################################
3479
3486
# Linear interpolation algorithms
0 commit comments