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

RFC: a more robust plot norm/colorbar API #3849

Merged
merged 63 commits into from
Aug 22, 2022

Conversation

neutrinoceros
Copy link
Member

@neutrinoceros neutrinoceros commented Mar 17, 2022

PR Summary

This is a deep refactor of how colorbar and plot norm data are stored and utilized internally.
It allows for a much more robust API where chaining operations like set_zlim and set_unit doesn't ruin the whole viz (fix #2538).
It also makes room to implement stuff like custom norm (fix #3840), and helps resolve a documented quirky behaviour (fix #3852).

It unifies the various strategies scattered across plot classes to determine what norm can be used in a given situation (symlog, log, linear ?), which is a area where we've seen many bugs in the recent pastn, basically on every matplotlib feature release.

I've been iterating and testing on this for a couple weeks locally, I'm opening the PR while it's still hot to see what bug existing tests might reveal.
Documentation is already included, but for now I haven't committed my test files because they are not adapated to yt's image comparison testing framework yet.

Note that this includes the changes from #2504, which changes some phase plots with respect to their gold standard, so CI should fail at the very least there, but no other failures are desired.

edit: I'm bumping matplotlib's minimal required version to 3.1 because 2.2.3 has some incompatibilities with the refactor and 3.1 is the oldest testable version for macOS.
FTR Matplotlib 3.1 was released in May 2019 and was only distributed for Python 3.6 and 3.7, so it's still a pretty conservative requirement now.

Note to reviewers

I opened a "companion" PR at #3900, which contains only the new tests, not the patch, to help demonstrate what's working here and not on the main branch.

I also tried to keep the commit history somewhat tidy and readable, so reading commits by chronological order is one possible angle to review this in steps.

After a lot of iterations, I bumped/added new answers both on Jenkins and the answer store. The supporting PR is yt-project/answer-store#31

A Summary of user-facing changes

A lot of symlog-related code is now centralised, making it reusable to all PlotContainer subclasses (not just ImagePlotContainer).

api changes

  • updated ImagePlotContainer.set_zlim to :
    • allow passing zmin or zmax only (previously they had to be both specified somehow)
    • allow passing unit-aware values (either as unyt_quantity objects or parsable tuples e.g. (10, "g/cm**2"))
  • updated PlotContainer.set_log so that the second argument (log) isn't necessary when passing linthresh. Previously users had to provide a value to the log argument but it was not actually used. Now a warning is emitted if a log value is received but discarded (this is however not deprecated).
  • added a PlotContainer.set_norm method to allow using matplotlib norms other than lin, log and symlog

deprecations

  • passing zmin=None (resp zmax=None) to set_zlim explicitly is deprecated (users can leave the parameter unset or pass zmin="min" (resp zmax="max") explicitly instead)
  • PlotContainer.set_log's symlog_auto parameter is deprecated (the same behaviour can be obtained by passing linthresh="auto" instead)

dependencies

  • bumped minimal supported version of MPL from 2.2.3 to 3.1 (this represents less than a 1yr jump)
  • added a dependency to typing_extensions (which are backports from the standard lib's typing module), exclusively for Python 3.7 (we can rely fully on the std lib in 3.8 and beyond)

PR Checklist

The following PRs should be handled before this one:

@neutrinoceros neutrinoceros added bug new feature Something fun and new! refactor improve readability, maintainability, modularity labels Mar 17, 2022
@matthewturk matthewturk self-requested a review March 18, 2022 14:28
@matthewturk matthewturk changed the title ENH: a more robust plot modification API REF: a more robust plot modification API Mar 18, 2022
@neutrinoceros neutrinoceros added the api-consistency naming conventions, code deduplication, informative error messages, code smells... label Mar 18, 2022
Copy link
Member

@matthewturk matthewturk left a comment

Choose a reason for hiding this comment

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

A few thoughts and questions before running off!

.pre-commit-config.yaml Outdated Show resolved Hide resolved
doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
@@ -883,7 +932,7 @@ As an example,

ds = yt.load_sample("FIRE_M12i_ref11")
p = yt.ProjectionPlot(ds, "x", ("gas", "density"))
p.set_log(("gas", "density"), True, symlog_auto=True)
p.set_log(("gas", "density"), linthresh="auto")
Copy link
Member

Choose a reason for hiding this comment

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

Is symlog_auto still allowed?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, but I'm deprecating it

doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
@@ -93,3 +97,128 @@ def get_canvas(figure, filename):
f"without an extension."
)
return get_canvas_class(suffix)(figure)

Copy link
Member

Choose a reason for hiding this comment

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

Are these functions inspired by or taken from somewhere else?

Copy link
Member Author

@neutrinoceros neutrinoceros Mar 18, 2022

Choose a reason for hiding this comment

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

It's all moved code:

  • the get_x_minorticks routines are taken (moved) from yt.visualization.plot_container
  • get_symlog_majorticks is extracted from ImagePlotMPL._init_image
  • get_default_from_config is adapted from a closure in PlotContainer.setup_defaults

The may reason for moving them around was to help me remembering were everything I needed was defined, but I may restore some of them to their original location when I try to clean this branch a bit.

@neutrinoceros neutrinoceros added the deprecation deprecate features or remove deprecated ones label Mar 19, 2022
@neutrinoceros neutrinoceros changed the title REF: a more robust plot modification API RFC: a more robust plot modification API Mar 19, 2022
@neutrinoceros neutrinoceros added this to the 4.1.0 milestone Mar 19, 2022
@neutrinoceros
Copy link
Member Author

Some desired changes in image tests collide with #3818, which is set for backporting, so I'll wait for that PR to resolve before I open this one for review.

@neutrinoceros neutrinoceros force-pushed the colorbar_handler branch 2 times, most recently from 159260d to 1f03523 Compare March 20, 2022 08:16
@neutrinoceros
Copy link
Member Author

I think I got this in a state were all remaining failures are expected changes. I simplified the branch history and reduced the amount of commits by a factor 10.
I also listed 2 PRs that should be handled before this one in the OP.

@neutrinoceros
Copy link
Member Author

Just noticed that some docs example like https://yt-project.org/doc/cookbook/simple_plots.html#showing-and-hiding-axis-labels-and-colorbars
are still broken on this branch. I'll continue to work on it.

@neutrinoceros neutrinoceros force-pushed the colorbar_handler branch 2 times, most recently from d8f07ab to 3ffc29b Compare March 20, 2022 14:40
@neutrinoceros
Copy link
Member Author

Docs build got stuck
@yt-fido test this please

@neutrinoceros neutrinoceros force-pushed the colorbar_handler branch 3 times, most recently from f245a0b to fd4a6cc Compare March 20, 2022 20:52
@neutrinoceros neutrinoceros changed the title RFC: a more robust plot modification API RFC: a more robust plot norm/colorbar API Mar 20, 2022
@neutrinoceros neutrinoceros force-pushed the colorbar_handler branch 3 times, most recently from 5ca8dd3 to 0a20134 Compare March 22, 2022 08:50
Copy link
Member

@chummels chummels left a comment

Choose a reason for hiding this comment

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

Again, many apologies for this taking so long to review. In general, I like what is done here. The old methods for specifying colorbar normalizations were getting pretty clunky after I added the auto_symlog kwarg a while back, and this is definitely an improvement over that. I tried to review as much as I could, but there is a lot of code here. In general, I just ran some test scripts locally to ensure that they worked and produced what was expected and read the code looking for any obvious inconsistencies.

My main comments are on how this is documented to ensure the users know how to use it, since it's changing the defaults a bit. I was hoping we could change references to "norms" in the docs to "normalizations" or "scalings", since I think norms is a bit confusing. But I realize that the classes and methods you created reference "Norms", which I think is fine. What do you think? After that minor stuff gets addressed, I'm happy to approve and merge this.

doc/source/visualizing/plots.rst Show resolved Hide resolved
doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
Colorbar norms
::::::::::::::

Slice plots and similar plot classes default to log norms when all values are
Copy link
Member

Choose a reason for hiding this comment

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

Have profile plots also moved to the new format--from below it looks like it? Maybe mentioning that here too?

Copy link
Member Author

Choose a reason for hiding this comment

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

Profile plots don't have a colorbar, unless you mean specifically 2D profile plots, aka phase plots ? (and yup, should mention it here)

doc/source/visualizing/plots.rst Show resolved Hide resolved
doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
doc/source/visualizing/plots.rst Outdated Show resolved Hide resolved
setup.cfg Show resolved Hide resolved
yt/visualization/plot_container.py Outdated Show resolved Hide resolved
neutrinoceros and others added 2 commits August 21, 2022 08:26
@neutrinoceros
Copy link
Member Author

@chummels thanks ! I think I replied to all your comments so far, but I'll let you resolve the threads when you're satisfied.

Just a note that merging this will not be a one step process. We need to merge the answer-store PR first, then update here.

chummels
chummels previously approved these changes Aug 22, 2022
Copy link
Member

@chummels chummels left a comment

Choose a reason for hiding this comment

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

Thanks for addressing my concerns. Psyched to see this go in! Only a couple of little requests, but other than that, this is great.

Co-authored-by: Cameron Hummels <chummels@gmail.com>
@neutrinoceros
Copy link
Member Author

Alright, looks like we're go ! Thank you so much for going through this gigantic PR
I'm going to merge yt-project/answer-store#31 and update this to point to a long lived branch of the answer store

@neutrinoceros
Copy link
Member Author

Ok this is now ready at last ! @chummels, if you'll do the honours ? 😄

@neutrinoceros
Copy link
Member Author

The docs build failed, but I'm hoping it's a random server-side event:

RuntimeError: Kernel didn't respond in 60 seconds

Let's try again: @yt-fido test this please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-consistency naming conventions, code deduplication, informative error messages, code smells... bug deprecation deprecate features or remove deprecated ones new feature Something fun and new! refactor improve readability, maintainability, modularity viz: 2D
Projects
None yet
5 participants