FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

One one tick in a log-scale axis · Issue #8768 · matplotlib/matplotlib · GitHub

Repository navigation

One one tick in a log-scale axis #8768

Closed

Description

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

import matplotlib.pylab as plt
plt.loglog([ 0.53,  0.41],[ 0.53,  0.41] )
plt.show()

Actual outcome

Expected outcome
Give at least two ticks for each axis.

Matplotlib version

  • Operating System: Ubuntu 16.04
  • Matplotlib Version: 2.02
  • Python Version: 3.6.0
    I install the library by conda.

Activity

  1. afvincent commented on Jun 16, 2017

    Contributor

    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 plt.xlim and plt.ylim to include 0.4, which results in a second tick being used.

    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?

  2. dstansby commented on Jun 16, 2017

    Member

    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()
  3. afvincent commented on Jun 16, 2017

    Contributor

    @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 log10(0.45 + x) with x in [0, 0.01] (i.e. x << 0.45) so

    log10(0.45 + x) = log10(0.45) + log10(1 + x/0.45)  # log scale
                    ~ log10(0.45) + x/0.45  # linear scale
    

    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?

  4. efiring commented on Jun 16, 2017

    Member

    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.

  5. szsdk commented on Jun 17, 2017

    Author

    @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.
    Probably, the ticks could be

    4.0e-1 4.5e-1 5.5e-1
    

    Somehow, give readers a sense that this is not a linear scale axis.

  6. added this to the milestone on Jun 17, 2017
  7. tacaswell commented on Jun 17, 2017

    Member

    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.

  8. danijar commented on Jul 25, 2017

    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.

  9. stevennoyce commented on Apr 18, 2018

    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!

  10. rudrathegreat commented on Nov 8, 2018

    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.

    np.linspace allows you to create a single dimensional array with values ranging from a start number, x, and an end number, y, all equally spaced out. You can set the length of the array by setting how many 'ticks' I want in between those those two numbers. You can try this yourself by simply -

    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

    • Python 3.7
    • Matplotlib 2.2.3
    • NumPy 1.10.0
  11. anntzer commented on Jan 7, 2019

    Contributor

    Closed by #12865.

  12. modified the milestones: needs sorting, v3.1 on Jan 12, 2019
  13. aggna commented on Oct 16, 2020

    Still getting this issue. Using python 3.6.8, matplotlib 3.1.1 on Windows 10.

    plt.figure(figsize=(6,2))
    plt.semilogy(np.arange(6),[9, 5e1, 1e2, 6e2, 9e2, 2e3])
    

    generates the following output.

    For me, the ideal case would be to have minor ticks in the above plot. But when I tried to force-add them with the following three methods, none worked:

    1. ax.tick_params(axis='y', colors='k',which = 'both')

    2. ax.yaxis.set_minor_locator(ticker.AutoMinorLocator())

    ax.minorticks_on()
    ax.xaxis.set_tick_params(which='minor', bottom=False)
    

    For now, I just artificially imposed ticks by increasing the ylim:
    plt.ylim(1,1e4)
    which gives the second example.

  14. jklymak commented on Oct 16, 2020

    Member

    You must have things set in your rcParams that are causing this, or we fixed something: I get:

  15. tacaswell commented on Oct 16, 2020

    Member

    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.

  16. tacaswell commented on Oct 16, 2020

    Member

    The really upsetting part is that the ticks are in-range just not shown!

  17. tacaswell commented on Oct 16, 2020

    Member

    ax.yaxis.get_major_locator().numticks = 4 makes it behave better for me locally.

  18. tacaswell commented on Oct 16, 2020

    Member

    and if you set ax.yaxis.get_major_locator().numticks = 3 it is broken independent of figure size (the small figure here is needed to trigger a small enough number out of ax.yaxis.get_tick_space() and it looks like @aggna is using latex for the tick labels which places the exponent a bit higher than the defaults so they triggered the problem with a slightly bigger figure than @jklymak and I did.

    I'm trying to puzzle through the LogLocator code to sort out what is going wrong...

  19. tacaswell commented on Oct 16, 2020

    Member

    ok, got this sorted, PR coming.

  20. aggna commented on Oct 16, 2020

    Thanks for looking into this so promptly!

    You must have things set in your rcParams that are causing this, or we fixed something

    That's right. I am using slightly bigger font in rcParams.

    size=14
    plt.rcParams.update({'font.size': size})
    plt.rcParams.update({'font.family':'Times New Roman'})
    

    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).

    The really upsetting part is that the ticks are in-range just not shown!

    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.

  21. tacaswell commented on Oct 16, 2020

    Member

    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.

  22. added a commit that references this issue on Oct 16, 2020
    b23a874
  23. aggna commented on Oct 17, 2020

    Thanks!

    ax.yaxis.get_major_locator().numticks = 4 worked well for me too.

    By any chance, do you know how I'd turn on the minor ticks?

  24. dmylnikov commented on Jul 29, 2021

    I'm still able to get 1 tick axis with the following code using matplotlib 3.3.4:
    plt.semilogy([1.5, 50])

  25. jklymak commented on Jul 29, 2021

    Member

    I think that is expected. The problem before was there were no minor ticks...

  26. doronbehar commented on Jan 7, 2025

    Contributor

    @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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL