Skip to content

[Bug]: (edge case) no ticks are drawn in colorbars with SymLogNorm #25945

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
Tracked by #4449
neutrinoceros opened this issue May 22, 2023 · 0 comments · Fixed by #25970
Closed
Tracked by #4449

[Bug]: (edge case) no ticks are drawn in colorbars with SymLogNorm #25945

neutrinoceros opened this issue May 22, 2023 · 0 comments · Fixed by #25970

Comments

@neutrinoceros
Copy link
Contributor

neutrinoceros commented May 22, 2023

Bug summary

In some edge cases, colorbars end up with 0 ticks.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import SymLogNorm

prng = np.random.RandomState(0)
data = prng.randint(0, 2, size=100).reshape(10, 10)

fig, ax = plt.subplots()
im = ax.imshow(data, norm=SymLogNorm(linthresh=1))
fig.colorbar(im)

sfile = "/tmp/symlog_no_ticks.png"
print(f"saving to {sfile}")
fig.savefig(sfile)

Actual outcome

symlog_no_ticks

Expected outcome

symlog_no_ticks

Additional information

I find this can be solved with the following patch

diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py
index a29343029f..17ab354dce 100644
--- a/lib/matplotlib/ticker.py
+++ b/lib/matplotlib/ticker.py
@@ -2503,9 +2503,9 @@ class SymmetricalLogLocator(Locator):
             return [vmin, vmax]

         # Lower log range is present
-        has_a = (vmin < -linthresh)
+        has_a = (vmin <= -linthresh)
         # Upper log range is present
-        has_c = (vmax > linthresh)
+        has_c = (vmax >= linthresh)

         # Check if linear range is present
         has_b = (has_a and vmax > -linthresh) or (has_c and vmin < linthresh)

I don't anticipate this patch to have undesirable side effects. Would it be acceptable as a fix ?

For context, this is part of an effort to upstream some subtly different rules regarding symlog normed colorbars that are implemented in yt. A rather obvious observation is that there is no actual need for the example here to use SymLogNorm, but yt auto-selects a norm depending on the value range to be plotted and is "log by default", so symlog is the default scale used for data that isn't strictly positive, as in the simple example above.

Operating system

No response

Matplotlib Version

3.7.1

Matplotlib Backend

MacOSX

Python version

Python 3.11.2

Jupyter version

No response

Installation

pip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants