Skip to content

Conversation

@QuLogic
Copy link
Member

@QuLogic QuLogic commented Dec 18, 2019

Rationale

This is a followup to #1213, converting the Cartopy-specific background_patch into the usual Axes.patch from Matplotlib.

Implications

Unfortunately, this breaks several tests. Most of these are due to clipping bugs upstream in Matplotlib (at least matplotlib/matplotlib#15952). I'm hoping to get these fixed, regenerate any test images with the new version if necessary, then just increase tolerance for the old images (most of them are small changes anyway.)

Since we aren't using the default patch, this should fix tight layout too, but I haven't yet tested it.

Fixes #1207.

@dopplershift
Copy link
Contributor

In general this looks good. Everything seems cleaner. Waiting to see what the image changes look like..

@QuLogic
Copy link
Member Author

QuLogic commented Dec 20, 2019

Currently, it's mostly the same as the referenced Matplotlib issue, plus matplotlib/matplotlib#15946.

@greglucas
Copy link
Contributor

Looks great to me. I just pulled your code and this does appear to fix the tight layout issues. Specifically, #1207 looks good to me locally with your changes.

With constrained_layout it appears much better, but there is still a slight shift between the two figures.

import cartopy
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

f, ax1 = plt.subplots(1, 1, constrained_layout=True,
                      subplot_kw=dict(projection=ccrs.PlateCarree()))

f.savefig('mpl-1.png')
f.savefig('mpl-2.png')

@QuLogic
Copy link
Member Author

QuLogic commented Jan 7, 2020

For reference, I've committed the changed images and the diffs here. To understand most of the changes, you have to know that Matplotlib draws spines at 0.8 linewidth, so there's usually one middle pixel full black, and two surrounding pixels of grey. Correctly clipped artists should end at the inner grey or the black pixel, and the inner grey one might be shaded a bit by the artist's colour. If not clipped correctly, then they might mix into the outer grey pixels, or only mix into the inner grey one via antialiasing (and thus a bit darker than they should be.)

My analysis of the changes is:

  • contour_label.png 0.9719825101307121. The difference is along the left/right edges, but honestly can't see it.
  • gshhs_coastlines.png 0.006666666666666667. Most tests use 0.5 tolerance, so I just increased that. It seems like some of the coastlines near the edge changed, so I'm not exactly sure why, but it could be because of the way it clipped.
  • regrid_image.png 5.5476486310267825. Mainly the clipping now works for the first Axes. However, there is an annoying extra bit of clipped pixels on the red/green/blue images, mostly visible on the left edges.
  • global_map.png 0.5430546319969413. The line here extends outside the spines just a little bit. It should be clipped, but it's visible on the outer grey side.
  • multiple_projections5.png 0.5250993556778882. This is mostly just stuff around the edges, but there are a lot of subplots so it raises the RMS. For the other lines, I suspect that things were already different, but RMS was under the original 0.5 tolerance before.
  • pcolormesh_global_wrap1.png 1.2638301573655641. The pcolormesh extends outside the Axes on the left and left/top edges.
  • pcolormesh_global_wrap2.png 1.6054726285773642. Same as above.
  • pcolormesh_global_wrap3.png 1.3892948851045908. Same as above, though I think the Robinson map is a bit better instead.
  • pcolormesh_goode_wrap.png 0.6293873785056563. Basically the same edge changes. I think this one is also improved a bit.
  • nightshade_platecarree.png 1.1415358805866185. The inner grey edge along the top is much darker now and it doesn't match the inner grey on the left and right edges.
  • poly_interiors.png 3.0048004417006537. This is outright a bug in Matplotlib. PatchCollection edges incorrect when clip path is set matplotlib/matplotlib#15946

@greglucas
Copy link
Contributor

Are you going to close this draft PR and merge all the changes in that other link you sent?
The changed images all look good to me. Minor and likely due to edge antialiasing as you mentioned. The only question I have is in regards to your last bullet.

poly_interiors.png 3.0048004417006537. This is outright a bug in Matplotlib. matplotlib/matplotlib#15946

Do you want to update this image if it is a known bug, or just xfail it in pytest for now and then update the image once that is fixed in MPL upstream?

@greglucas
Copy link
Contributor

@QuLogic, are you still planning on doing more work on this? I think it is an excellent improvement and well worth getting in for the next release.

@QuLogic QuLogic mentioned this pull request Feb 11, 2020
@QuLogic QuLogic added this to the 0.18 milestone Feb 11, 2020
@QuLogic
Copy link
Member Author

QuLogic commented Feb 11, 2020

I still want to do this for 0.18, but I'm looking to fix the two bugs in Matplotlib first. I had half-fixed one, and the other should be possible, though it needs further testing.

@QuLogic QuLogic force-pushed the background_patch-removal branch 2 times, most recently from 1793888 to f6bc67e Compare March 31, 2020 08:33
@QuLogic QuLogic marked this pull request as ready for review March 31, 2020 08:35
@QuLogic
Copy link
Member Author

QuLogic commented Mar 31, 2020

I've now run through the whole combination of dependencies, and updated the tests to account for the change here. I updated the images where stuff was improved and where differences were small-ish, I just increased the tolerance (note our default is 0.5 RMS.) Replacement images were generated with the latest Matplotlib, and tolerances added for older versions if necessary.

Some much older versions of Matplotlib are completely broken for some tests, but rather than fix that, I just decided to mark the tests as xfail. We're going to drop support for old Matplotlib anyway.

Unfortunately, I was not able to fix some of the above bugs in Matplotlib for 3.2.0, so I just upped the tolerances for the tests that were affected here.

@QuLogic
Copy link
Member Author

QuLogic commented Mar 31, 2020

Oh, and one other is regrid_image.png is not updated yet. The clipping works better for the first Axes, but the extra clipped pixels on the red/green/blue images is a bug somewhere, and I haven't figured out whether it's Matplotlib or Cartopy yet. We can update that image later.

Copy link
Contributor

@greglucas greglucas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a nice abstraction and all of the new images look good. 👍 from me, just a minor comment and question. Thanks for the great effort seeing this through!

square in axes coordinates.
"""
if use_as_clip_path is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know why this was there in the first place?
If I'm understanding this correctly, everything will now be clipped at the defined boundary no matter what. Whereas before, there was an option to not use the map boundary as a clip path, but rather just use the default axes.

What you're doing makes intuitive sense to me, I'm just wondering if there would be a reason to keep this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer that people use Matplotlib's builtin support for clipping, by setting clip_on=False on the artists they don't want to be clipped.

The regrid_image.png test image is affected by this, but honestly it looks better this way (note, not updated yet due to reasons above.)

@QuLogic QuLogic force-pushed the background_patch-removal branch from f6bc67e to 43421a7 Compare April 3, 2020 04:22
@greglucas greglucas merged commit 5e77741 into SciTools:master Apr 10, 2020
@QuLogic QuLogic deleted the background_patch-removal branch April 10, 2020 02:04
valentinaschueller added a commit to valentinaschueller/scriptengine-tasks-ecearth that referenced this pull request Sep 2, 2020
In earlier versions, the facecolor of GeoAxes objects is set via
GeoAxes.background_patch.set_facecolor()
see: SciTools/cartopy#880
This is changed in 0.18: SciTools/cartopy#1422

To make the grey areas in helpers/map_type_handling.py work,
cartopy>=0.18 is required.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tight_layout and Matplotlib 3

4 participants