-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
One one tick in a log-scale axis #8768
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
Comments
What supplementary tick value would you expect? 0.41? Or would you expect the ylim to be automatically extended to include 0.4 (for example)? Currently, one simple workaround solution may be to simply use By pure curiosity, why is there the need of a logarithmic plot on such a short (meaning << 1 decade) range? Is it related to a specific field of research? |
An even worse case, where no tick labels are present: import matplotlib.pylab as plt
plt.loglog([ 0.45, 0.46],[ 0.45, 0.46] )
plt.show() |
@dstansby What would be the correct behavior in this case? I agree that no tick is a bad choice. But it also seems wrong to me to use a log scale on such a small range of values as it should be more or less linear anyway, shouldn't it? In your example, one wants to plot values
Would you suggest the logarithmic locators to switch to a linear-like behavior for ranges where one or no tick at all would be displayed? |
All of this is inherent in the way log locators and formatters work. @afvincent's suggestion is correct: the solution to this is an AutoLogLocator that switches to using a MaxNLocator when the range drops below a threshold, probably a little larger than the largest minor tick interval. |
@afvincent The reason I want to use log-scale is that the theory shows that the data should behave the power law in this range. Indeed, there is no big difference between log-scale or linear-scale in this range.
Somehow, give readers a sense that this is not a linear scale axis. |
If I put on my physicist hat, I am deeply skeptical of power law claims at less than 3 decades (as a default position), but with my Matplotlib hat on we probably should make sure we do not create plots with too few ticks to be useful. For now @szsdk I suggest manually setting the ticks. |
Running into the same problem with much more data points. Setting limits manually is hard since I only want to include the previous and next tick and not more. |
Although it may not always make sense to plot on a log scale over a small range, it can become necessary for some applications. I have been building a matplotlib backend to a test and measurement system. The expected data spans several decades and is best suited for a log scale. By nature of doing research and measuring devices with properties that are not known in advance, however, there will be some devices that do not function properly and produce data spanning only a small range. It does not make much sense to plot on a linear scale because I want to compare poorly functioning devices to those that function well. I really appreciate that this was added to a milestone, but I noticed that milestone has been deleted. I upgraded to 2.2.2 and the issue persists, so I just wanted to check: what is the status on this? Is it in the plans? Is anyone working on it? Oh, and another simple code block to reproduce this is: from matplotlib import pyplot as plt
plt.semilogy([0,1,2],[0.31,0.32,0.33])
plt.show() Thanks all! |
Another way is to set the x and y scales by simply - fig ,ax = plt.subplots(figsize=(12, 6)) # Create figure and subplot
ax.set_xlim(0, 255)
ax.set_ylim(0, 255) Or you can create a single dimensional array using NumPy, especially a linspace.
import numpy as np
x = np.linspace(1, 10, 5)
print(x) You can use this on the x/y-scale as follows - fig, ax = plt.subplots(figsize=(12, 6))
x = np.linspace(0, 10**6, 10**3)
y, = ax.semilogx(x)
ax.set_ylim(1000)
ax.plot([10**1, 10**2, 10**3], [10**1, 10**2, 10**3])
plt.show() I hope that answered your issue! Requirements
|
Closed by #12865. |
if you make the window small enough you you can get it to go to 1 tick (I think it is font dependent). For me if I make it ~1.2 in tall I can get it to drop to one tick. |
|
and if you set I'm trying to puzzle through the |
ok, got this sorted, PR coming. |
Thanks for looking into this so promptly!
That's right. I am using slightly bigger font in rcParams.
In the MWE there's no latex involvement, but perhaps its auto-enabled in my matplotlib (I do use math mode for axis labels etc, so it probably is).
I completely agree. As can be seen from the numbers in the MWE, its 2 orders of magnitude and deserves at least minor ticks (without labels) if there isn't space for the major tick labels. |
The underlying source of the bug is when we ask for very small numbers of ticks we can end up deciding the best stride between the log ticks is equal to the approximate range of your data which means unless you set the limits just right you'll only see one. In your case we are trying to tick at (10^0, 10^2, 10^4) which given our heuristic of trying to keep ticks "spread out" is sensible. My proposed fix is to make sure the stride is always less than the estimated range which leads to crunched tick labels, but that seems like a better trade off to make than showing only one tick. |
If we have both a small target number of ticks and a small displayed range we would previously pick a tick stride that was the same size or bigger than the visible data range which would result in only 1 tick being visible on the axis. This patch ensures that, with a floor at 1, the stride is smaller than the estimated data range. re-closes matplotlib#8768 (same symptoms, different cause)
Thanks!
By any chance, do you know how I'd turn on the minor ticks? |
I think that is expected. The problem before was there were no minor ticks... |
@dmylnikov the issue you are describing was further described in #29414 and was fixed in #29054 - should be part of the matplotlib 3.11 release. |
Bug report
For the data in a small range, there is just on tick in the default log scale axis, which means nothing.
Code for reproduction
Actual outcome
Expected outcome
Give at least two ticks for each axis.
Matplotlib version
I install the library by conda.
The text was updated successfully, but these errors were encountered: