Search code examples
pythonpython-3.xpandasgeneratorcartopy

Get information about a specific country from Cartopy shapereader records


I'm plotting world map-data at a country level, using the geometries provided in the Cartopy shapereader natural earth records:

import cartopy.io.shapereader as shpreader
import pandas as pd

my_data = pd.read_csv("my_data.csv", index_col = 0)

shpfilename = shpreader.natural_earth(resolution='50m',
                                      category='cultural',
                                      name='admin_0_countries')
reader = shpreader.Reader(shpfilename)
countries = reader.records()

for country in countries:

   sovgt = country.attribute["SOVEREIGNT"]

   plot_val = my_data.loc[sovgt]

   ax.add_geometries([country.geometry],
                     ccrs.PlateCarree(),
                     facecolor = cmap(plot_val))

My question is: is there a neater way to extract data about a specific country from countries given that it is a generator. It would be highly preferable if I could do something like

for country in my_data.index.to_list():
   
   geometry = countries[country].geometry

   ax.add_geometries(geometry,
                     ccrs.PlateCarree(),
                     facecolor = cmap(plot_val))

The reason for this is that my index of countries in my_data does not align with the names of countries in countries. I have a tiered list of try:, except KeyError: with dicts of names to handle all the dependant states etc that aren't listed seperately in my dataset.

This is probably a more general question about generator objects. Apologies if it also a stupid question.


Solution

  • I don't have any insight for generators, but I answered a related question about colouring a nation on a map from a list of nation names and values https://stackoverflow.com/a/61525984/13208790

    The key step is reading the natural earth data into geopandas, so you have a dataframe rather than a generator to work with. Not very elegant but should work:

    import geopandas
    from cartopy.io import shapereader
    shpfilename = shapereader.natural_earth('50m', 'cultural', 'admin_0_countries')
    df = geopandas.read_file(shpfilename)
    df.head()