Skip to content

[Bug]: Setting set_xscale("symlog") has different behavior depending on value range #24549

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
xapple opened this issue Nov 26, 2022 · 2 comments
Labels
Community support Users in need of help.

Comments

@xapple
Copy link

xapple commented Nov 26, 2022

Bug summary

In this simple test I make two scatter plots. The first one has values drawn from a uniform distribution between 0 and 1000. The second plot is the same except that values are now drawn between 0 and 1 only.

Finally, I set set_xscale("symlog") and set_yscale("symlog") on both plots. The result is that the first plot responds correctly, while the second plot does not change, and the data points remain in the same linear display.

Code for reproduction

# Modules #
import random
from matplotlib import pyplot

# New graph #
fig, axes = pyplot.subplots()

# Constants #
upper_bound = 1.0 # try it with 1000.0 instead and it works

# Do it #
x = [random.uniform(0.0, upper_bound) for x in range(1000)]
y = [random.uniform(0.0, upper_bound) for x in range(1000)]
pyplot.plot(x, y, 'o')
axes.set_xscale("symlog")
axes.set_yscale("symlog")

Actual outcome

bug
With upper_bound = 1.0.

Expected outcome

expected
With upper_bound = 1000.0.

Additional information

This is quite a serious bug as it silently produces broken or miss-leading visualizations which then bias the interpretation of critical scientific data.

Operating system

macOS

Matplotlib Version

3.6.2

Matplotlib Backend

MacOSX

Python version

Python 3.10.8

Jupyter version

No response

Installation

conda

@timhoffm
Copy link
Member

Symlog is actually a bit trickier than one might assume. One can put arbitrary many decades (and thus screen space) between any value and 0. To draw symlog scale, we have to set this to a fixed value. This value is called linthresh and defaults to (-2, 2), see https://matplotlib.org/devdocs/api/scale_api.html#matplotlib.scale.SymmetricalLogScale. To preserve at least visual continuity, we add a range of linear scaling between these values. Your data in the second case happen to fall into the linear scaling regime, hence they don't change. If you set set_yscale('symlog, linthresh=2e-3) in the second case, the result will be equivalent.

@timhoffm timhoffm added the Community support Users in need of help. label Nov 26, 2022
@xapple
Copy link
Author

xapple commented Nov 26, 2022

Thanks for your clear response. Yes, now that I read the full documentation it seems obvious. I had erroneously assumed that the log scale automatically extended to the smallest value plotted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community support Users in need of help.
Projects
None yet
Development

No branches or pull requests

2 participants