Beispiel #1
0
 def plot(self, xs, ys, *args, **kwargs):
     '''
     Plot 2D or 3D data.
     ==========  ================================================
     Argument    Description
     ==========  ================================================
     *xs*, *ys*  X, y coordinates of vertices
     *zs*        z value(s), either one for all points or one for
                 each point.
     *zdir*      Which direction to use as z ('x', 'y' or 'z')
                 when plotting a 2d set.
     ==========  ================================================
     Other arguments are passed on to
     :func:`~matplotlib.axes.Axes.plot`
     '''
     had_data = self.has_data()
     zs = kwargs.pop('zs', 0)
     zdir = kwargs.pop('zdir', 'z')
     argsi = 0
     if len(args) > 0 and cbook.iterable(args[0]) and \
             len(xs) == len(args[0]) and cbook.is_scalar(args[0][0]):
         zs = args[argsi]
         argsi += 1
     elif len(args) > 0 and cbook.is_scalar(args[0]):
         zs = args[argsi]
         argsi += 1
     if not cbook.iterable(zs):
         zs = np.ones(len(xs)) * zs
     lines = Axes.plot(self, xs, ys, *args[argsi:], **kwargs)
     for line in lines:
         art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)
     self.auto_scale_xyz(xs, ys, zs, had_data)
     return lines
Beispiel #2
0
    def plot(self, xs, ys, *args, **kwargs):
        '''
        Plot 2D or 3D data.

        ==========  ================================================
        Argument    Description
        ==========  ================================================
        *xs*, *ys*  X, y coordinates of vertices

        *zs*        z value(s), either one for all points or one for
                    each point.
        *zdir*      Which direction to use as z ('x', 'y' or 'z')
                    when plotting a 2d set.
        ==========  ================================================

        Other arguments are passed on to
        :func:`~matplotlib.axes.Axes.plot`
        '''
        # FIXME: This argument parsing might be better handled
        #        when we set later versions of python for
        #        minimum requirements.  Currently at 2.4.
        #        Note that some of the reason for the current difficulty
        #        is caused by the fact that we want to insert a new
        #        (semi-optional) positional argument 'Z' right before
        #        many other traditional positional arguments occur
        #        such as the color, linestyle and/or marker.
        had_data = self.has_data()
        zs = kwargs.pop('zs', 0)
        zdir = kwargs.pop('zdir', 'z')

        argsi = 0
        # First argument is array of zs
        if len(args) > 0 and cbook.iterable(args[0]) and \
                len(xs) == len(args[0]) :
            # So, we know that it is an array with
            # first dimension the same as xs.
            # Next, check to see if the data contained
            # therein (if any) is scalar (and not another array).
            if len(args[0]) == 0 or cbook.is_scalar(args[0][0]) :
                zs = args[argsi]
                argsi += 1

        # First argument is z value
        elif len(args) > 0 and cbook.is_scalar(args[0]):
            zs = args[argsi]
            argsi += 1

        # Match length
        if not cbook.iterable(zs):
            zs = np.ones(len(xs)) * zs

        lines = Axes.plot(self, xs, ys, *args[argsi:], **kwargs)
        for line in lines:
            art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)

        self.auto_scale_xyz(xs, ys, zs, had_data)
        return lines
Beispiel #3
0
    def plot(self, xs, ys, *args, **kwargs):
        '''
        Plot 2D or 3D data.

        ==========  ================================================
        Argument    Description
        ==========  ================================================
        *xs*, *ys*  X, y coordinates of vertices

        *zs*        z value(s), either one for all points or one for
                    each point.
        *zdir*      Which direction to use as z ('x', 'y' or 'z')
                    when plotting a 2d set.
        ==========  ================================================

        Other arguments are passed on to
        :func:`~matplotlib.axes.Axes.plot`
        '''

        had_data = self.has_data()
        zs = kwargs.pop('zs', 0)
        zdir = kwargs.pop('zdir', 'z')

        argsi = 0
        # First argument is array of zs
        if len(args) > 0 and cbook.iterable(args[0]) and \
                len(xs) == len(args[0]) and cbook.is_scalar(args[0][0]):
            zs = args[argsi]
            argsi += 1

        # First argument is z value
        elif len(args) > 0 and cbook.is_scalar(args[0]):
            zs = args[argsi]
            argsi += 1

        # Match length
        if not cbook.iterable(zs):
            zs = np.ones(len(xs)) * zs

        lines = Axes.plot(self, xs, ys, *args[argsi:], **kwargs)
        for line in lines:
            art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)

        self.auto_scale_xyz(xs, ys, zs, had_data)
        return lines
Beispiel #4
0
    def plot(self, xs, ys, *args, **kwargs):
        """
        Plot 2D or 3D data.

        ==========  ================================================
        Argument    Description
        ==========  ================================================
        *xs*, *ys*  X, y coordinates of vertices

        *zs*        z value(s), either one for all points or one for
                    each point.
        *zdir*      Which direction to use as z ('x', 'y' or 'z')
                    when plotting a 2d set.
        ==========  ================================================

        Other arguments are passed on to
        :func:`~matplotlib.axes.Axes.plot`
        """

        had_data = self.has_data()
        zs = kwargs.pop("zs", 0)
        zdir = kwargs.pop("zdir", "z")

        argsi = 0
        # First argument is array of zs
        if len(args) > 0 and cbook.iterable(args[0]) and len(xs) == len(args[0]) and cbook.is_scalar(args[0][0]):
            zs = args[argsi]
            argsi += 1

        # First argument is z value
        elif len(args) > 0 and cbook.is_scalar(args[0]):
            zs = args[argsi]
            argsi += 1

        # Match length
        if not cbook.iterable(zs):
            zs = [zs] * len(xs)

        lines = Axes.plot(self, xs, ys, *args[argsi:], **kwargs)
        for line in lines:
            art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)

        self.auto_scale_xyz(xs, ys, zs, had_data)
        return lines
Beispiel #5
0
def draw_networkx_edges(G, pos, node_patches=None,
                        edgelist=None,
                        width=None,
                        edge_color=None,
                        style='solid',
                        alpha=None,
                        edge_cmap=None,
                        edge_vmin=None,
                        edge_vmax=None, 
                        ax=None,
                        arrows=True,
                        arrow_style=None,
                        connection_style='arc3',
                        color_weights=False,
                        width_weights=False,
                        **kwds):
    """Draw the edges of the graph G

    This draws only the edges of the graph G.

    Parameters
    ----------
    G : graph
       A networkx graph 

    pos : dictionary
       A dictionary with nodes as keys and positions as values.
       If not specified a spring layout positioning will be computed.
       See networkx.layout for functions that compute node positions.
       
    ax : Matplotlib Axes object, optional
       Draw the graph in the specified Matplotlib axes.  

    alpha: float
       The edge transparency (default=1.0) 

    width`: float
       Line width of edges (default =1.0)

    edge_color: color string, or array of floats
       Edge color. Can be a single color format string (default='r'),
       or a sequence of colors with the same length as edgelist.
       If numeric values are specified they will be mapped to
       colors using the edge_cmap and edge_vmin,edge_vmax parameters.

    edge_ cmap: Matplotlib colormap
       Colormap for mapping intensities of edges (default=None)

    edge_vmin,edge_vmax: floats
       Minimum and maximum for edge colormap scaling (default=None)

    style: string
       Edge line style (default='solid') (solid|dashed|dotted,dashdot)
    arrow: Bool
       Whether to draw arrows or not for directed graphs
    arrow_style: string
       Arrow style used by matplotlib see FancyArrowPatch
    connection_style: string
       Connection style used by matplotlib, see FancyArrowPatch
    color_weights: Bool
       Whether to color the edges of a graph by their weight if the
       graph has any.
    width_weights: Bool
       Whether to vary the thicknes of an edge by their weight, if the
       graph has any.

    Examples
    --------
    >>> G=nx.dodecahedral_graph()
    >>> edges=nx.draw_networkx_edges(G,pos=nx.spring_layout(G)) 

    Also see the NetworkX drawing examples at
    http://networkx.lanl.gov/gallery.html

    See Also
    --------
    draw()
    draw_networkx()
    draw_networkx_nodes()
    draw_networkx_labels()
    draw_networkx_edge_labels()

    """
    try:
        import matplotlib
        import matplotlib.pylab as pylab
        import matplotlib.cbook as cb
        from matplotlib.colors import colorConverter,Colormap
        from matplotlib.collections import LineCollection
        import numpy
    except ImportError:
        raise ImportError, "Matplotlib required for draw()"
    except RuntimeError:
        print "Matplotlib unable to open display"
        raise

    if ax is None:
        ax=pylab.gca()

    if edgelist is None:
        edgelist=G.edges()

    if not edgelist or len(edgelist)==0: # no edges!
        return None

    # set edge positions
    edge_pos=numpy.asarray([(pos[e[0]],pos[e[1]]) for e in edgelist])

    
    if width is None and width_weights and is_weighted(G):
        lw = edge_width_weight(G,edgelist)
        if alpha is None:
            alpha = 0.75
    elif width is None:
        lw = {}.fromkeys(edgelist,1.0)
    elif cb.iterable(width):
        try:
            lwvals = width.values()
        except:
            lwvals = width
        lw = dict(zip(edgelist,lwvals))
    elif cb.is_scalar(width):
        lw = {}.fromkeys(edgelist,width)
    else:
        raise nx.NetworkXError("Must provide a single scalar value or a list \
                                of values for line width or None")
    

    if edge_cmap is None:
        edge_cmap = cm.get_cmap(mpl.rcParams['image.cmap'])

    if edge_color is None and color_weights and is_weighted(G):
        edge_color = edge_color_weight(G,edgelist)
        if alpha is None:
            alpha = 0.75
    elif edge_color is None:
        edge_color = 'k'

    e_colors = get_color_dict(edge_color,edgelist,edge_vmin,edge_vmax,edge_cmap)

    edge_patches = {}

    if arrow_style is None:
        if G.is_directed():
            arrow_style = '-|>'
        else:
            arrow_style = '-'

    if node_patches is None:
        node_patches = {}.fromkeys(G.nodes(),None)
    for (u,v) in edgelist:
        edge_patches[(u,v)] = patches.FancyArrowPatch(posA=pos[u],
                                                      posB=pos[v],
                                                      arrowstyle=arrow_style,
                                                      connectionstyle=connection_style,
                                                      patchA=node_patches[u],
                                                      patchB=node_patches[v],
                                                      shrinkA=0.0,
                                                      shrinkB=0.0,
                                                      mutation_scale=20.0,
                                                      alpha=alpha,
                                                      color=e_colors[(u,v)],
                                                      lw = lw[(u,v)],
                                                      linestyle=style,
                                                      zorder=1)
        ax.add_patch(edge_patches[(u,v)])
                                                      
    # update view
    minx = numpy.amin(numpy.ravel(edge_pos[:,:,0]))
    maxx = numpy.amax(numpy.ravel(edge_pos[:,:,0]))
    miny = numpy.amin(numpy.ravel(edge_pos[:,:,1]))
    maxy = numpy.amax(numpy.ravel(edge_pos[:,:,1]))

    w = maxx-minx
    h = maxy-miny
    padx, pady = 0.05*w, 0.05*h
    corners = (minx-padx, miny-pady), (maxx+padx, maxy+pady)
    ax.update_datalim( corners)
    ax.autoscale_view()

    return edge_patches
Beispiel #6
0
def get_color_dict(color,item_list,vmin=None,vmax=None,cmap=None):
    """ Determine color rgb color values given a data list.

    This function is used to take a sequence of data and convert it
    into a dictionary which of possible rgb values. It can take a
    number of different types of data explained below. If no colormap
    is given it will return the grayscale for scalar values.

    Parameters:
    -----------
    color: A string, scalar, or iterable of either.
           This can be a color in a variety of formats. A matplotlib
           a single color, which can be a matplotlib color specification
           e.g. 'rgbcmykw', a hex color string '#00FFFF', a standard
           html name like 'aqua', or a numeric value to be scaled with
           vmax or vmin. It can also be a list of any of these types
           as well as a dictionary of any of these types.
    item_list: a list
               A list of keys which correspond to the values given in
               color.
    vmin: A scalar
          The minimum value if scalar values are given for color
    vmax: A scalar
          The maximum value if scalar values are given for color
    cmap: A matplotlib colormap
          A colormap to be used if scalar values are given.

    Returns:
    -------
    color_dict: dict
                A dictionary of rgb colors keyed by values in item_list
    """
    
    CC = mcolors.ColorConverter()

    if cb.is_string_like(color):
        return {}.fromkeys(item_list,CC.to_rgb(color))
    elif cb.is_scalar(color):
        CN = mcolors.Normalize(0.0,1.0)
        if cmap is not None:
            return {}.fromkeys(item_list,cmap(CN(color)))
        else:
            return {}.fromkeys(item_list,CC.to_rgb(str(CN(color))))
    elif cb.iterable(color) and not cb.is_string_like(color):
        try:
            vals = [color[i] for i in item_list]
        except:
            vals = color
        keys = item_list
        if len(item_list)>len(vals):
            raise nx.NetworkXError("Must provide a value for each item")
        if cb.alltrue([cb.is_string_like(c) for c in vals]):
            return dict(zip(keys,[CC.to_rgb(v) for v in vals]))
        elif cb.alltrue([cb.is_scalar(c) for c in vals]):
            if vmin is None:
                vmin = float(min(vals))
            if vmax is None:
                vmax = float(max(vals))
            CN = mcolors.Normalize(vmin,vmax)
            if cmap is not None:
                return dict(zip(keys,[cmap(CN(v)) for v in vals]))
            else:
                return dict(zip(keys,[CC.to_rgb(str(CN(v))) for v in vals]))
        elif cb.alltrue([cb.iterable(c) and not cb.is_string(c) for c in vals]):
            return dict(zip(keys,vals))
    else:
        raise nx.NetworkXError("Could not convert colors")
Beispiel #7
0
def draw_networkx_edges(G,
                        pos,
                        node_patches=None,
                        edgelist=None,
                        width=None,
                        edge_color=None,
                        style='solid',
                        alpha=None,
                        edge_cmap=None,
                        edge_vmin=None,
                        edge_vmax=None,
                        ax=None,
                        arrows=True,
                        arrow_style=None,
                        connection_style='arc3',
                        color_weights=False,
                        width_weights=False,
                        **kwds):
    """Draw the edges of the graph G

    This draws only the edges of the graph G.

    Parameters
    ----------
    G : graph
       A networkx graph 

    pos : dictionary
       A dictionary with nodes as keys and positions as values.
       If not specified a spring layout positioning will be computed.
       See networkx.layout for functions that compute node positions.
       
    ax : Matplotlib Axes object, optional
       Draw the graph in the specified Matplotlib axes.  

    alpha: float
       The edge transparency (default=1.0) 

    width`: float
       Line width of edges (default =1.0)

    edge_color: color string, or array of floats
       Edge color. Can be a single color format string (default='r'),
       or a sequence of colors with the same length as edgelist.
       If numeric values are specified they will be mapped to
       colors using the edge_cmap and edge_vmin,edge_vmax parameters.

    edge_ cmap: Matplotlib colormap
       Colormap for mapping intensities of edges (default=None)

    edge_vmin,edge_vmax: floats
       Minimum and maximum for edge colormap scaling (default=None)

    style: string
       Edge line style (default='solid') (solid|dashed|dotted,dashdot)
    arrow: Bool
       Whether to draw arrows or not for directed graphs
    arrow_style: string
       Arrow style used by matplotlib see FancyArrowPatch
    connection_style: string
       Connection style used by matplotlib, see FancyArrowPatch
    color_weights: Bool
       Whether to color the edges of a graph by their weight if the
       graph has any.
    width_weights: Bool
       Whether to vary the thicknes of an edge by their weight, if the
       graph has any.

    Examples
    --------
    >>> G=nx.dodecahedral_graph()
    >>> edges=nx.draw_networkx_edges(G,pos=nx.spring_layout(G)) 

    Also see the NetworkX drawing examples at
    http://networkx.lanl.gov/gallery.html

    See Also
    --------
    draw()
    draw_networkx()
    draw_networkx_nodes()
    draw_networkx_labels()
    draw_networkx_edge_labels()

    """
    try:
        import matplotlib
        import matplotlib.pylab as pylab
        import matplotlib.cbook as cb
        from matplotlib.colors import colorConverter, Colormap
        from matplotlib.collections import LineCollection
        import numpy
    except ImportError:
        raise ImportError, "Matplotlib required for draw()"
    except RuntimeError:
        print "Matplotlib unable to open display"
        raise

    if ax is None:
        ax = pylab.gca()

    if edgelist is None:
        edgelist = G.edges()

    if not edgelist or len(edgelist) == 0:  # no edges!
        return None

    # set edge positions
    edge_pos = numpy.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist])

    if width is None and width_weights and is_weighted(G):
        lw = edge_width_weight(G, edgelist)
        if alpha is None:
            alpha = 0.75
    elif width is None:
        lw = {}.fromkeys(edgelist, 1.0)
    elif cb.iterable(width):
        try:
            lwvals = width.values()
        except:
            lwvals = width
        lw = dict(zip(edgelist, lwvals))
    elif cb.is_scalar(width):
        lw = {}.fromkeys(edgelist, width)
    else:
        raise nx.NetworkXError("Must provide a single scalar value or a list \
                                of values for line width or None")

    if edge_cmap is None:
        edge_cmap = cm.get_cmap(mpl.rcParams['image.cmap'])

    if edge_color is None and color_weights and is_weighted(G):
        edge_color = edge_color_weight(G, edgelist)
        if alpha is None:
            alpha = 0.75
    elif edge_color is None:
        edge_color = 'k'

    e_colors = get_color_dict(edge_color, edgelist, edge_vmin, edge_vmax,
                              edge_cmap)

    edge_patches = {}

    if arrow_style is None:
        if G.is_directed():
            arrow_style = '-|>'
        else:
            arrow_style = '-'

    if node_patches is None:
        node_patches = {}.fromkeys(G.nodes(), None)
    for (u, v) in edgelist:
        edge_patches[(u, v)] = patches.FancyArrowPatch(
            posA=pos[u],
            posB=pos[v],
            arrowstyle=arrow_style,
            connectionstyle=connection_style,
            patchA=node_patches[u],
            patchB=node_patches[v],
            shrinkA=0.0,
            shrinkB=0.0,
            mutation_scale=20.0,
            alpha=alpha,
            color=e_colors[(u, v)],
            lw=lw[(u, v)],
            linestyle=style,
            zorder=1)
        ax.add_patch(edge_patches[(u, v)])

    # update view
    minx = numpy.amin(numpy.ravel(edge_pos[:, :, 0]))
    maxx = numpy.amax(numpy.ravel(edge_pos[:, :, 0]))
    miny = numpy.amin(numpy.ravel(edge_pos[:, :, 1]))
    maxy = numpy.amax(numpy.ravel(edge_pos[:, :, 1]))

    w = maxx - minx
    h = maxy - miny
    padx, pady = 0.05 * w, 0.05 * h
    corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady)
    ax.update_datalim(corners)
    ax.autoscale_view()

    return edge_patches
Beispiel #8
0
def get_color_dict(color, item_list, vmin=None, vmax=None, cmap=None):
    """ Determine color rgb color values given a data list.

    This function is used to take a sequence of data and convert it
    into a dictionary which of possible rgb values. It can take a
    number of different types of data explained below. If no colormap
    is given it will return the grayscale for scalar values.

    Parameters:
    -----------
    color: A string, scalar, or iterable of either.
           This can be a color in a variety of formats. A matplotlib
           a single color, which can be a matplotlib color specification
           e.g. 'rgbcmykw', a hex color string '#00FFFF', a standard
           html name like 'aqua', or a numeric value to be scaled with
           vmax or vmin. It can also be a list of any of these types
           as well as a dictionary of any of these types.
    item_list: a list
               A list of keys which correspond to the values given in
               color.
    vmin: A scalar
          The minimum value if scalar values are given for color
    vmax: A scalar
          The maximum value if scalar values are given for color
    cmap: A matplotlib colormap
          A colormap to be used if scalar values are given.

    Returns:
    -------
    color_dict: dict
                A dictionary of rgb colors keyed by values in item_list
    """

    CC = mcolors.ColorConverter()

    if cb.is_string_like(color):
        return {}.fromkeys(item_list, CC.to_rgb(color))
    elif cb.is_scalar(color):
        CN = mcolors.Normalize(0.0, 1.0)
        if cmap is not None:
            return {}.fromkeys(item_list, cmap(CN(color)))
        else:
            return {}.fromkeys(item_list, CC.to_rgb(str(CN(color))))
    elif cb.iterable(color) and not cb.is_string_like(color):
        try:
            vals = [color[i] for i in item_list]
        except:
            vals = color
        keys = item_list
        if len(item_list) > len(vals):
            raise nx.NetworkXError("Must provide a value for each item")
        if cb.alltrue([cb.is_string_like(c) for c in vals]):
            return dict(zip(keys, [CC.to_rgb(v) for v in vals]))
        elif cb.alltrue([cb.is_scalar(c) for c in vals]):
            if vmin is None:
                vmin = float(min(vals))
            if vmax is None:
                vmax = float(max(vals))
            CN = mcolors.Normalize(vmin, vmax)
            if cmap is not None:
                return dict(zip(keys, [cmap(CN(v)) for v in vals]))
            else:
                return dict(zip(keys, [CC.to_rgb(str(CN(v))) for v in vals]))
        elif cb.alltrue([cb.iterable(c) and not cb.is_string(c)
                         for c in vals]):
            return dict(zip(keys, vals))
    else:
        raise nx.NetworkXError("Could not convert colors")
Beispiel #9
0
def basemapInterp2D(datain,xin,yin,xout,yout,checkbounds=False,masked=False,order=1):
    """
    Interpolate data (``datain``) on a rectilinear grid (with x = ``xin``
    y = ``yin``) to a grid with x = ``xout``, y= ``yout``.

    .. tabularcolumns:: |l|L|

    ==============   ====================================================
    Arguments        Description
    ==============   ====================================================
    datain           a rank-2 array with 1st dimension corresponding to
                     y, 2nd dimension x.
    xin, yin         rank-1 arrays containing x and y of
                     datain grid in increasing order.
    xout, yout       rank-2 arrays containing x and y of desired output grid.
    ==============   ====================================================

    .. tabularcolumns:: |l|L|

    ==============   ====================================================
    Keywords         Description
    ==============   ====================================================
    checkbounds      If True, values of xout and yout are checked to see
                     that they lie within the range specified by xin
                     and xin.
                     If False, and xout,yout are outside xin,yin,
                     interpolated values will be clipped to values on
                     boundary of input grid (xin,yin)
                     Default is False.
    masked           If True, points outside the range of xin and yin
                     are masked (in a masked array).
                     If masked is set to a number, then
                     points outside the range of xin and yin will be
                     set to that number. Default False.
    order            0 for nearest-neighbor interpolation, 1 for
                     bilinear interpolation, 3 for cublic spline
                     (default 1). order=3 requires scipy.ndimage.
    ==============   ====================================================

    .. note::
     If datain is a masked array and order=1 (bilinear interpolation) is
     used, elements of dataout will be masked if any of the four surrounding
     points in datain are masked.  To avoid this, do the interpolation in two
     passes, first with order=1 (producing dataout1), then with order=0
     (producing dataout2).  Then replace all the masked values in dataout1
     with the corresponding elements in dataout2 (using numpy.where).
     This effectively uses nearest neighbor interpolation if any of the
     four surrounding points in datain are masked, and bilinear interpolation
     otherwise.

    Returns ``dataout``, the interpolated data on the grid ``xout, yout``.
    """
    # xin and yin must be monotonically increasing.
    if xin[-1]-xin[0] < 0 or yin[-1]-yin[0] < 0:
        raise ValueError('xin and yin must be increasing!')
    if xout.shape != yout.shape:
        raise ValueError('xout and yout must have same shape!')
    # check that xout,yout are
    # within region defined by xin,yin.
    if checkbounds:
        if xout.min() < xin.min() or \
           xout.max() > xin.max() or \
           yout.min() < yin.min() or \
           yout.max() > yin.max():
            raise ValueError('yout or xout outside range of yin or xin')
    # compute grid coordinates of output grid.
    delx = xin[1:]-xin[0:-1]
    dely = yin[1:]-yin[0:-1]
    if max(delx)-min(delx) < 1.e-4 and max(dely)-min(dely) < 1.e-4:
        # regular input grid.
        xcoords = (len(xin)-1)*(xout-xin[0])/(xin[-1]-xin[0])
        ycoords = (len(yin)-1)*(yout-yin[0])/(yin[-1]-yin[0])
    else:
        # irregular (but still rectilinear) input grid.
        xoutflat = xout.flatten(); youtflat = yout.flatten()
        ix = (np.searchsorted(xin,xoutflat)-1).tolist()
        iy = (np.searchsorted(yin,youtflat)-1).tolist()
        xoutflat = xoutflat.tolist(); xin = xin.tolist()
        youtflat = youtflat.tolist(); yin = yin.tolist()
        xcoords = []; ycoords = []
        for n,i in enumerate(ix):
            if i < 0:
                xcoords.append(-1) # outside of range on xin (lower end)
            elif i >= len(xin)-1:
                xcoords.append(len(xin)) # outside range on upper end.
            else:
                xcoords.append(float(i)+(xoutflat[n]-xin[i])/(xin[i+1]-xin[i]))
        for m,j in enumerate(iy):
            if j < 0:
                ycoords.append(-1) # outside of range of yin (on lower end)
            elif j >= len(yin)-1:
                ycoords.append(len(yin)) # outside range on upper end
            else:
                ycoords.append(float(j)+(youtflat[m]-yin[j])/(yin[j+1]-yin[j]))
        xcoords = np.reshape(xcoords,xout.shape)
        ycoords = np.reshape(ycoords,yout.shape)
    # data outside range xin,yin will be clipped to
    # values on boundary.
    if masked:
        xmask = np.logical_or(np.less(xcoords,0),np.greater(xcoords,len(xin)-1))
        ymask = np.logical_or(np.less(ycoords,0),np.greater(ycoords,len(yin)-1))
        xymask = np.logical_or(xmask,ymask)
    xcoords = np.clip(xcoords,0,len(xin)-1)
    ycoords = np.clip(ycoords,0,len(yin)-1)
    # interpolate to output grid using bilinear interpolation.
    if order == 1:
        xi = xcoords.astype(np.int32)
        yi = ycoords.astype(np.int32)
        xip1 = xi+1
        yip1 = yi+1
        xip1 = np.clip(xip1,0,len(xin)-1)
        yip1 = np.clip(yip1,0,len(yin)-1)
        delx = xcoords-xi.astype(np.float32)
        dely = ycoords-yi.astype(np.float32)
        dataout = (1.-delx)*(1.-dely)*datain[yi,xi] + \
                  delx*dely*datain[yip1,xip1] + \
                  (1.-delx)*dely*datain[yip1,xi] + \
                  delx*(1.-dely)*datain[yi,xip1]
    elif order == 0:
        xcoordsi = np.around(xcoords).astype(np.int32)
        ycoordsi = np.around(ycoords).astype(np.int32)
        dataout = datain[ycoordsi,xcoordsi]
    elif order == 3:
        try:
            from scipy.ndimage import map_coordinates
        except ImportError:
            raise ValueError('scipy.ndimage must be installed if order=3')
        coords = [ycoords,xcoords]
        dataout = map_coordinates(datain,coords,order=3,mode='nearest')
    else:
        raise ValueError('order keyword must be 0, 1 or 3')
    if masked and isinstance(masked,bool):
        dataout = ma.masked_array(dataout)
        newmask = ma.mask_or(ma.getmask(dataout), xymask)
        dataout = ma.masked_array(dataout,mask=newmask)
    elif masked and is_scalar(masked):
        dataout = np.where(xymask,masked,dataout)
    return dataout