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

Colorbar with SymmetricalLogLocator : issue when handling only negative values · Issue #7202 · matplotlib/matplotlib · GitHub

Repository navigation

Colorbar with SymmetricalLogLocator : issue when handling only negative values #7202

Closed

Description

Tested with matplotlib 1.4.3 and 1.5.3 built from sources - python 2.7.11 - Windows and Linux (64-bit)

To reproduce this issue, choose a set of values X so that -100<X<-10, then plot a NonUniformImage and attach a colorbar with a SymmetricalLogLocator : no tick or ticklabel will be displayed on the colorbar.

Activity

  1. egaudry commented on Sep 30, 2016

    Author

    The attached patch allows to draw ticks/ticklabels in case no decade (or only one) was selected based on vmin/vmax detected values.
    There is however still an issue in the colorbar height.

    Index: lib/matplotlib/colorbar.py
    ===================================================================
    --- lib/matplotlib/colorbar.py  (revision 97805)
    +++ lib/matplotlib/colorbar.py  (working copy)
    @@ -592,12 +592,14 @@
             formatter.set_data_interval(*intv)
    
             b = np.array(locator())
    -        if isinstance(locator, ticker.LogLocator):
    +        if isinstance(locator, ticker.LogLocator) or isinstance(locator, ticker.SymmetricalLogLocator):
                 eps = 1e-10
                 b = b[(b <= intv[1] * (1 + eps)) & (b >= intv[0] * (1 - eps))]
             else:
                 eps = (intv[1] - intv[0]) * 1e-10
                 b = b[(b <= intv[1] + eps) & (b >= intv[0] - eps)]
    +        if len(b)<2:
    +            b = np.array(locator())
             ticks = self._locate(b)
             formatter.set_locs(b)
             ticklabels = [formatter(t, i) for i, t in enumerate(b)]
    Index: lib/matplotlib/ticker.py
    ===================================================================
    --- lib/matplotlib/ticker.py    (revision 97805)
    +++ lib/matplotlib/ticker.py    (working copy)
    @@ -1722,6 +1722,8 @@
                     a_range = get_log_range(t, -vmin + 1)
                 else:
                     a_range = get_log_range(-vmax, -vmin + 1)
    +                if vmin<0 and vmax<0:
    +                  a_range = ( a_range[0], a_range[1]+1 )
             else:
                 a_range = (0, 0)
    
    
  2. egaudry commented on Sep 30, 2016

    Author

    might be linked to #7146

  3. tacaswell commented on Oct 3, 2016

    Member

    @egaudry Can you open a pull request with that patch?

    attn @efiring

  4. NelleV commented on Oct 24, 2016

    Member
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import colors
    from matplotlib import ticker
    
    X = -1 * np.random.randint(10, 90, size=(100, 100))
    
    fig, ax = plt.subplots()
    m = ax.imshow(X, norm=colors.SymLogNorm(1))
    formatter = ticker.LogFormatter(10)
    cb = fig.colorbar(m, format=formatter)
    ax.set_title("label only base")
  5. added
    Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
    on Oct 25, 2016
  6. added this to the milestone on Oct 25, 2016
  7. tacaswell commented on Oct 31, 2016

    Member
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import colors
    from matplotlib import ticker
    
    plt.ion()
    
    X = np.random.randint(15, 90, size=(100, 100))
    
    fig, ax = plt.subplots()
    m = ax.imshow(X, norm=colors.LogNorm())
    formatter = ticker.LogFormatter(10)
    cb = fig.colorbar(m, format=formatter)
    ax.set_title("label only base")
    

  8. NelleV commented on Oct 31, 2016

    Member

    So… The behaviour is not the same for log and symlog Norm… minorticks appear with symlog but not log.
    I'll do more tests.

  9. NelleV commented on Nov 5, 2016

    Member

    @efiring @tacaswell @dopplershift

    Following monday's discussion, I've ran some tests. By default, Log formatter behave extremely poorly with colorbars. The current behaviour is as follows

    Disabling labelOnlyBase does not change anything:

    Disabling the sublabels only feature (introduced in august) does not change anything:

    To have a behaviour that seems reasonable for colorbars we need to modify both the sublabels filtering and the labelOnlyBase:

    Now going to using the LogFormatter on a log scaled plot while disabling the sublabels filtering does not change anything on this example: http://matplotlib.org/devdocs/examples/scales/scales.html

    With sublabels:

    Without sublabels:

    From our discussion, I undersand that the labelOnlyBase=True is mostly use for minor ticks. I propose to change the default to have labelOnlyBase = False to remove or disable the sublabel filtering by default. I have yet to find a case where this new filtering improved the readibility of the figure, and I believe this may be due to improvements in the defaults of max number of ticks and placements of those ticks.

    I have to tweak matplotlib's code to add an option to disable the sublabels, that you can find in https://github.com/NelleV/matplotlib/tree/test_7202

    But here are some tests scripts I wrote:

    1. Colorbars

    import numpy as np
    
    import matplotlib.pyplot as plt
    from matplotlib import ticker, colors
    
    disable_sublabel = True
    
    
    X_1 = np.random.randint(10000, 90000, size=(100, 100))
    X_2 = np.random.randint(10000, 1000000, size=(100, 100))
    
    formatter = ticker.LogFormatter(
        10, disable_sublabel=disable_sublabel,
        labelOnlyBase=False)
    
    X = [X_1, X_2]
    
    fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
    for i, x in enumerate(X):
        ax = axes[i]
        m = ax.imshow(x, norm=colors.SymLogNorm(1))
        ax.set_title("Disabling sublabels & labelOnlyBase")
        cb = fig.colorbar(m, format=formatter, ax=ax, shrink=0.9, )
    fig.savefig("images/log_colorbar_proposed_new_default.png")
    
    formatter = ticker.LogFormatter(
        10, disable_sublabel=disable_sublabel,
        labelOnlyBase=True)
    
    fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
    for i, x in enumerate(X):
        ax = axes[i]
        m = ax.imshow(x, norm=colors.SymLogNorm(1))
        ax.set_title("Disable sublabel only")
        cb = fig.colorbar(m, format=formatter, ax=ax, shrink=0.9)
    fig.savefig("images/log_colorbar_disable_sublabels_only.png")
    
    formatter = ticker.LogFormatter(10, labelOnlyBase=False)
    
    fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
    for i, x in enumerate(X):
        ax = axes[i]
        m = ax.imshow(x, norm=colors.SymLogNorm(1))
        ax.set_title("Log formatter labelOnlyBase=False")
        cb = fig.colorbar(m, ax=ax, format=formatter, shrink=0.9)
    fig.savefig("images/log_colorbar_disable_labelonlybase.png")
    
    formatter = ticker.LogFormatter(10)
    
    fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
    for i, x in enumerate(X):
        ax = axes[i]
        m = ax.imshow(x, norm=colors.SymLogNorm(1))
        ax.set_title("Current Default")
        cb = fig.colorbar(m, ax=ax, format=formatter, shrink=0.9)
    fig.savefig("images/log_colorbar_default.png")

    2. the scales example

    import numpy as np
    from matplotlib import ticker
    import matplotlib.pyplot as plt
    
    disable_sublabel = True
    
    old_formatter = ticker.LogFormatterSciNotation(
        10, labelOnlyBase=False)
    formatter = ticker.LogFormatterSciNotation(
        10, disable_sublabel=True,
        labelOnlyBase=False)
    
    np.random.seed(19680801)
    # make up some data in the interval ]0, 1[
    y = np.random.normal(loc=0.5, scale=0.4, size=1000)
    y = y[(y > 0) & (y < 1)]
    y.sort()
    x = np.arange(len(y))
    
    for i, fmt in enumerate([old_formatter, formatter]):
        # plot with various axes scales
        fig, axs = plt.subplots(2, 2)
    
        # linear
        ax = axs[0, 0]
        ax.plot(x, y)
        ax.set_yscale('linear')
        ax.set_title('linear')
        ax.grid(True)
    
        # log
        ax = axs[0, 1]
        ax.plot(x, y)
        ax.set_yscale('log')
        ax.set_title('log')
        ax.yaxis.set_major_formatter(fmt)
    
        ax.grid(True)
    
        # symmetric log
        ax = axs[1, 1]
        ax.plot(x, y - y.mean())
        ax.set_yscale('symlog', linthreshy=0.05)
        ax.set_title('symlog')
        ax.yaxis.set_major_formatter(fmt)
        ax.grid(True)
    
        # logit
        ax = axs[1, 0]
        ax.plot(x, y)
        ax.set_yscale('logit')
        ax.set_title('logit')
        #ax.yaxis.set_major_formatter(formatter)
        ax.yaxis.set_minor_formatter(ticker.NullFormatter())
        ax.grid(True)
    
        plt.show()
        if i == 0:
            fig.savefig("images/example_old_formatter.png")
        else:
            fig.savefig("images/example_disabling_sublabels.png")

    3. some random tests

    import numpy as np
    
    import matplotlib.pyplot as plt
    from matplotlib import ticker, colors
    
    formatter = ticker.LogFormatterSciNotation(
        10, disable_sublabel=True,
        labelOnlyBase=False)
    
    X_1 = np.random.randint(10000, 90000, size=(1000,))
    X_1.sort()
    X_2 = np.random.randint(1e5, 1e12, size=(1000,))
    X_2.sort()
    X_3 = np.random.randint(1e5, 1e16, size=(1000,))
    X_3.sort()
    
    X = [X_1, X_2, X_3]
    
    fig, ax = plt.subplots(ncols=len(X), nrows=2, figsize=(12, 6))
    for i, x in enumerate(X):
        ax[0, i].plot(x)
        ax[0, i].set_yscale("symlog")
    
        ax[1, i].plot(x)
        ax[1, i].set_yscale("symlog")
        ax[1, i].yaxis.set_major_formatter(formatter)
    
    
    ax[0, 1].set_title("Symmetrical log")
    
    fig, ax = plt.subplots(ncols=len(X), nrows=2, figsize=(12, 6))
    for i, x in enumerate(X):
        ax[0, i].plot(x)
        ax[0, i].set_yscale("log")
        ax[1, i].plot(x)
        ax[1, i].set_yscale("log")
        ax[1, i].yaxis.set_major_formatter(formatter)
    
    ax[0, 1].set_title("Log")
    l_f = ax[0, 1].yaxis.get_major_formatter()
    
    
  10. NelleV commented on Nov 5, 2016

    Member

    Note that by default, labelOnlyBase is True for LogFormatter but False for LogFormatterSciNotation.

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

    Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL