Note
Plotting with CartoPy and GeoPandas#
Converting between GeoPandas and CartoPy for visualizing data.
CartoPy is a Python library that specializes in creating geospatial visualizations. It has a slightly different way of representing Coordinate Reference Systems (CRS) as well as constructing plots. This example steps through a round-trip transfer of data between GeoPandas and CartoPy.
First we’ll load in the data using GeoPandas.
[1]:
import matplotlib.pyplot as plt
import geopandas
from cartopy import crs as ccrs
path = geopandas.datasets.get_path('naturalearth_lowres')
df = geopandas.read_file(path)
# Add a column we'll use later
df['gdp_pp'] = df['gdp_md_est'] / df['pop_est']
ERROR 1: PROJ: proj_create_from_database: Open of /home/docs/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/share/proj failed
First we’ll visualize the map using GeoPandas
[2]:
df.plot()
[2]:
<AxesSubplot: >
Plotting with CartoPy#
Cartopy also handles Shapely objects well, but it uses a different system for CRS. To plot this data with CartoPy, we’ll first need to project it into a new CRS. We’ll use a CRS defined within CartoPy and use the GeoPandas to_crs
method to make the transformation.
[3]:
# Define the CartoPy CRS object.
crs = ccrs.AzimuthalEquidistant()
# This can be converted into a `proj4` string/dict compatible with GeoPandas
crs_proj4 = crs.proj4_init
df_ae = df.to_crs(crs_proj4)
# Here's what the plot looks like in GeoPandas
df_ae.plot()
[3]:
<AxesSubplot: >
Now that our data is in a CRS based off of CartoPy, we can easily plot it.
[4]:
fig, ax = plt.subplots(subplot_kw={'projection': crs})
ax.add_geometries(df_ae['geometry'], crs=crs)
[4]:
<cartopy.mpl.feature_artist.FeatureArtist at 0x7fad73b5d720>
Error in callback <function _draw_all_if_interactive at 0x7fad85300d30> (for post_execute):
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/pyplot.py:119, in _draw_all_if_interactive()
117 def _draw_all_if_interactive():
118 if matplotlib.is_interactive():
--> 119 draw_all()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
130 for manager in cls.get_all_fig_managers():
131 if force or manager.canvas.figure.stale:
--> 132 manager.canvas.draw_idle()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2054, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
2052 if not self._is_idle_drawing:
2053 with self._idle_draw_cntx():
-> 2054 self.draw(*args, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:408, in FigureCanvasAgg.draw(self)
404 # Acquire a lock on the shared font cache.
405 with RendererAgg.lock, \
406 (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
407 else nullcontext()):
--> 408 self.figure.draw(self.renderer)
409 # A GUI class may be need to update a window using this draw, so
410 # don't forget to call the superclass.
411 super().draw()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:543, in GeoAxes.draw(self, renderer, **kwargs)
535 """
536 Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.
537
(...)
540 been set.
541 """
542 # Shared processing steps
--> 543 self._draw_preprocess(renderer)
545 # XXX This interface needs a tidy up:
546 # image drawing on pan/zoom;
547 # caching the resulting image;
548 # buffering the result by 10%...;
549 if not self._done_img_factory:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes._draw_preprocess(self, renderer)
506 # If data has been added (i.e. autoscale hasn't been turned off)
507 # then we should autoscale the view.
508 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 509 self.autoscale_view()
511 # Adjust location of background patch so that new gridlines below are
512 # clipped correctly.
513 self.patch._adjust_location()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/formatters.py:339, in BaseFormatter.__call__(self, obj)
337 pass
338 else:
--> 339 return printer(obj)
340 # Finally look for special method names
341 method = get_real_method(obj, self.print_method)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/pylabtools.py:151, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
148 from matplotlib.backend_bases import FigureCanvasBase
149 FigureCanvasBase(fig)
--> 151 fig.canvas.print_figure(bytes_io, **kw)
152 data = bytes_io.getvalue()
153 if fmt == 'svg':
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2314, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2308 renderer = _get_renderer(
2309 self.figure,
2310 functools.partial(
2311 print_method, orientation=orientation)
2312 )
2313 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2314 self.figure.draw(renderer)
2316 if bbox_inches:
2317 if bbox_inches == "tight":
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:543, in GeoAxes.draw(self, renderer, **kwargs)
535 """
536 Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.
537
(...)
540 been set.
541 """
542 # Shared processing steps
--> 543 self._draw_preprocess(renderer)
545 # XXX This interface needs a tidy up:
546 # image drawing on pan/zoom;
547 # caching the resulting image;
548 # buffering the result by 10%...;
549 if not self._done_img_factory:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes._draw_preprocess(self, renderer)
506 # If data has been added (i.e. autoscale hasn't been turned off)
507 # then we should autoscale the view.
508 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 509 self.autoscale_view()
511 # Adjust location of background patch so that new gridlines below are
512 # clipped correctly.
513 self.patch._adjust_location()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
<Figure size 640x480 with 1 Axes>
Note that we could have easily done this with an EPSG code like so:
[5]:
crs_epsg = ccrs.epsg('3857')
df_epsg = df.to_crs(epsg='3857')
# Generate a figure with two axes, one for CartoPy, one for GeoPandas
fig, axs = plt.subplots(1, 2, subplot_kw={'projection': crs_epsg},
figsize=(10, 5))
# Make the CartoPy plot
axs[0].add_geometries(df_epsg['geometry'], crs=crs_epsg,
facecolor='white', edgecolor='black')
# Make the GeoPandas plot
df_epsg.plot(ax=axs[1], color='white', edgecolor='black')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In [5], line 11
8 axs[0].add_geometries(df_epsg['geometry'], crs=crs_epsg,
9 facecolor='white', edgecolor='black')
10 # Make the GeoPandas plot
---> 11 df_epsg.plot(ax=axs[1], color='white', edgecolor='black')
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/geopandas/plotting.py:968, in GeoplotAccessor.__call__(self, *args, **kwargs)
966 kind = kwargs.pop("kind", "geo")
967 if kind == "geo":
--> 968 return plot_dataframe(data, *args, **kwargs)
969 if kind in self._pandas_kinds:
970 # Access pandas plots
971 return PlotAccessor(data)(kind=kind, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/geopandas/plotting.py:704, in plot_dataframe(df, column, cmap, color, ax, cax, categorical, legend, scheme, k, vmin, vmax, markersize, figsize, legend_kwds, categories, classification_kwds, missing_kwds, aspect, **style_kwds)
701 markersize = df[markersize].values
703 if column is None:
--> 704 return plot_series(
705 df.geometry,
706 cmap=cmap,
707 color=color,
708 ax=ax,
709 figsize=figsize,
710 markersize=markersize,
711 aspect=aspect,
712 **style_kwds,
713 )
715 # To accept pd.Series and np.arrays as column
716 if isinstance(column, (np.ndarray, pd.Series)):
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/geopandas/plotting.py:458, in plot_series(s, cmap, color, ax, figsize, aspect, **style_kwds)
455 facecolor = color_
457 values_ = values[poly_idx] if cmap else None
--> 458 _plot_polygon_collection(
459 ax, polys, values_, facecolor=facecolor, cmap=cmap, **style_kwds
460 )
462 # plot all LineStrings and MultiLineString components in same collection
463 lines = expl_series[line_idx]
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/geopandas/plotting.py:185, in _plot_polygon_collection(ax, geoms, values, color, cmap, vmin, vmax, **kwargs)
182 collection.set_clim(vmin, vmax)
184 ax.add_collection(collection, autolim=True)
--> 185 ax.autoscale_view()
186 return collection
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
Error in callback <function _draw_all_if_interactive at 0x7fad85300d30> (for post_execute):
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/pyplot.py:119, in _draw_all_if_interactive()
117 def _draw_all_if_interactive():
118 if matplotlib.is_interactive():
--> 119 draw_all()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
130 for manager in cls.get_all_fig_managers():
131 if force or manager.canvas.figure.stale:
--> 132 manager.canvas.draw_idle()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2054, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
2052 if not self._is_idle_drawing:
2053 with self._idle_draw_cntx():
-> 2054 self.draw(*args, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:408, in FigureCanvasAgg.draw(self)
404 # Acquire a lock on the shared font cache.
405 with RendererAgg.lock, \
406 (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
407 else nullcontext()):
--> 408 self.figure.draw(self.renderer)
409 # A GUI class may be need to update a window using this draw, so
410 # don't forget to call the superclass.
411 super().draw()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:543, in GeoAxes.draw(self, renderer, **kwargs)
535 """
536 Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.
537
(...)
540 been set.
541 """
542 # Shared processing steps
--> 543 self._draw_preprocess(renderer)
545 # XXX This interface needs a tidy up:
546 # image drawing on pan/zoom;
547 # caching the resulting image;
548 # buffering the result by 10%...;
549 if not self._done_img_factory:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes._draw_preprocess(self, renderer)
506 # If data has been added (i.e. autoscale hasn't been turned off)
507 # then we should autoscale the view.
508 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 509 self.autoscale_view()
511 # Adjust location of background patch so that new gridlines below are
512 # clipped correctly.
513 self.patch._adjust_location()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/formatters.py:339, in BaseFormatter.__call__(self, obj)
337 pass
338 else:
--> 339 return printer(obj)
340 # Finally look for special method names
341 method = get_real_method(obj, self.print_method)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/pylabtools.py:151, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
148 from matplotlib.backend_bases import FigureCanvasBase
149 FigureCanvasBase(fig)
--> 151 fig.canvas.print_figure(bytes_io, **kw)
152 data = bytes_io.getvalue()
153 if fmt == 'svg':
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2314, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2308 renderer = _get_renderer(
2309 self.figure,
2310 functools.partial(
2311 print_method, orientation=orientation)
2312 )
2313 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2314 self.figure.draw(renderer)
2316 if bbox_inches:
2317 if bbox_inches == "tight":
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:543, in GeoAxes.draw(self, renderer, **kwargs)
535 """
536 Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.
537
(...)
540 been set.
541 """
542 # Shared processing steps
--> 543 self._draw_preprocess(renderer)
545 # XXX This interface needs a tidy up:
546 # image drawing on pan/zoom;
547 # caching the resulting image;
548 # buffering the result by 10%...;
549 if not self._done_img_factory:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes._draw_preprocess(self, renderer)
506 # If data has been added (i.e. autoscale hasn't been turned off)
507 # then we should autoscale the view.
508 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 509 self.autoscale_view()
511 # Adjust location of background patch so that new gridlines below are
512 # clipped correctly.
513 self.patch._adjust_location()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
<Figure size 1000x500 with 2 Axes>
CartoPy to GeoPandas#
Next we’ll perform a CRS projection in CartoPy, and then convert it back into a GeoPandas object.
[6]:
crs_new = ccrs.AlbersEqualArea()
new_geometries = [crs_new.project_geometry(ii, src_crs=crs)
for ii in df_ae['geometry'].values]
fig, ax = plt.subplots(subplot_kw={'projection': crs_new})
ax.add_geometries(new_geometries, crs=crs_new)
[6]:
<cartopy.mpl.feature_artist.FeatureArtist at 0x7fad69e409d0>
Error in callback <function _draw_all_if_interactive at 0x7fad85300d30> (for post_execute):
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/pyplot.py:119, in _draw_all_if_interactive()
117 def _draw_all_if_interactive():
118 if matplotlib.is_interactive():
--> 119 draw_all()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
130 for manager in cls.get_all_fig_managers():
131 if force or manager.canvas.figure.stale:
--> 132 manager.canvas.draw_idle()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2054, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
2052 if not self._is_idle_drawing:
2053 with self._idle_draw_cntx():
-> 2054 self.draw(*args, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:408, in FigureCanvasAgg.draw(self)
404 # Acquire a lock on the shared font cache.
405 with RendererAgg.lock, \
406 (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
407 else nullcontext()):
--> 408 self.figure.draw(self.renderer)
409 # A GUI class may be need to update a window using this draw, so
410 # don't forget to call the superclass.
411 super().draw()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:543, in GeoAxes.draw(self, renderer, **kwargs)
535 """
536 Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.
537
(...)
540 been set.
541 """
542 # Shared processing steps
--> 543 self._draw_preprocess(renderer)
545 # XXX This interface needs a tidy up:
546 # image drawing on pan/zoom;
547 # caching the resulting image;
548 # buffering the result by 10%...;
549 if not self._done_img_factory:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes._draw_preprocess(self, renderer)
506 # If data has been added (i.e. autoscale hasn't been turned off)
507 # then we should autoscale the view.
508 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 509 self.autoscale_view()
511 # Adjust location of background patch so that new gridlines below are
512 # clipped correctly.
513 self.patch._adjust_location()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/formatters.py:339, in BaseFormatter.__call__(self, obj)
337 pass
338 else:
--> 339 return printer(obj)
340 # Finally look for special method names
341 method = get_real_method(obj, self.print_method)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/pylabtools.py:151, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
148 from matplotlib.backend_bases import FigureCanvasBase
149 FigureCanvasBase(fig)
--> 151 fig.canvas.print_figure(bytes_io, **kw)
152 data = bytes_io.getvalue()
153 if fmt == 'svg':
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2314, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2308 renderer = _get_renderer(
2309 self.figure,
2310 functools.partial(
2311 print_method, orientation=orientation)
2312 )
2313 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2314 self.figure.draw(renderer)
2316 if bbox_inches:
2317 if bbox_inches == "tight":
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:543, in GeoAxes.draw(self, renderer, **kwargs)
535 """
536 Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.
537
(...)
540 been set.
541 """
542 # Shared processing steps
--> 543 self._draw_preprocess(renderer)
545 # XXX This interface needs a tidy up:
546 # image drawing on pan/zoom;
547 # caching the resulting image;
548 # buffering the result by 10%...;
549 if not self._done_img_factory:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes._draw_preprocess(self, renderer)
506 # If data has been added (i.e. autoscale hasn't been turned off)
507 # then we should autoscale the view.
508 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 509 self.autoscale_view()
511 # Adjust location of background patch so that new gridlines below are
512 # clipped correctly.
513 self.patch._adjust_location()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
<Figure size 640x480 with 1 Axes>
Now that we’ve created new Shapely objects with the CartoPy CRS, we can use this to create a GeoDataFrame.
[7]:
df_aea = geopandas.GeoDataFrame(df['gdp_pp'], geometry=new_geometries,
crs=crs_new.proj4_init)
df_aea.plot()
[7]:
<AxesSubplot: >
We can even combine these into the same figure. Here we’ll plot the shapes of the countries with CartoPy. We’ll then calculate the centroid of each with GeoPandas and plot it on top.
[8]:
# Generate a CartoPy figure and add the countries to it
fig, ax = plt.subplots(subplot_kw={'projection': crs_new})
ax.add_geometries(new_geometries, crs=crs_new)
# Calculate centroids and plot
df_aea_centroids = df_aea.geometry.centroid
# Need to provide "zorder" to ensure the points are plotted above the polygons
df_aea_centroids.plot(ax=ax, markersize=5, color='r', zorder=10)
plt.show()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In [8], line 8
6 df_aea_centroids = df_aea.geometry.centroid
7 # Need to provide "zorder" to ensure the points are plotted above the polygons
----> 8 df_aea_centroids.plot(ax=ax, markersize=5, color='r', zorder=10)
10 plt.show()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/geopandas/geoseries.py:809, in GeoSeries.plot(self, *args, **kwargs)
807 @doc(plot_series)
808 def plot(self, *args, **kwargs):
--> 809 return plot_series(self, *args, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/geopandas/plotting.py:478, in plot_series(s, cmap, color, ax, figsize, aspect, **style_kwds)
475 values_ = values[point_idx] if cmap else None
476 color_ = expl_color[point_idx] if color_given else color
--> 478 _plot_point_collection(
479 ax, points, values_, color=color_, cmap=cmap, **style_kwds
480 )
482 plt.draw()
483 return ax
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/geopandas/plotting.py:306, in _plot_point_collection(ax, geoms, values, color, cmap, vmin, vmax, marker, markersize, **kwargs)
303 _expand_kwargs(kwargs, multiindex)
305 if "norm" not in kwargs:
--> 306 collection = ax.scatter(x, y, vmin=vmin, vmax=vmax, cmap=cmap, **kwargs)
307 else:
308 collection = ax.scatter(x, y, cmap=cmap, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:318, in _add_transform.<locals>.wrapper(self, *args, **kwargs)
313 raise ValueError(f'Invalid transform: Spherical {func.__name__} '
314 'is not supported - consider using '
315 'PlateCarree/RotatedPole.')
317 kwargs['transform'] = transform
--> 318 return func(self, *args, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:1753, in GeoAxes.scatter(self, *args, **kwargs)
1747 raise ValueError('Cartopy cannot currently do spherical '
1748 'scatter. The source CRS cannot be a '
1749 'geodetic, consider using the cyllindrical form '
1750 '(PlateCarree or RotatedPole).')
1752 result = matplotlib.axes.Axes.scatter(self, *args, **kwargs)
-> 1753 self.autoscale_view()
1754 return result
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:943, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
936 def autoscale_view(self, tight=None, scalex=True, scaley=True):
937 """
938 Autoscale the view limits using the data limits, taking into
939 account the projection of the geoaxes.
940
941 See :meth:`~matplotlib.axes.Axes.imshow()` for more details.
942 """
--> 943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
946 if scalex and self._autoscaleXon:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:2973, in _AxesBase.autoscale_view(self, tight, scalex, scaley)
2970 set_bound(x0, x1)
2971 # End of definition of internal function 'handle_single_axis'.
-> 2973 handle_single_axis(
2974 scalex, self._shared_axes["x"], 'x', self.xaxis, self._xmargin,
2975 x_stickies, self.set_xbound)
2976 handle_single_axis(
2977 scaley, self._shared_axes["y"], 'y', self.yaxis, self._ymargin,
2978 y_stickies, self.set_ybound)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:2970, in _AxesBase.autoscale_view.<locals>.handle_single_axis(scale, shared_axes, name, axis, margin, stickies, set_bound)
2968 if not self._tight:
2969 x0, x1 = locator.view_limits(x0, x1)
-> 2970 set_bound(x0, x1)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:3567, in _AxesBase.set_xbound(self, lower, upper)
3564 if upper is None and np.iterable(lower):
3565 lower, upper = lower
-> 3567 old_lower, old_upper = self.get_xbound()
3568 if lower is None:
3569 lower = old_lower
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:3539, in _AxesBase.get_xbound(self)
3529 def get_xbound(self):
3530 """
3531 Return the lower and upper x-axis bounds, in increasing order.
3532
(...)
3537 invert_xaxis, xaxis_inverted
3538 """
-> 3539 left, right = self.get_xlim()
3540 if left < right:
3541 return left, right
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:3597, in _AxesBase.get_xlim(self)
3577 def get_xlim(self):
3578 """
3579 Return the x-axis view limits.
3580
(...)
3595 be greater than the *right* value.
3596 """
-> 3597 return tuple(self.viewLim.intervalx)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:815, in _AxesBase.viewLim(self)
813 @property
814 def viewLim(self):
--> 815 self._unstale_viewLim()
816 return self._viewLim
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:810, in _AxesBase._unstale_viewLim(self)
808 for ax in self._shared_axes[name].get_siblings(self):
809 ax._stale_viewlims[name] = False
--> 810 self.autoscale_view(**{f"scale{name}": scale
811 for name, scale in need_scale.items()})
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:946, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
943 matplotlib.axes.Axes.autoscale_view(self, tight=tight,
944 scalex=scalex, scaley=scaley)
945 # Limit the resulting bounds to valid area.
--> 946 if scalex and self._autoscaleXon:
947 bounds = self.get_xbound()
948 self.set_xbound(max(bounds[0], self.projection.x_limits[0]),
949 min(bounds[1], self.projection.x_limits[1]))
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
Error in callback <function _draw_all_if_interactive at 0x7fad85300d30> (for post_execute):
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/pyplot.py:119, in _draw_all_if_interactive()
117 def _draw_all_if_interactive():
118 if matplotlib.is_interactive():
--> 119 draw_all()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
130 for manager in cls.get_all_fig_managers():
131 if force or manager.canvas.figure.stale:
--> 132 manager.canvas.draw_idle()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2054, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
2052 if not self._is_idle_drawing:
2053 with self._idle_draw_cntx():
-> 2054 self.draw(*args, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:408, in FigureCanvasAgg.draw(self)
404 # Acquire a lock on the shared font cache.
405 with RendererAgg.lock, \
406 (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
407 else nullcontext()):
--> 408 self.figure.draw(self.renderer)
409 # A GUI class may be need to update a window using this draw, so
410 # don't forget to call the superclass.
411 super().draw()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:558, in GeoAxes.draw(self, renderer, **kwargs)
553 self.imshow(img, extent=extent, origin=origin,
554 transform=factory.crs, *factory_args[1:],
555 **factory_kwargs)
556 self._done_img_factory = True
--> 558 return matplotlib.axes.Axes.draw(self, renderer=renderer, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:3107, in _AxesBase.draw(self, renderer)
3104 a.draw(renderer)
3105 renderer.stop_rasterizing()
-> 3107 mimage._draw_list_compositing_images(
3108 renderer, self, artists, self.figure.suppressComposite)
3110 renderer.close_group('axes')
3111 self.stale = False
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/feature_artist.py:147, in FeatureArtist.draw(self, renderer, *args, **kwargs)
145 extent = None
146 try:
--> 147 extent = ax.get_extent(feature_crs)
148 except ValueError:
149 warnings.warn('Unable to determine extent. Defaulting to global.')
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:814, in GeoAxes.get_extent(self, crs)
805 def get_extent(self, crs=None):
806 """
807 Get the extent (x0, x1, y0, y1) of the map in the given coordinate
808 system.
(...)
812
813 """
--> 814 p = self._get_extent_geom(crs)
815 r = p.bounds
816 x1, y1, x2, y2 = r
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:821, in GeoAxes._get_extent_geom(self, crs)
819 def _get_extent_geom(self, crs=None):
820 # Perform the calculations for get_extent(), which just repackages it.
--> 821 with self.hold_limits():
822 if self.get_autoscale_on():
823 self.autoscale_view()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/contextlib.py:135, in _GeneratorContextManager.__enter__(self)
133 del self.args, self.kwds, self.func
134 try:
--> 135 return next(self.gen)
136 except StopIteration:
137 raise RuntimeError("generator didn't yield") from None
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:491, in GeoAxes.hold_limits(self, hold)
488 data_lim = self.dataLim.frozen().get_points()
489 view_lim = self.viewLim.frozen().get_points()
490 other = (self.ignore_existing_data_limits,
--> 491 self._autoscaleXon, self._autoscaleYon)
492 try:
493 yield
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/formatters.py:339, in BaseFormatter.__call__(self, obj)
337 pass
338 else:
--> 339 return printer(obj)
340 # Finally look for special method names
341 method = get_real_method(obj, self.print_method)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/IPython/core/pylabtools.py:151, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
148 from matplotlib.backend_bases import FigureCanvasBase
149 FigureCanvasBase(fig)
--> 151 fig.canvas.print_figure(bytes_io, **kw)
152 data = bytes_io.getvalue()
153 if fmt == 'svg':
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/backend_bases.py:2314, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2308 renderer = _get_renderer(
2309 self.figure,
2310 functools.partial(
2311 print_method, orientation=orientation)
2312 )
2313 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2314 self.figure.draw(renderer)
2316 if bbox_inches:
2317 if bbox_inches == "tight":
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:74, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
72 @wraps(draw)
73 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 74 result = draw(artist, renderer, *args, **kwargs)
75 if renderer._rasterizing:
76 renderer.stop_rasterizing()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/figure.py:3074, in Figure.draw(self, renderer)
3071 # ValueError can occur when resizing a window.
3073 self.patch.draw(renderer)
-> 3074 mimage._draw_list_compositing_images(
3075 renderer, self, artists, self.suppressComposite)
3077 for sfig in self.subfigs:
3078 sfig.draw(renderer)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:558, in GeoAxes.draw(self, renderer, **kwargs)
553 self.imshow(img, extent=extent, origin=origin,
554 transform=factory.crs, *factory_args[1:],
555 **factory_kwargs)
556 self._done_img_factory = True
--> 558 return matplotlib.axes.Axes.draw(self, renderer=renderer, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/axes/_base.py:3107, in _AxesBase.draw(self, renderer)
3104 a.draw(renderer)
3105 renderer.stop_rasterizing()
-> 3107 mimage._draw_list_compositing_images(
3108 renderer, self, artists, self.figure.suppressComposite)
3110 renderer.close_group('axes')
3111 self.stale = False
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together
134 image_group = []
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/matplotlib/artist.py:51, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
48 if artist.get_agg_filter() is not None:
49 renderer.start_filter()
---> 51 return draw(artist, renderer)
52 finally:
53 if artist.get_agg_filter() is not None:
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/feature_artist.py:147, in FeatureArtist.draw(self, renderer, *args, **kwargs)
145 extent = None
146 try:
--> 147 extent = ax.get_extent(feature_crs)
148 except ValueError:
149 warnings.warn('Unable to determine extent. Defaulting to global.')
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:814, in GeoAxes.get_extent(self, crs)
805 def get_extent(self, crs=None):
806 """
807 Get the extent (x0, x1, y0, y1) of the map in the given coordinate
808 system.
(...)
812
813 """
--> 814 p = self._get_extent_geom(crs)
815 r = p.bounds
816 x1, y1, x2, y2 = r
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:821, in GeoAxes._get_extent_geom(self, crs)
819 def _get_extent_geom(self, crs=None):
820 # Perform the calculations for get_extent(), which just repackages it.
--> 821 with self.hold_limits():
822 if self.get_autoscale_on():
823 self.autoscale_view()
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/contextlib.py:135, in _GeneratorContextManager.__enter__(self)
133 del self.args, self.kwds, self.func
134 try:
--> 135 return next(self.gen)
136 except StopIteration:
137 raise RuntimeError("generator didn't yield") from None
File ~/checkouts/readthedocs.org/user_builds/geopandas/conda/v0.12.0/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:491, in GeoAxes.hold_limits(self, hold)
488 data_lim = self.dataLim.frozen().get_points()
489 view_lim = self.viewLim.frozen().get_points()
490 other = (self.ignore_existing_data_limits,
--> 491 self._autoscaleXon, self._autoscaleYon)
492 try:
493 yield
AttributeError: 'GeoAxesSubplot' object has no attribute '_autoscaleXon'
<Figure size 640x480 with 1 Axes>