Stream: general

Topic: FGOALS model throws error when trying to use projection


view this post on Zulip Mira Berdahl (May 03 2024 at 22:39):

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().

view this post on Zulip Katelyn FitzGerald (May 03 2024 at 23:19):

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.

view this post on Zulip Mira Berdahl (May 04 2024 at 00:27):

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'

view this post on Zulip Katelyn FitzGerald (May 04 2024 at 00:36):

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.

view this post on Zulip Mira Berdahl (May 04 2024 at 19:38):

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!

view this post on Zulip Katelyn FitzGerald (May 06 2024 at 18:38):

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.

view this post on Zulip Mira Berdahl (May 06 2024 at 18:55):

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