Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colouring countries #1303

Closed
Especuloide opened this issue May 4, 2019 · 9 comments · Fixed by #1999
Closed

Colouring countries #1303

Especuloide opened this issue May 4, 2019 · 9 comments · Fixed by #1999

Comments

@Especuloide
Copy link

Especuloide commented May 4, 2019

Description

Cartopy stop working when you try to color some countries, like Austria (AUT), Albania among others in Europe as far as I could see. My maps heve been working fine until couple last update on april.

Code to reproduce

import matplotlib.pyplot as plt
import cartopy
import cartopy.io.shapereader as shpreader
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature


def area(ax, iso, clr) :
  
    shp = shpreader.natural_earth(resolution='10m',category='cultural',name='admin_0_countries')
    reader = shpreader.Reader(shp)
    countries = reader.records()
  
    for n in countries :
        if n.attributes['ADM0_A3'] == iso: 
            ax.add_geometries(n.geometry, ccrs.PlateCarree(),
                              facecolor=clr, alpha = 1.00, linewidth =0.15, edgecolor = "black",
                              label=n.attributes['ADM0_A3']) 
          
    return ax

iso3 = ['USA','CAN','RUS','GBR','ISL','FRA','ITA','AUT'] # works fine with this codes
#iso3 = ['USA','CAN','RUS','GBR','ISL','FRA','ITA','CHN','AUT'] # error message - due to  "AUT" - Austria 

def main():
    ax = plt.axes(projection=ccrs.Miller())
    
    states_provinces = cfeature.NaturalEarthFeature(
        category='cultural',
        name='admin_1_states_provinces_lines',
        scale='50m',
        facecolor='none')

    ax.add_feature(cfeature.LAND)
    ax.add_feature(cfeature.COASTLINE)
    ax.add_feature(states_provinces, edgecolor='gray')

    for n in iso3 :
        area(ax,n,"red")         
             
    plt.show()


if __name__ == '__main__':
    main()

Traceback

File "C:\ProgramData\Anaconda3\lib\site-packages\cartopy\mpl\geoaxes.py", line 588, in add_geometries
  feature = cartopy.feature.ShapelyFeature(geoms, crs, **kwargs)

File "C:\ProgramData\Anaconda3\lib\site-packages\cartopy\feature\__init__.py", line 231, in __init__
  self._geoms = tuple(geometries)

TypeError: 'Polygon' object is not iterable
Full environment definition

Operating system

Windows 10

Cartopy version

0.17.0

conda list

4.64.14

pip list

19.1

@eleanorlutz
Copy link

I'm not sure if this is helpful, but I just updated cartopy and I wasn't able to replicate the issue on my computer (Mac, cartopy v0.17.0, matplotlib v3.0.2). So it might be an issue that's more specific to your system (Windows OS or your environment).

import matplotlib.pyplot as plt
import cartopy.io.shapereader as shpreader
import cartopy.crs as ccrs
import cartopy.feature as cfeature
%matplotlib inline

def area(ax, iso, clr) :
    shp = shpreader.natural_earth(resolution='10m',category='cultural',
                                  name='admin_0_countries')
    reader = shpreader.Reader(shp)
    for n in reader.records() :
        if n.attributes['ADM0_A3'] == iso: 
            ax.add_geometries(n.geometry, ccrs.PlateCarree(), facecolor=clr, 
                              alpha = 1.00, linewidth =0.15, edgecolor = "black",
                              label=n.attributes['ADM0_A3']) 
    return ax

iso3 = ['USA','CAN','RUS','GBR','ISL','FRA','ITA','CHN','AUT']

ax = plt.axes(projection=ccrs.Miller())
ax.add_feature(cfeature.COASTLINE)

for n in iso3 :
    area(ax, n, "red")
    
plt.show()

Unknown

@Especuloide
Copy link
Author

Dear Eleanor,

I tried to reset Spyder but the problem persists. On the other hand when I run Python via Canopy and It works fine. Something might no be right with my Anaconda/pyder installation.

Anyway, thank you very much Eleanor.

Roberval

_EuropeTelephoneLines

@Swanson-Hysell
Copy link

I get the same TypeError: 'Polygon' object is not iterable error using:

cartopy                   0.17.0          py36h929c6f0_1004    conda-forge
matplotlib                3.0.3                    py36_0    conda-forge

and also with an update to:

cartopy                   0.17.0          py36h929c6f0_1004    conda-forge
matplotlib                3.1.0                    py36_1    conda-forge

@Swanson-Hysell
Copy link

I downgraded to cartopy 0.16 (which also downgraded associated packages as follows) and in doing so am able to iterate through the shpreader records

Here are the relevant package versions associated with the downgrade:

pyproj-1.9.5.1       | 54 KB     | ##################################### | 100% 
json-c-0.12.1        | 47 KB     | ##################################### | 100% 
geotiff-1.4.2        | 1.1 MB    | ##################################### | 100% 
shapely-1.6.4        | 302 KB    | ##################################### | 100% 
libgdal-2.2.2        | 15.2 MB   | ##################################### | 100% 
gdal-2.2.2           | 824 KB    | ##################################### | 100% 
blas-2.10            | 7 KB      | ##################################### | 100% 
netcdf4-1.3.1        | 749 KB    | ##################################### | 100% 
proj4-4.9.3          | 3.1 MB    | ##################################### | 100% 
libspatialite-4.3.0a | 3.0 MB    | ##################################### | 100% 
geos-3.6.2           | 1.4 MB    | ##################################### | 100% 
cartopy-0.16.0       | 1.7 MB    | ##################################### | 100% 
basemap-1.2.0        | 15.1 MB   | ##################################### | 100% 
fiona-1.7.13         | 756 KB    | ##################################### | 100%

@ccmorin
Copy link

ccmorin commented Aug 10, 2019

I had the same issue with cartopy 0.17 and matplotlib 3.0.2 . I ended up downgrading to 0.16 (and upgrading matplotlib to 3.1.0). This fixed the error. I'm running the code in Atom with Hydrogen on a Mac.

@greglucas
Copy link
Contributor

I think the real problem here is that you're passing in a single geometry to the plot, which can't be iterated upon.

If you change your code to put the single geometry in a list [n.geometry] here:

            ax.add_geometries([n.geometry], ccrs.PlateCarree(),
                              facecolor=clr, alpha = 1.00, linewidth =0.15, edgecolor = "black",
                              label=n.attributes['ADM0_A3'])

it works for me without errors. An unfortunate pluralization of geometries() requiring an iterable I suppose.

@Swanson-Hysell
Copy link

Thank you so much @greglucas! That solves the problem I was having with the code.

@Swanson-Hysell
Copy link

This thread is probably not the most descriptively names to deal with this issue, but it does seem that allowing add_geometeries() to plot non-iterable (single) objects makes sense.

@greglucas
Copy link
Contributor

Glad that helped! I agree with you that it would be nice to not force plural here. My guess is something like:

if isinstance(geometries, sgeom.base.BaseGeometry, sgeom.base.BaseMultipartGeometry)):
    geometries = [geometries]

near here:

self._geoms = tuple(geometries)

would do the trick. But that is untested. Feel free to open a PR if you'd like!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants