@@ -3356,124 +3356,131 @@ def newfunc(val, mask, mval):
33563356 if opened :
33573357 fh .close ()
33583358
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 )
34093411 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+
34263446 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+
34773484
34783485##################################################
34793486# Linear interpolation algorithms
0 commit comments