# Buggy code
def _get_plot_defn(cube, mode, ndims=2):
    """
    Return data and plot-axis coords given a cube & a mode of either
    POINT_MODE or BOUND_MODE.

    """
    if cube.ndim != ndims:
        msg = "Cube must be %s-dimensional. Got %s dimensions."
        raise ValueError(msg % (ndims, cube.data.ndim))

    # Start by taking the DimCoords from each dimension.
    coords = [None] * ndims
    for dim_coord in cube.dim_coords:
        dim = cube.coord_dims(dim_coord)[0]
        coords[dim] = dim_coord

    # When appropriate, restrict to 1D with bounds.
    if mode == iris.coords.BOUND_MODE:
        coords = map(_valid_bound_coord, coords)

    def guess_axis(coord):
        axis = None
        if coord is not None:
            axis = iris.util.guess_coord_axis(coord)
        return axis

    # Allow DimCoords in aux_coords to fill in for missing dim_coords.
    for dim, coord in enumerate(coords):
        if coord is None:
            aux_coords = cube.coords(dimensions=dim)
            aux_coords = filter(
                lambda coord: isinstance(coord, iris.coords.DimCoord), aux_coords
            )
            if aux_coords:
                key_func = lambda coord: coord._as_defn()
                aux_coords.sort(key=key_func)
                coords[dim] = aux_coords[0]

    if mode == iris.coords.POINT_MODE:
        # Allow multi-dimensional aux_coords to override the dim_coords.
        # (things like grid_latitude will be overriden by latitude etc.)
        axes = map(guess_axis, coords)
        for coord in cube.coords(dim_coords=False):
            if max(coord.shape) > 1 and (
                mode == iris.coords.POINT_MODE or coord.nbounds
            ):
                axis = iris.util.guess_coord_axis(coord)
                if axis and axis in axes:
                    coords[axes.index(axis)] = coord

    # Re-order the coordinates to achieve the preferred
    # horizontal/vertical associations.
    def sort_key(coord):
        order = {"X": 2, "T": 1, "Y": -1, "Z": -2}
        axis = guess_axis(coord)
        return (order.get(axis, 0), coord and coord.name())

    sorted_coords = sorted(coords, key=sort_key)

    transpose = sorted_coords != coords
    return PlotDefn(sorted_coords, transpose)


# Traceback (iris.exceptions.CoordinateNotFoundError)
Traceback (most recent call last):
File "/net/home/h05/cpelley/Remedy/GITHUB/no_pass_coords.py", line 28, in <module>
iplt.contourf(cube)
File "/home/h05/cpelley/git/iris/lib/iris/plot.py", line 464, in contourf
result = _draw_2d_from_points('contourf', None, cube, *args, **kwargs)
File "/home/h05/cpelley/git/iris/lib/iris/plot.py", line 261, in _draw_2d_from_points
*args, **kwargs)
File "/home/h05/cpelley/git/iris/lib/iris/plot.py", line 373, in _map_common
x, y = cartography.get_xy_grids(cube)
File "/home/h05/cpelley/git/iris/lib/iris/analysis/cartography.py", line 190, in get_xy_grids
x_coord, y_coord = cube.coord(axis="X"), cube.coord(axis="Y")
File "/home/h05/cpelley/git/iris/lib/iris/cube.py", line 1041, in coord
raise iris.exceptions.CoordinateNotFoundError(msg)
iris.exceptions.CoordinateNotFoundError: u'Expected to find exactly 1 coordinate, but found 2. They were: grid_longitude, longitude.'

# Fixed code
def _get_plot_defn(cube, mode, ndims=2):
    """
    Return data and plot-axis coords given a cube & a mode of either
    POINT_MODE or BOUND_MODE.

    """
    if cube.ndim != ndims:
        msg = "Cube must be %s-dimensional. Got %s dimensions."
        raise ValueError(msg % (ndims, cube.data.ndim))

    # Start by taking the DimCoords from each dimension.
    coords = [None] * ndims
    for dim_coord in cube.dim_coords:
        dim = cube.coord_dims(dim_coord)[0]
        coords[dim] = dim_coord

    # When appropriate, restrict to 1D with bounds.
    if mode == iris.coords.BOUND_MODE:
        coords = map(_valid_bound_coord, coords)

    def guess_axis(coord):
        axis = None
        if coord is not None:
            axis = iris.util.guess_coord_axis(coord)
        return axis

    # Allow DimCoords in aux_coords to fill in for missing dim_coords.
    for dim, coord in enumerate(coords):
        if coord is None:
            aux_coords = cube.coords(dimensions=dim)
            aux_coords = filter(
                lambda coord: isinstance(coord, iris.coords.DimCoord), aux_coords
            )
            if aux_coords:
                key_func = lambda coord: coord._as_defn()
                aux_coords.sort(key=key_func)
                coords[dim] = aux_coords[0]

    if mode == iris.coords.POINT_MODE:
        # Allow multi-dimensional aux_coords to override the dim_coords
        # along the Z axis. This results in a preference for using the
        # derived altitude over model_level_number or level_height.
        # Limit to Z axis to avoid preferring latitude over grid_latitude etc.
        axes = map(guess_axis, coords)
        axis = "Z"
        if axis in axes:
            for coord in cube.coords(dim_coords=False):
                if max(coord.shape) > 1 and iris.util.guess_coord_axis(coord) == axis:
                    coords[axes.index(axis)] = coord

    # Re-order the coordinates to achieve the preferred
    # horizontal/vertical associations.
    def sort_key(coord):
        order = {"X": 2, "T": 1, "Y": -1, "Z": -2}
        axis = guess_axis(coord)
        return (order.get(axis, 0), coord and coord.name())

    sorted_coords = sorted(coords, key=sort_key)

    transpose = sorted_coords != coords
    return PlotDefn(sorted_coords, transpose)