Skip to content

scatter + loglog = bad autolimits #5897

Closed

Description

@anntzer
import matplotlib.pyplot as plt
xs = [97, 4980, 9863, 14746, 19628, 24511, 29394, 34277, 39160, 44042, 48925]
ys = [7e-09, 3e-09, 1e-09, 7e-10, 4e-10, 5e-10, 2e-10, 1e-10, 1e-10, 1e-10, 1e-10]
zs = [6e-09, 3e-09, 1e-09, 7e-10, 4e-10, 2e-10, 2e-10, 1e-10, 1e-10, 1e-10, 1e-10]
plt.scatter(xs, ys)
plt.loglog(xs, zs)
plt.show()

master
screenshot_20160121_210941
1.5.1
screenshot_20160121_211042
I've also had cases where the bottom of the line plot was cut out, although I don't have a minimal example yet.

Activity

  1. added this to the milestone on Jan 23, 2016
  2. zblz commented on Jan 30, 2016

    @zblz
    Member

    There is indeed something fishy going on in the log scale autolimit logic. I have found a similar problem when using a ax.set_ylim(bottom=1e-4) call: the top limit is not recomputed automatically but remains at the level of the previous view. Since the new autolimit logic, this means it might be several orders of magnitde above if the initial range before the set_ylim was very large. MWE:

    import matplotlib.pyplot as plt
    import numpy as np
    f,ax = plt.subplots(1)
    x = np.logspace(-2,3,100)
    y = x**1 * np.exp(-x/10)**2
    ax.loglog(x, y)
    ax.set_ylim(bottom=1e-3)
    f.show()
    

    On master:
    log-autolimits-after

    On 1.4.3:
    log-autolimits-1 4 3-after

  3. tacaswell commented on Apr 28, 2016

    @tacaswell
    Member

    This resulted in a hour long phone discussion. It seems there are significant order of operations issues here.

  4. anntzer commented on May 29, 2016

    @anntzer
    ContributorAuthor

    OK, I got it: this is because the data limits of a collection include the physical extent of the artists that are part of the collection (in this case, the markers). I guess this is necessary because artists may be quite large...
    Now, when the scatterplot is made, the y extent essentially comes from the marker size + margins. In fact, it can easily be checked that changing the size of the markers will change the ylims of the final plot. Ugh.
    Note that AFAICT this is different from the issue pointed out by @zblz.

  5. zblz commented on May 31, 2016

    @zblz
    Member

    Yes, it looks like a different issue. @tacaswell: when you mention there is an order of operations issue did you mean with @anntzer's issue or the autolimit/zoom issue I mentioned? Maybe I should split it into a new issue...

  6. anntzer commented on Jun 3, 2016

    @anntzer
    ContributorAuthor

    @zblz: I am not sure that there is much to do about the issue you are raising. I guess the only alternative would be to store (upon a call to margins) somewhere the information that some limits should be automatically recomputed if the "opposing" limit is moved (until overriden by a call to set_{x,y}lims). I'm not too worried about the implementation (well, perhaps a bit) but more that this may lead to all kinds of strange behavior and confused users... or perhaps not?

  7. zblz commented on Jun 3, 2016

    @zblz
    Member

    @anntzer: In my opinion, the current behaviour is more confusing: if a limit is set automatically to 20% beyond the data range, I expect this to hold always, even when I change the range. So I would be in favor of storing which limits are automatic and which have been manually set, and compute the auto limits on every new view given the manually set ones.

  8. anntzer commented on Jun 3, 2016

    @anntzer
    ContributorAuthor

    Fair enough.

    Coming back to my own issue: I thought that at least in theory, collections could return their limits as "data-value limit + axes-value limit" (the latter coming from the e.g. rightmost artist). However things are more complicated, because which artist has its rightmost point the furthest can depend on the xlims themselves (a larger artist more to the left can "catch up" a smaller artist more to the right if the scaling is compressed enough).

  9. NelleV commented on Nov 11, 2016

    @NelleV
    Member

    Current master yield this results with @anntzer's code:

    5897

    while @zblz
    5897_2

    I personnally find the new results to match my expections. @anntzer Can you confirm and close if that is the case?

  10. NelleV commented on Nov 11, 2016

    @NelleV
    Member

    I think this was closed by #7410

  11. anntzer commented on Nov 11, 2016

    @anntzer
    ContributorAuthor

    My example still suffers from the issue described in #7413.

  12. modified the milestones: , on Nov 16, 2016
  13. modified the milestones: , on Oct 3, 2017
  14. lzkelley commented on Jun 25, 2018

    @lzkelley
    Contributor
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    np.random.seed(12345)
    
    fig, axes = plt.subplots(figsize=[8, 5], ncols=2)
    
    NUM = int(1e4)
    xx = np.random.lognormal(1.0, 2.0, NUM)
    yy = np.random.lognormal(1.0, 2.0, NUM) + np.maximum(np.random.normal(0.0, 1.0, NUM), 0.0)
    
    xlim = [np.min(xx), np.max(xx)]
    ylim = [np.min(yy), np.max(yy)]
    
    for ax in axes:
        ax.scatter(xx, yy, alpha=0.2)
        ax.set(xscale='log', yscale='log')
    
    axes[0].set_title("Autolimits")
    axes[1].set_title("Manual limits")
    axes[1].set(xlim=xex, ylim=yex);
    fig.text(0.2, 0.3, "Matplotlib version: " + mpl.__version__)
    fig.savefig('log-log-scatter-limits-blow.png')
    

    log-log-scatter-limits-blow

  15. anntzer commented on Mar 11, 2022

    @anntzer
    ContributorAuthor

    Fixed by #13642, I believe.

  16. modified the milestones: needs sorting, v3.2.0 on Mar 11, 2022
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