Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes for matplotlib3.8 #339

Merged
merged 14 commits into from
Oct 1, 2023
Merged

Conversation

AdamOrmondroyd
Copy link
Collaborator

@AdamOrmondroyd AdamOrmondroyd commented Sep 15, 2023

Description

matplotlib3.8 released yesterday morning.

  • Axes._get_lines.prop_cycler has been removed, instead use Axes._get_lines.get_next_color() (inevitable with private member usage)
  • plt.hexbin now plots bins ≥mincnt, not >mincnt, which changes the behaviour with the default of 0 (corresponding to None in the signature). I have used np.finfo.tiny to correct this.
  • tcolors is deprecated, I have lifted the code used to simulate it in matplotlib to restore the test in test_contour_plot_2d().
  • samples.plot.[fast]kde_2d() now only adds two collections to the axes
  • plt.contour colors are out of whack (one weird extra one and the others are slightly different)

The last three are all symptoms of plt.contour returning QuadContourSet (one per level, so usually two for a contour plot) rather than PathCollection.

I'm completely stumped by the last one.

Fixes # (issue)

Checklist:

  • I have performed a self-review of my own code
  • My code is PEP8 compliant (flake8 anesthetic tests)
  • My code contains compliant docstrings (pydocstyle --convention=numpy anesthetic)
  • New and existing unit tests pass locally with my changes (python -m pytest)
  • I have added tests that prove my fix is effective or that my feature works
  • I have appropriately incremented the semantic version number in both README.rst and anesthetic/_version.py

@@ -1245,7 +1245,7 @@ def test_samples_dot_plot():
assert len(axes) == 2

axes = samples.plot.kde_2d('x0', 'x1')
assert len(axes.collections) == 5
assert len(axes.collections) == 2
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This test will fail on mpl<3.8. Is this a test we really need to do? The number of collections feels like matplotlib just doing matplotlib things

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree (although 2 makes more sense here than 5...). Is there anything explicit we can test to confirm that it has plotted something?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Check it's more than 0?

Copy link
Collaborator

Choose a reason for hiding this comment

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

That would do

@@ -131,6 +131,8 @@ def __init__(self, data, x, y, C=None, **kwargs) -> None:
C = '__weights'
data[C] = data.get_weights()
kwargs['reduce_C_function'] = np.sum
if 'mincnt' not in kwargs:
kwargs['mincnt'] = np.finfo(np.float64).tiny
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

alias for smallest_normal but I like tiny

@codecov
Copy link

codecov bot commented Sep 16, 2023

Codecov Report

All modified lines are covered by tests ✅

Comparison is base (8563cae) 100.00% compared to head (9035297) 100.00%.

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #339   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           34        34           
  Lines         2868      2868           
=========================================
  Hits          2868      2868           
Files Coverage Δ
anesthetic/_version.py 100.00% <100.00%> (ø)
anesthetic/plot.py 100.00% <100.00%> (ø)
anesthetic/plotting/_matplotlib/core.py 100.00% <100.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@AdamOrmondroyd
Copy link
Collaborator Author

An extra level of .collections[0] restores the original test, as the first gets at the QuadContour object, and the second gets us to the deprecated API we were using to test before.

The plots at least look identical to the previous matplotlib

@AdamOrmondroyd
Copy link
Collaborator Author

Still stumped 😢 using the old api will be deprecated in a couple of minor versions so I'd prefer not to rely on it.

I just can't work out what the five colours from QuadContourSet.get_edgecolor() actually correspond to

@lukashergt
Copy link
Collaborator

Still stumped 😢 using the old api will be deprecated in a couple of minor versions so I'd prefer not to rely on it.

Agreed, how about we add a matplotlib version check to the tests and test both old and new API. In the actual code I'd find that really annoying, but if we limit it to the tests that should be ok, right?

@AdamOrmondroyd
Copy link
Collaborator Author

Still stumped 😢 using the old api will be deprecated in a couple of minor versions so I'd prefer not to rely on it.

Agreed, how about we add a matplotlib version check to the tests and test both old and new API. In the actual code I'd find that really annoying, but if we limit it to the tests that should be ok, right?

But what do we do in two matplotlib's time? My concern is I don't understand the QuadContourSet colours

@lukashergt
Copy link
Collaborator

But what do we do in two matplotlib's time?

Keep adding to the tests and we could say anything older than 2 or 3 minor matplotlib versions get's scratched.

My concern is I don't understand the QuadContourSet colours

QuadContourSet.get_edgecolor() should return the colours of the contour lines (so it should be one more than the number of levels). QuadContourSet.get_facecolor() should return the colours of the contourf faces (as many as there are levels). In 3.7 each face and each line was its own PathCollection (that's where the number 5 came from, 2 faces and 3 lines). Now in 3.8 it seems these have been grouped into two QuadContourSet, one for contourf and one for contour.

@AdamOrmondroyd
Copy link
Collaborator Author

got it, thanks Lukas 😄 hopefully that's this PR done

@AdamOrmondroyd AdamOrmondroyd marked this pull request as ready for review October 1, 2023 10:25
@AdamOrmondroyd AdamOrmondroyd mentioned this pull request Oct 1, 2023
6 tasks
Copy link
Collaborator

@lukashergt lukashergt left a comment

Choose a reason for hiding this comment

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

Thanks a bunch @AdamOrmondroyd! Please squash and merge.

@AdamOrmondroyd
Copy link
Collaborator Author

Whoops! Left that in from while I was remembering how to check the version

@AdamOrmondroyd AdamOrmondroyd merged commit 434d97e into handley-lab:master Oct 1, 2023
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants