Skip to content

Fix base mesh plotting with cartopy 0.25 and matplotlib 3.11 - #972

Merged
xylar merged 2 commits into
MPAS-Dev:mainfrom
xylar:fix-base-mesh-plotting
Jul 25, 2026
Merged

Fix base mesh plotting with cartopy 0.25 and matplotlib 3.11#972
xylar merged 2 commits into
MPAS-Dev:mainfrom
xylar:fix-base-mesh-plotting

Conversation

@xylar

@xylar xylar commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

Creating gridline labels with draw_labels=True and then hiding some of them (gl.top_labels = False, etc.) confuses cartopy's title placement. GeoAxes._update_title_position() scans gl.top_label_artists whenever gl.geo_labels is true (the default), so the hidden top labels are still included. During a draw, their tight bounding boxes are infinite, so the title ends up at y = inf and the axes tight bounding box becomes non-finite.

The NaN then cascades: tight_layout() gives the axes a NaN position, the "geo" spine path becomes all NaN, and cartopy's gridliner hands NaN vertices to shapely, which raises

GEOSException: IllegalArgumentException: Points of LinearRing do not
form a closed linestring

Instead, only request the labels we actually want. In _plot_cell_width(), that means draw_labels=['left', 'bottom']. In the arrm10to60 and wc14 mesh plots, all four label sets were hidden, so draw_labels=False.

Also drop the redundant fig.canvas.draw() and plt.tight_layout() from _plot_cell_width(), since bbox_inches='tight' already crops the figure. Removing tight_layout() alone is not sufficient: without the label fix, the title is silently dropped and bbox_inches='tight' crops to a garbage bounding box, saving only the colorbar.

List-valued draw_labels requires cartopy 0.22, so add that constraint.

Along the way, satisfy the pre-commit hooks on the arrm10to60 file: isort reorders its imports and flake8 flags a pre-existing F523 (a '{0} x {0}'.format(dlon, dlat) that never used dlat), now an f-string.

This merge also fixes an unrelated provenance issue caused by the transition from conda to pixi.

Checklist

  • Document (in a comment titled Testing in this PR) any testing that was used to verify the changes

Creating gridline labels with draw_labels=True and then hiding some of
them (gl.top_labels = False, etc.) confuses cartopy's title placement.
GeoAxes._update_title_position() scans gl.top_label_artists whenever
gl.geo_labels is true (the default), so the hidden top labels are still
included.  During a draw, their tight bounding boxes are infinite, so
the title ends up at y = inf and the axes tight bounding box becomes
non-finite.

The NaN then cascades: tight_layout() gives the axes a NaN position, the
"geo" spine path becomes all NaN, and cartopy's gridliner hands NaN
vertices to shapely, which raises

    GEOSException: IllegalArgumentException: Points of LinearRing do not
    form a closed linestring

Instead, only request the labels we actually want.  In
_plot_cell_width(), that means draw_labels=['left', 'bottom'].  In the
arrm10to60 and wc14 mesh plots, all four label sets were hidden, so
draw_labels=False.

Also drop the redundant fig.canvas.draw() and plt.tight_layout() from
_plot_cell_width(), since bbox_inches='tight' already crops the figure.
Removing tight_layout() alone is not sufficient: without the label fix,
the title is silently dropped and bbox_inches='tight' crops to a garbage
bounding box, saving only the colorbar.

List-valued draw_labels requires cartopy 0.22, so add that constraint.

Along the way, satisfy the pre-commit hooks on the arrm10to60 file:
isort reorders its imports and flake8 flags a pre-existing F523 (a
'{0} x {0}'.format(dlon, dlat) that never used dlat), now an f-string.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@xylar

xylar commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator Author

Testing

I'm running the EC30to60 grid through its paces in:

/lcrc/group/e3sm/ac.xylar/compass_2.0/chrysalis/test_20260725/ec30to60_2

The mesh, WOA23/init and WOA23/performance_test tests passed.

The switch from conda to pixi means the `conda` command is no longer
available, so getting package versions for MPAS mesh metadata with
`conda list` fails with a `FileNotFoundError`.  Instead, look up conda
package records in the environment's `conda-meta` directory, falling
back on python package metadata for packages installed with pip (namely
compass itself).

Also, JIGSAW is now built as part of the `jigsawpy` package, so the two
share a version.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@xylar xylar added bug Something isn't working ocean labels Jul 25, 2026
@xylar xylar self-assigned this Jul 25, 2026
@xylar
xylar merged commit 9fde57e into MPAS-Dev:main Jul 25, 2026
5 checks passed
@xylar
xylar deleted the fix-base-mesh-plotting branch July 25, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ocean

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant