prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  coastlines drawn under filled contours
  When using matplotlib v1.3.x and cartopy v0.7.x (development master from github) coastlines and other features are drawn underneath filled contours unless:
  
  ```
  ax.coastlines(zorder=1)
  ```
  
  is used to manually raise them above. I suspect this may be a matplotlib issue, but thought it would be best to raise it here for the cartopy experts to take a look at first.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `lib/cartopy/mpl/feature_artist.py`
  Content:
  ```
  1 # (C) British Crown Copyright 2011 - 2012, Met Office
  2 #
  3 # This file is part of cartopy.
  4 #
  5 # cartopy is free software: you can redistribute it and/or modify it under
  6 # the terms of the GNU Lesser General Public License as published by the
  7 # Free Software Foundation, either version 3 of the License, or
  8 # (at your option) any later version.
  9 #
  10 # cartopy is distributed in the hope that it will be useful,
  11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 # GNU Lesser General Public License for more details.
  14 #
  15 # You should have received a copy of the GNU Lesser General Public License
  16 # along with cartopy.  If not, see <http://www.gnu.org/licenses/>.
  17 """
  18 This module defines the :class:`FeatureArtist` class, for drawing
  19 :class:`Feature` instances with matplotlib.
  20 
  21 """
  22 import warnings
  23 import weakref
  24 
  25 import matplotlib.artist
  26 import matplotlib.cbook
  27 import matplotlib.collections
  28 import matplotlib.lines
  29 
  30 import cartopy.mpl.patch
  31 
  32 
  33 class FeatureArtist(matplotlib.artist.Artist):
  34     """
  35     A subclass of :class:`~matplotlib.artist.Artist` capable of
  36     drawing a :class:`cartopy.feature.Feature`.
  37 
  38     """
  39     _geometry_to_path_cache = weakref.WeakKeyDictionary()
  40     """
  41     A nested mapping from geometry and target projection to the
  42     resulting transformed matplotlib paths::
  43 
  44         {geom: {target_projection: list_of_paths}}
  45 
  46     This provides a significant boost when producing multiple maps of the
  47     same projection.
  48 
  49     """
  50     def __init__(self, feature, **kwargs):
  51         """
  52         Args:
  53 
  54         * feature:
  55             an instance of :class:`cartopy.feature.Feature` to draw.
  56         * kwargs:
  57             keyword arguments to be used when drawing the feature. These
  58             will override those shared with the feature.
  59 
  60         """
  61         super(FeatureArtist, self).__init__()
  62 
  63         if kwargs is None:
  64             kwargs = {}
  65         self._kwargs = dict(kwargs)
  66 
  67         # Set default zorder so that features are drawn before
  68         # lines e.g. contours but after images.
  69         # Note that the zorder of Patch, PatchCollection and PathCollection
  70         # are all 1 by default. Assuming equal zorder drawing takes place in
  71         # the following order: collections, patches, lines (default zorder=2),
  72         # text (default zorder=3), then other artists e.g. FeatureArtist.
  73         if self._kwargs.get('zorder') is not None:
  74             self.set_zorder(self._kwargs['zorder'])
  75         elif feature.kwargs.get('zorder') is not None:
  76             self.set_zorder(feature.kwargs['zorder'])
  77         else:
  78             self.set_zorder(matplotlib.collections.PathCollection.zorder)
  79 
  80         self._feature = feature
  81 
  82     @matplotlib.artist.allow_rasterization
  83     def draw(self, renderer, *args, **kwargs):
  84         """
  85         Draws the geometries of the feature that intersect with the extent of
  86         the :class:`cartopy.mpl.GeoAxes` instance to which this
  87         object has been added.
  88 
  89         """
  90         if not self.get_visible():
  91             return
  92 
  93         ax = self.get_axes()
  94         feature_crs = self._feature.crs
  95 
  96         # Get geometries that we need to draw.
  97         extent = None
  98         try:
  99             extent = ax.get_extent(feature_crs)
  100         except ValueError:
  101             warnings.warn('Unable to determine extent. Defaulting to global.')
  102         geoms = self._feature.intersecting_geometries(extent)
  103 
  104         # Project (if necessary) and convert geometries to matplotlib paths.
  105         paths = []
  106         key = ax.projection
  107         for geom in geoms:
  108             mapping = FeatureArtist._geometry_to_path_cache.setdefault(geom,
  109                                                                        {})
  110             geom_paths = mapping.get(key)
  111             if geom_paths is None:
  112                 if ax.projection != feature_crs:
  113                     projected_geom = ax.projection.project_geometry(
  114                         geom, feature_crs)
  115                 else:
  116                     projected_geom = geom
  117                 geom_paths = cartopy.mpl.patch.geos_to_path(
  118                     projected_geom)
  119                 mapping[key] = geom_paths
  120             paths.extend(geom_paths)
  121 
  122         # Build path collection and draw it.
  123         transform = ax.projection._as_mpl_transform(ax)
  124         # Combine all the keyword args in priority order
  125         final_kwargs = dict(self._feature.kwargs)
  126         final_kwargs.update(self._kwargs)
  127         final_kwargs.update(kwargs)
  128         c = matplotlib.collections.PathCollection(paths,
  129                                                   transform=transform,
  130                                                   **final_kwargs)
  131         c.set_clip_path(ax.patch)
  132         return c.draw(renderer)
  133
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/lib/cartopy/mpl/feature_artist.py b/lib/cartopy/mpl/feature_artist.py
  --- a/lib/cartopy/mpl/feature_artist.py
  +++ b/lib/cartopy/mpl/feature_artist.py
  @@ -75,7 +75,10 @@
           elif feature.kwargs.get('zorder') is not None:
               self.set_zorder(feature.kwargs['zorder'])
           else:
  -            self.set_zorder(matplotlib.collections.PathCollection.zorder)
  +            # The class attribute matplotlib.collections.PathCollection.zorder
  +            # was removed after mpl v1.2.0, so the hard-coded value of 1 is
  +            # used instead.
  +            self.set_zorder(1)
   
           self._feature = feature
  
verification_info: {"golden_diff": "diff --git a/lib/cartopy/mpl/feature_artist.py b/lib/cartopy/mpl/feature_artist.py\n--- a/lib/cartopy/mpl/feature_artist.py\n+++ b/lib/cartopy/mpl/feature_artist.py\n@@ -75,7 +75,10 @@\n         elif feature.kwargs.get('zorder') is not None:\n             self.set_zorder(feature.kwargs['zorder'])\n         else:\n-            self.set_zorder(matplotlib.collections.PathCollection.zorder)\n+            # The class attribute matplotlib.collections.PathCollection.zorder\n+            # was removed after mpl v1.2.0, so the hard-coded value of 1 is\n+            # used instead.\n+            self.set_zorder(1)\n \n         self._feature = feature\n", "issue": "coastlines drawn under filled contours\nWhen using matplotlib v1.3.x and cartopy v0.7.x (development master from github) coastlines and other features are drawn underneath filled contours unless:\n\n```\nax.coastlines(zorder=1)\n```\n\nis used to manually raise them above. I suspect this may be a matplotlib issue, but thought it would be best to raise it here for the cartopy experts to take a look at first.\n\n", "before_files": [{"content": "# (C) British Crown Copyright 2011 - 2012, Met Office\n#\n# This file is part of cartopy.\n#\n# cartopy is free software: you can redistribute it and/or modify it under\n# the terms of the GNU Lesser General Public License as published by the\n# Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# cartopy is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser General Public License for more details.\n#\n# You should have received a copy of the GNU Lesser General Public License\n# along with cartopy.  If not, see <http://www.gnu.org/licenses/>.\n\"\"\"\nThis module defines the :class:`FeatureArtist` class, for drawing\n:class:`Feature` instances with matplotlib.\n\n\"\"\"\nimport warnings\nimport weakref\n\nimport matplotlib.artist\nimport matplotlib.cbook\nimport matplotlib.collections\nimport matplotlib.lines\n\nimport cartopy.mpl.patch\n\n\nclass FeatureArtist(matplotlib.artist.Artist):\n    \"\"\"\n    A subclass of :class:`~matplotlib.artist.Artist` capable of\n    drawing a :class:`cartopy.feature.Feature`.\n\n    \"\"\"\n    _geometry_to_path_cache = weakref.WeakKeyDictionary()\n    \"\"\"\n    A nested mapping from geometry and target projection to the\n    resulting transformed matplotlib paths::\n\n        {geom: {target_projection: list_of_paths}}\n\n    This provides a significant boost when producing multiple maps of the\n    same projection.\n\n    \"\"\"\n    def __init__(self, feature, **kwargs):\n        \"\"\"\n        Args:\n\n        * feature:\n            an instance of :class:`cartopy.feature.Feature` to draw.\n        * kwargs:\n            keyword arguments to be used when drawing the feature. These\n            will override those shared with the feature.\n\n        \"\"\"\n        super(FeatureArtist, self).__init__()\n\n        if kwargs is None:\n            kwargs = {}\n        self._kwargs = dict(kwargs)\n\n        # Set default zorder so that features are drawn before\n        # lines e.g. contours but after images.\n        # Note that the zorder of Patch, PatchCollection and PathCollection\n        # are all 1 by default. Assuming equal zorder drawing takes place in\n        # the following order: collections, patches, lines (default zorder=2),\n        # text (default zorder=3), then other artists e.g. FeatureArtist.\n        if self._kwargs.get('zorder') is not None:\n            self.set_zorder(self._kwargs['zorder'])\n        elif feature.kwargs.get('zorder') is not None:\n            self.set_zorder(feature.kwargs['zorder'])\n        else:\n            self.set_zorder(matplotlib.collections.PathCollection.zorder)\n\n        self._feature = feature\n\n    @matplotlib.artist.allow_rasterization\n    def draw(self, renderer, *args, **kwargs):\n        \"\"\"\n        Draws the geometries of the feature that intersect with the extent of\n        the :class:`cartopy.mpl.GeoAxes` instance to which this\n        object has been added.\n\n        \"\"\"\n        if not self.get_visible():\n            return\n\n        ax = self.get_axes()\n        feature_crs = self._feature.crs\n\n        # Get geometries that we need to draw.\n        extent = None\n        try:\n            extent = ax.get_extent(feature_crs)\n        except ValueError:\n            warnings.warn('Unable to determine extent. Defaulting to global.')\n        geoms = self._feature.intersecting_geometries(extent)\n\n        # Project (if necessary) and convert geometries to matplotlib paths.\n        paths = []\n        key = ax.projection\n        for geom in geoms:\n            mapping = FeatureArtist._geometry_to_path_cache.setdefault(geom,\n                                                                       {})\n            geom_paths = mapping.get(key)\n            if geom_paths is None:\n                if ax.projection != feature_crs:\n                    projected_geom = ax.projection.project_geometry(\n                        geom, feature_crs)\n                else:\n                    projected_geom = geom\n                geom_paths = cartopy.mpl.patch.geos_to_path(\n                    projected_geom)\n                mapping[key] = geom_paths\n            paths.extend(geom_paths)\n\n        # Build path collection and draw it.\n        transform = ax.projection._as_mpl_transform(ax)\n        # Combine all the keyword args in priority order\n        final_kwargs = dict(self._feature.kwargs)\n        final_kwargs.update(self._kwargs)\n        final_kwargs.update(kwargs)\n        c = matplotlib.collections.PathCollection(paths,\n                                                  transform=transform,\n                                                  **final_kwargs)\n        c.set_clip_path(ax.patch)\n        return c.draw(renderer)\n", "path": "lib/cartopy/mpl/feature_artist.py"}], "after_files": [{"content": "# (C) British Crown Copyright 2011 - 2012, Met Office\n#\n# This file is part of cartopy.\n#\n# cartopy is free software: you can redistribute it and/or modify it under\n# the terms of the GNU Lesser General Public License as published by the\n# Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# cartopy is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser General Public License for more details.\n#\n# You should have received a copy of the GNU Lesser General Public License\n# along with cartopy.  If not, see <http://www.gnu.org/licenses/>.\n\"\"\"\nThis module defines the :class:`FeatureArtist` class, for drawing\n:class:`Feature` instances with matplotlib.\n\n\"\"\"\nimport warnings\nimport weakref\n\nimport matplotlib.artist\nimport matplotlib.cbook\nimport matplotlib.collections\nimport matplotlib.lines\n\nimport cartopy.mpl.patch\n\n\nclass FeatureArtist(matplotlib.artist.Artist):\n    \"\"\"\n    A subclass of :class:`~matplotlib.artist.Artist` capable of\n    drawing a :class:`cartopy.feature.Feature`.\n\n    \"\"\"\n    _geometry_to_path_cache = weakref.WeakKeyDictionary()\n    \"\"\"\n    A nested mapping from geometry and target projection to the\n    resulting transformed matplotlib paths::\n\n        {geom: {target_projection: list_of_paths}}\n\n    This provides a significant boost when producing multiple maps of the\n    same projection.\n\n    \"\"\"\n    def __init__(self, feature, **kwargs):\n        \"\"\"\n        Args:\n\n        * feature:\n            an instance of :class:`cartopy.feature.Feature` to draw.\n        * kwargs:\n            keyword arguments to be used when drawing the feature. These\n            will override those shared with the feature.\n\n        \"\"\"\n        super(FeatureArtist, self).__init__()\n\n        if kwargs is None:\n            kwargs = {}\n        self._kwargs = dict(kwargs)\n\n        # Set default zorder so that features are drawn before\n        # lines e.g. contours but after images.\n        # Note that the zorder of Patch, PatchCollection and PathCollection\n        # are all 1 by default. Assuming equal zorder drawing takes place in\n        # the following order: collections, patches, lines (default zorder=2),\n        # text (default zorder=3), then other artists e.g. FeatureArtist.\n        if self._kwargs.get('zorder') is not None:\n            self.set_zorder(self._kwargs['zorder'])\n        elif feature.kwargs.get('zorder') is not None:\n            self.set_zorder(feature.kwargs['zorder'])\n        else:\n            # The class attribute matplotlib.collections.PathCollection.zorder\n            # was removed after mpl v1.2.0, so the hard-coded value of 1 is\n            # used instead.\n            self.set_zorder(1)\n\n        self._feature = feature\n\n    @matplotlib.artist.allow_rasterization\n    def draw(self, renderer, *args, **kwargs):\n        \"\"\"\n        Draws the geometries of the feature that intersect with the extent of\n        the :class:`cartopy.mpl.GeoAxes` instance to which this\n        object has been added.\n\n        \"\"\"\n        if not self.get_visible():\n            return\n\n        ax = self.get_axes()\n        feature_crs = self._feature.crs\n\n        # Get geometries that we need to draw.\n        extent = None\n        try:\n            extent = ax.get_extent(feature_crs)\n        except ValueError:\n            warnings.warn('Unable to determine extent. Defaulting to global.')\n        geoms = self._feature.intersecting_geometries(extent)\n\n        # Project (if necessary) and convert geometries to matplotlib paths.\n        paths = []\n        key = ax.projection\n        for geom in geoms:\n            mapping = FeatureArtist._geometry_to_path_cache.setdefault(geom,\n                                                                       {})\n            geom_paths = mapping.get(key)\n            if geom_paths is None:\n                if ax.projection != feature_crs:\n                    projected_geom = ax.projection.project_geometry(\n                        geom, feature_crs)\n                else:\n                    projected_geom = geom\n                geom_paths = cartopy.mpl.patch.geos_to_path(\n                    projected_geom)\n                mapping[key] = geom_paths\n            paths.extend(geom_paths)\n\n        # Build path collection and draw it.\n        transform = ax.projection._as_mpl_transform(ax)\n        # Combine all the keyword args in priority order\n        final_kwargs = dict(self._feature.kwargs)\n        final_kwargs.update(self._kwargs)\n        final_kwargs.update(kwargs)\n        c = matplotlib.collections.PathCollection(paths,\n                                                  transform=transform,\n                                                  **final_kwargs)\n        c.set_clip_path(ax.patch)\n        return c.draw(renderer)\n", "path": "lib/cartopy/mpl/feature_artist.py"}]}