Skip to content

Choropleth map from geopandas GeoDataFrame #160

@burggraaff

Description

@burggraaff

Is your feature request related to a problem? Please describe.

Hi, I'm trying to plot a choropleth map from a geopandas GeoDataFrame into an earthkit-plots (v0.5.2) figure, but I'm not sure how to.

I have attached a simple example file which I made by combining data from the CDS dataset sis-european-wind-storm-reanalysis with NUTS shapefiles from GISCO: choropleth_example.json

import geopandas as gpd
import earthkit.data as ekd
import earthkit.plots as ekp
from matplotlib import pyplot as plt

data = gpd.read_file("choropleth_example.json")

This is easily plotted with geopandas itself:

data.plot.geo("storms_number")
Image

However, when I try to use earthkit-plots, I either get an error or an empty figure.

Trying to plot from geopandas into an earthkit-plots figure:

fig = ekp.Figure(rows=1, columns=1, size=(4, 4))
subplot = fig.add_map(domain="Europe")
data.plot.geo("storms_number", ax=subplot.ax, transform=subplot.crs)
plt.show()
plt.close()
Image

(same result with or without the transform= kwarg, also tried zorder=)

Trying to use Map.shapes:

fig = ekp.Figure(rows=1, columns=1, size=(4, 4))
subplot = fig.add_map(domain="Europe")
subplot.shapes(data)
plt.show()
plt.close()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_4243/2616145229.py in ?()
      1 fig = ekp.Figure(rows=1, columns=1, size=(4, 4))
      2 subplot = fig.add_map(domain="Europe")
----> 3 subplot.shapes(data)
      4 plt.show()
      5 plt.close()

~/git/c3s2-eqc-quality-assessment/.venv/lib/python3.12/site-packages/earthkit/plots/schemas.py in ?(*args, **kwargs)
    137             @functools.wraps(function)
    138             def wrapper(*args, **kwargs):
--> 139                 return function(*args, **self._update_kwargs(kwargs, keys))

~/git/c3s2-eqc-quality-assessment/.venv/lib/python3.12/site-packages/earthkit/plots/components/maps.py in ?(self, shapes, transform, adjust_labels, labels, *args, **kwargs)
    732         """
    733         if isinstance(shapes, str):
    734             shapes = shpreader.Reader(shapes)
    735         results = self.ax.add_geometries(
--> 736             shapes.geometries(), transform, *args, **kwargs
    737         )
    738         if labels:
    739             label_key = labels if isinstance(labels, str) else None

~/git/c3s2-eqc-quality-assessment/.venv/lib/python3.12/site-packages/pandas/core/generic.py in ?(self, name)
   6314             and name not in self._accessors
   6315             and self._info_axis._can_hold_identifiers_and_holds_name(name)
   6316         ):
   6317             return self[name]
-> 6318         return object.__getattribute__(self, name)

AttributeError: 'GeoDataFrame' object has no attribute 'geometries'

Same as above, but using earthkit-data to read the file:

data = ekd.from_source("file", "choropleth_example.json")

fig = ekp.Figure(rows=1, columns=1, size=(4, 4))
subplot = fig.add_map(domain="Europe")
subplot.shapes(data)
plt.show()
plt.close()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[4], line 5
      3 fig = ekp.Figure(rows=1, columns=1, size=(4, 4))
      4 subplot = fig.add_map(domain="Europe")
----> 5 subplot.shapes(data)
      6 plt.show()
      7 plt.close()

File ~/git/c3s2-eqc-quality-assessment/.venv/lib/python3.12/site-packages/earthkit/plots/schemas.py:139, in Schema.apply.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
    137 @functools.wraps(function)
    138 def wrapper(*args, **kwargs):
--> 139     return function(*args, **self._update_kwargs(kwargs, keys))

File ~/git/c3s2-eqc-quality-assessment/.venv/lib/python3.12/site-packages/earthkit/plots/components/maps.py:736, in Map.shapes(self, shapes, transform, adjust_labels, labels, *args, **kwargs)
    733 if isinstance(shapes, str):
    734     shapes = shpreader.Reader(shapes)
    735 results = self.ax.add_geometries(
--> 736     shapes.geometries(), transform, *args, **kwargs
    737 )
    738 if labels:
    739     label_key = labels if isinstance(labels, str) else None

AttributeError: 'File' object has no attribute 'geometries'

Jupyter notebook containing all of the above: choropleth.ipynb

Describe the solution you'd like

If this functionality does not exist, could you please add it?
If it does, could you please add an example to the documentation?

There's Working with shapefiles but that only shows how to plot shapes, not colour them etc. and it was not clear to me from the Map.shapes documentation whether that function supports this. Moreover, I couldn't get it to work in the first place (see above). I saw the Using GeoJSON and GeoPandas data example in the earthkit-data documentation but I'm not sure if this is relevant.

Describe alternatives you've considered

No response

Additional context

No response

Organisation

National Physical Laboratory

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions