|
90 | 90 |
|
91 | 91 | import matplotlib.nxutils as nxutils |
92 | 92 | import matplotlib.cbook as cbook |
| 93 | +try: |
| 94 | + import mpl_tookits._natgrid as _natgrid |
| 95 | + _use_natgrid = True |
| 96 | +except ImportError: |
| 97 | + import matplotlib.delaunay as delaunay |
| 98 | + _use_natgrid = False |
93 | 99 |
|
94 | 100 | # set is a new builtin function in 2.4; delete the following when |
95 | 101 | # support for 2.3 is dropped. |
@@ -2691,3 +2697,55 @@ def newfunc(val, mask, mval): |
2691 | 2697 | in zip(funcs, row, rowmask, mvals)]) |
2692 | 2698 | if opened: |
2693 | 2699 | fh.close() |
| 2700 | + |
| 2701 | +def griddata(x,y,z,xi,yi): |
| 2702 | + """ |
| 2703 | + zi = griddata(x,y,z,xi,yi) fits a surface of the form z = f(x,y) |
| 2704 | + to the data in the (usually) nonuniformly spaced vectors (x,y,z). |
| 2705 | + griddata interpolates this surface at the points specified by (xi,yi) |
| 2706 | + to produce zi. xi and yi must describe a regular grid, can be |
| 2707 | + either 1D or 2D, but must be monotonically increasing. |
| 2708 | + |
| 2709 | + A masked array is returned if any grid points are outside convex |
| 2710 | + hull defined by input data (no extrapolation is done). |
| 2711 | +
|
| 2712 | + Uses natural neighbor interpolation based on Delaunay triangulation. |
| 2713 | + """ |
| 2714 | + if xi.ndim != yi.ndim: |
| 2715 | + raise TypeError("inputs xi and yi must have same number of dimensions (1 or 2)") |
| 2716 | + if xi.ndim != 1 and xi.ndim != 2: |
| 2717 | + raise TypeError("inputs xi and yi must be 1D or 2D.") |
| 2718 | + if _use_natgrid: # use natgrid toolkit if available. |
| 2719 | + if xi.ndim == 2: |
| 2720 | + xi = xi[0,:] |
| 2721 | + yi = yi[:,0] |
| 2722 | + # override default natgrid internal parameters. |
| 2723 | + _natgrid.seti('ext',0) |
| 2724 | + _natgrid.setr('nul',np.nan) |
| 2725 | + # cast input arrays to doubles (this makes a copy) |
| 2726 | + x = x.astype(np.float) |
| 2727 | + y = y.astype(np.float) |
| 2728 | + z = z.astype(np.float) |
| 2729 | + xo = xi.astype(np.float) |
| 2730 | + yo = yi.astype(np.float) |
| 2731 | + if min(xo[1:]-xo[0:-1]) < 0 or min(yo[1:]-yo[0:-1]) < 0: |
| 2732 | + raise ValueError, 'output grid defined by xi,yi must be monotone increasing' |
| 2733 | + # allocate array for output (buffer will be overwritten by nagridd) |
| 2734 | + zo = np.empty((yo.shape[0],xo.shape[0]), np.float) |
| 2735 | + _natgrid.natgridd(x,y,z,xo,yo,zo) |
| 2736 | + else: # use Robert Kern's delaunay package from scikits (default) |
| 2737 | + if xi.ndim != yi.ndim: |
| 2738 | + raise TypeError("inputs xi and yi must have same number of dimensions (1 or 2)") |
| 2739 | + if xi.ndim != 1 and xi.ndim != 2: |
| 2740 | + raise TypeError("inputs xi and yi must be 1D or 2D.") |
| 2741 | + if xi.ndim == 1: |
| 2742 | + xi,yi = np.meshgrid(xi,yi) |
| 2743 | + # triangulate data |
| 2744 | + tri = delaunay.Triangulation(x,y) |
| 2745 | + # interpolate data |
| 2746 | + interp = tri.nn_interpolator(z) |
| 2747 | + zo = interp(xi,yi) |
| 2748 | + # mask points on grid outside convex hull of input data. |
| 2749 | + if np.any(np.isnan(zo)): |
| 2750 | + zo = np.ma.masked_where(np.isnan(zo),zo) |
| 2751 | + return zo |
0 commit comments