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.
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()
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
Windows 10
0.17.0
4.64.14
19.1
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()

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

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
md5-48c59c1876c36ff974d2ae2378d657f0
cartopy 0.17.0 py36h929c6f0_1004 conda-forge
md5-d5705a1cb916ca68625d50c03f0dde5b
matplotlib 3.1.0 py36_1 conda-forge
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%
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.
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.
Thank you so much @greglucas! That solves the problem I was having with the code.
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.
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]
would do the trick. But that is untested. Feel free to open a PR if you'd like!
Most helpful comment
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:it works for me without errors. An unfortunate pluralization of geometries() requiring an iterable I suppose.