Skip to content

autoinfer norms from scale names in the "norm" kwarg of imshow() and friends. #20746

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

Closed
anntzer opened this issue Jul 27, 2021 · 6 comments
Closed

Comments

@anntzer
Copy link
Contributor

anntzer commented Jul 27, 2021

Problem

Now that Norms are auto-derived from Scales (see make_norm_from_scale), it may be nice to reuse the scale-name machinery to allow using strings to specify norms, e.g.

imshow(..., norm="log")
# => norm=colors.make_norm_from_scale(scale.scale_factory("log"))
# a.k.a. norm=colors.LogNorm()

and perhaps

imshow(..., norm=("log", vmin, vmax))

or just allow

imshow(..., norm="log", vmin=vmin, vmax=vmax)

(#15769 deprecated norm=LogNorm(), vmin=vmin, vmax=vmax but that was because in that case it was unclear whether the passed-in norm should be mutated, whereas here it's always a new norm instance which can thus always be mutated). (I'm not always particularly fond of using strings when objects would be more featureful, but here the machinery for scales is already present and well established so...)

This would seem relatively easy to implement, except for one detail: LogScale currently defaults to nonpositive="clip" (see #9477 and the long tree of linked issues for the reason), whereas norms use nonpositive="mask" (which is more or less implied by the existence of APIs like Colormap.set_bad). While this can be resolved in an ad-hoc manner (e.g. by making sure that such scales have a nonpositive parameter/attribute and setting it accordingly), I wonder whether a more general solution is possible.

Proposed Solution

As described above.

Additional context and prior art

AFAICT, proplot uses a hard-coded mapping of norm names (https://proplot.readthedocs.io/en/latest/api/proplot.constructor.Norm.html).

@story645
Copy link
Member

I don't think there will be confusion w/ norms where the string version doesn't exist 'cause it's not a scale (like boundarynorm) but I'm like kinda wondering what this looks like in documentation since it let's the kwarg take as input the object and a strict subset of strings.

@jklymak
Copy link
Member

jklymak commented Jul 27, 2021

We already do that for ax.set_scale.

I think this could work. I'm a little leery about doing it because making folks aware of the underlying Norm class is quite useful. But it is awkward to grab. Another alternative is we add the norms to pyplot so folks can do norm=plt.LogNorm()

@anntzer
Copy link
Contributor Author

anntzer commented Jul 27, 2021

I would document this exactly in the same way as we document set_scale, as norms can (mostly) be thought of as setting the scale on the colorbar axis. (And even though (as noted above) I like exposing the underlying objects, here there's strong precedent for using strings for scales.)
BoundaryNorm and friends are different, of course :-)

@timhoffm
Copy link
Member

and perhaps

imshow(..., norm=("log", vmin, vmax))

👎 on such an API. This is not discoverable, has no editor support (completion/checking), and it's not readable (a common realistic case would be explicit numbers imshow(..., norm=("log", 0.1, 1))).

or just allow

imshow(..., norm="log", vmin=vmin, vmax=vmax)

ok.

@anntzer
Copy link
Contributor Author

anntzer commented Jul 28, 2021

Agreed, I went for the second solution in #20752.

@anntzer
Copy link
Contributor Author

anntzer commented Apr 19, 2024

Closed by #20752.

@anntzer anntzer closed this as completed Apr 19, 2024
@anntzer anntzer added this to the v3.6.0 milestone Apr 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants