Hi,
I'm plotting trends I've computed from a variety of CMIP6 models. They all work fine, except one model (FGOALS) gives me this error:
fig, (axs) = plt.subplots(ncols=1, nrows=1, figsize=[5, 5], subplot_kw={"projection": ccrs.Robinson()})
FGOALS_g3_histNat_trends.polyfit_coefficients.plot(transform=ccrs.PlateCarree(), cmap="RdBu_r", robust=True)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[132], line 2
1 fig, (axs) = plt.subplots(ncols=1, nrows=1, figsize=[5, 5], subplot_kw={"projection": ccrs.Robinson()})
----> 2 FGOALS_g3_histNat_trends.polyfit_coefficients.plot(transform=ccrs.PlateCarree(), cmap="RdBu_r", robust=True)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/xarray/plot/accessor.py:48, in DataArrayPlotAccessor.__call__(self, **kwargs)
46 @functools.wraps(dataarray_plot.plot, assigned=("__doc__", "__annotations__"))
47 def __call__(self, **kwargs) -> Any:
---> 48 return dataarray_plot.plot(self._da, **kwargs)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/xarray/plot/dataarray_plot.py:309, in plot(darray, row, col, col_wrap, ax, hue, subplot_kws, **kwargs)
305 plotfunc = hist
307 kwargs["ax"] = ax
--> 309 return plotfunc(darray, **kwargs)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/xarray/plot/dataarray_plot.py:1602, in _plot2d.<locals>.newplotfunc(***failed resolving arguments***)
1598 raise ValueError("plt.imshow's `aspect` kwarg is not available in xarray")
1600 ax = get_axis(figsize, size, aspect, ax, **subplot_kws)
-> 1602 primitive = plotfunc(
1603 xplt,
1604 yplt,
1605 zval,
1606 ax=ax,
1607 cmap=cmap_params["cmap"],
1608 vmin=cmap_params["vmin"],
1609 vmax=cmap_params["vmax"],
1610 norm=cmap_params["norm"],
1611 **kwargs,
1612 )
1614 # Label the plot with metadata
1615 if add_labels:
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/xarray/plot/dataarray_plot.py:2322, in pcolormesh(x, y, z, ax, xscale, yscale, infer_intervals, **kwargs)
2319 y = _infer_interval_breaks(y, axis=0, scale=yscale)
2321 ax.grid(False)
-> 2322 primitive = ax.pcolormesh(x, y, z, **kwargs)
2324 # by default, pcolormesh picks "round" values for bounds
2325 # this results in ugly looking plots with lots of surrounding whitespace
2326 if not hasattr(ax, "projection") and x.ndim == 1 and y.ndim == 1:
2327 # not a cartopy geoaxis
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:315, in _add_transform.<locals>.wrapper(self, *args, **kwargs)
310 raise ValueError(f'Invalid transform: Spherical {func.__name__} '
311 'is not supported - consider using '
312 'PlateCarree/RotatedPole.')
314 kwargs['transform'] = transform
--> 315 return func(self, *args, **kwargs)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1783, in GeoAxes.pcolormesh(self, *args, **kwargs)
1781 result = super().pcolormesh(*args, **kwargs)
1782 # Wrap the quadrilaterals if necessary
-> 1783 result = self._wrap_quadmesh(result, **kwargs)
1784 # Re-cast the QuadMesh as a GeoQuadMesh to enable future wrapping
1785 # updates to the collection as well.
1786 result.__class__ = cartopy.mpl.geocollection.GeoQuadMesh
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1973, in GeoAxes._wrap_quadmesh(self, collection, **kwargs)
1971 pcolor_col.set_array(pcolor_data[mask].ravel())
1972 else:
-> 1973 pcolor_col = self.pcolor(coords[..., 0], coords[..., 1],
1974 pcolor_data, zorder=zorder,
1975 **kwargs)
1976 # Currently pcolor_col.get_array() will return a compressed array
1977 # and warn unless we explicitly set the 2D array. This should be
1978 # unnecessary with future matplotlib versions.
1979 pcolor_col.set_array(pcolor_data)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:315, in _add_transform.<locals>.wrapper(self, *args, **kwargs)
310 raise ValueError(f'Invalid transform: Spherical {func.__name__} '
311 'is not supported - consider using '
312 'PlateCarree/RotatedPole.')
314 kwargs['transform'] = transform
--> 315 return func(self, *args, **kwargs)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:2012, in GeoAxes.pcolor(self, *args, **kwargs)
2009 result = super().pcolor(*args, **kwargs)
2011 # Update the datalim for this pcolor.
-> 2012 limits = result.get_datalim(self.transData)
2013 self.update_datalim(limits)
2015 self.autoscale_view()
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/matplotlib/collections.py:267, in Collection.get_datalim(self, transData)
264 return transforms.Bbox.null()
266 if not transform.is_affine:
--> 267 paths = [transform.transform_path_non_affine(p) for p in paths]
268 # Don't convert transform to transform.get_affine() here because
269 # we may have transform.contains_branch(transData) but not
270 # transforms.get_affine().contains_branch(transData). But later,
271 # be careful to only apply the affine part that remains.
273 offsets = self.get_offsets()
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/matplotlib/collections.py:267, in <listcomp>(.0)
264 return transforms.Bbox.null()
266 if not transform.is_affine:
--> 267 paths = [transform.transform_path_non_affine(p) for p in paths]
268 # Don't convert transform to transform.get_affine() here because
269 # we may have transform.contains_branch(transData) but not
270 # transforms.get_affine().contains_branch(transData). But later,
271 # be careful to only apply the affine part that remains.
273 offsets = self.get_offsets()
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/matplotlib/transforms.py:2426, in CompositeGenericTransform.transform_path_non_affine(self, path)
2424 return path
2425 elif not self._a.is_affine and self._b.is_affine:
-> 2426 return self._a.transform_path_non_affine(path)
2427 else:
2428 return self._b.transform_path_non_affine(
2429 self._a.transform_path(path))
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:186, in InterProjectionTransform.transform_path_non_affine(self, src_path)
182 geoms = cpatch.path_to_geos(src_path,
183 getattr(self, 'force_path_ccw', False))
185 for geom in geoms:
--> 186 proj_geom = self.target_projection.project_geometry(
187 geom, self.source_projection)
188 transformed_geoms.append(proj_geom)
190 if not transformed_geoms:
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/crs.py:817, in Projection.project_geometry(self, geometry, src_crs)
815 if not method_name:
816 raise ValueError(f'Unsupported geometry type {geom_type!r}')
--> 817 return getattr(self, method_name)(geometry, src_crs)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/crs.py:972, in Projection._project_polygon(self, polygon, src_crs)
968 rings.extend(self._attach_lines_to_boundary(multi_lines, is_ccw))
970 # Resolve all the inside vs. outside rings, and convert to the
971 # final MultiPolygon.
--> 972 return self._rings_to_multi_polygon(rings, is_ccw)
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/cartopy/crs.py:1233, in Projection._rings_to_multi_polygon(self, rings, is_ccw)
1230 polygon_bits.append(polygon)
1232 if polygon_bits:
-> 1233 multi_poly = sgeom.MultiPolygon(polygon_bits)
1234 else:
1235 multi_poly = sgeom.MultiPolygon()
File /glade/work/mberdahl/miniconda/envs/NPL_forCloud/lib/python3.11/site-packages/shapely/geometry/multipolygon.py:79, in MultiPolygon.__new__(self, polygons)
77 ob = polygons[i]
78 if not isinstance(ob, polygon.Polygon):
---> 79 shell = ob[0]
80 if len(ob) > 1:
81 holes = ob[1]
TypeError: 'GeometryCollection' object is not subscriptable
It appears to be triggered when including transform=ccrs.PlateCarree().
This looks like this might be a bug in Cartopy. There's a suggested workaround in this issue on GitHub. I'd give that a try.
Katelyn FitzGerald said:
This looks like this might be a bug in Cartopy. There's a suggested workaround in this issue on GitHub. I'd give that a try.
@Katelyn FitzGerald thanks. Unfortunately, it appears that the recommendation to use the transform_first argument is only for contouring. I get the error:
QuadMesh.set() got an unexpected keyword argument 'transform_first'
Bummer, I was worried that may be the case.
If you want to point me to the script / notebook, I can try to take a deeper look next week.
Katelyn FitzGerald said:
Bummer, I was worried that may be the case.
If you want to point me to the script / notebook, I can try to take a deeper look next week.
@Katelyn FitzGerald , thanks that would be great!
You can take a look at my notebook here:
/glade/u/home/mberdahl/Gerard/Hist/NorESM/ExptWithDataTrees-Copy1.ipynb
Thanks!
It's not a good long term fix, but downgrading shapely<2.0 should fix your problem for now. You can do something like conda install 'shapely<2'
to update your environment.
It looks like something in the last major version release of shapely broke things in Cartopy that have yet to be been fixed. I'll add some additional notes to the related issue on Cartopy's GitHub repository.
Katelyn FitzGerald said:
It's not a good long term fix, but downgrading shapely<2.0 should fix your problem for now. You can do something like
conda install 'shapely<2'
to update your environment.It looks like something in the last major version release of shapely broke things in Cartopy that have yet to be been fixed. I'll add some additional notes to the related issue on Cartopy's GitHub repository.
Thanks for looking into this. I tried to downgrade shapely, but ran into a compatibility issue.
Could not solve for environment specs
The following packages are incompatible
├─ geos 3.12.0.* is requested and can be installed;
├─ pin-1 is installable and it requires
│ └─ python 3.11.* , which can be installed;
└─ shapely <2 is not installable because there are no viable options
├─ shapely [1.5.13|1.5.15|1.5.16|1.6.4|1.7.0] would require
│ └─ python [2.7* |>=2.7,<2.8.0a0 ], which conflicts with any installable versions previously reported;
├─ shapely [1.5.13|1.5.15|1.5.16] would require
│ └─ python 3.4* , which conflicts with any installable versions previously reported;
├─ shapely [1.5.13|1.5.15|1.5.16] would require
│ └─ python 3.5* , which conflicts with any installable versions previously reported;
├─ shapely [1.5.16|1.5.17] would require
│ └─ geos 3.4.* , which does not exist (perhaps a missing channel);
├─ shapely 1.5.17 would require
│ └─ geos 3.5.* , which does not exist (perhaps a missing channel);
├─ shapely [1.5.17|1.6.0|1.6.1|1.6.2] would require
│ └─ geos 3.5.1 , which does not exist (perhaps a missing channel);
├─ shapely [1.6.2|1.6.3|1.6.4] would require
│ └─ geos 3.6.2 , which does not exist (perhaps a missing channel);
├─ shapely 1.6.4 would require
│ └─ geos >=3.6.2,<3.6.3.0a0 , which does not exist (perhaps a missing channel);
├─ shapely [1.6.4|1.7.0|1.7.1] would require
│ └─ python >=3.6,<3.7.0a0 , which conflicts with any installable versions previously reported;
├─ shapely [1.6.4|1.7.0|...|1.8.5] would require
│ └─ python >=3.7,<3.8.0a0 , which conflicts with any installable versions previously reported;
├─ shapely [1.6.4|1.7.0|...|1.8.5] would require
│ └─ python >=3.8,<3.9.0a0 , which conflicts with any installable versions previously reported;
├─ shapely [1.7.1|1.8.0|...|1.8.5] would require
│ └─ python >=3.9,<3.10.0a0 , which conflicts with any installable versions previously reported;
├─ shapely [1.8.0|1.8.1|...|1.8.5] would require
│ └─ python >=3.10,<3.11.0a0 , which conflicts with any installable versions previously reported;
├─ shapely 1.8.5 would require
│ └─ geos >=3.11.1,<3.11.2.0a0 , which conflicts with any installable versions previously reported;
└─ shapely 1.8.5 would require
└─ geos >=3.11.0,<3.11.1.0a0 , which conflicts with any installable versions previously reported.
Last updated: May 16 2025 at 17:14 UTC