[Matplotlib-users] Bug with changing formatter and locator of a secondary axis ?

Hello,

I’ve a question on the secondary
axis feature introduced in matplotlib 3.1
. I’m on version
3.1.1.

  My use case is to plot log values but also display the

exponentiated values. I can use a twin axes with the shared scale
and a functional formatter. Here is an example:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import LogLocator, FuncFormatter

fig, ax = plt.subplots(1,1)

    # twin ax with shared scale
    # cf. @ImportanceOfBeingErnest at

ax2 = ax.twiny()
ax.get_shared_x_axes().join(ax, ax2)

Plot

ax.plot([-1,2,5], [1,2,3], ‘d-’)
ax.grid()

x axis labeling

ax.set_xlabel(‘log2 x-value’)
ax2.xaxis.set_major_formatter(FuncFormatter(lambda x,pos:
f"{2**x:.3g}"))
ax2.set_xlabel(‘x-value’);

  This twinx/y approach works, but I wanted originally to use the

new secondary axis feature. I see to options for this:

  1. use a secondary axes with the log transform
  2.     use a secondary axes with no transform, and then transform the
    

display ticks using a FuncFormatter
Option 1 works initially, but breaks when I want to use a
LogLocator to have equally spaced log values:

fig, ax = plt.subplots(1,1)

    ax.plot([-1,2,5], [1,2,3], 'd-')

    ax2 = ax.secondary_xaxis('top', functions=(lambda x: 2**x,

np.log2))
# Place ticks at log equally spaced location [doesn’t work]
ax2.xaxis.set_major_locator(LogLocator(2))

  Option 2 doesn't work either due. Setting the formatter has no

effect

fig, ax = plt.subplots(1,1)

    ax.plot([-1,2,5], [1,2,3], 'd-')

    ax2 = ax.secondary_xaxis('top')
    # Format the log values as exponentiated values [doesn't work]
    ax2.xaxis.set_major_formatter(FuncFormatter(lambda x,pos:

f"{2**x:.3g}"))

  Is it an expected behavior (or a known bug) that changing the

locator and the formatter of a secondary axis has no effect? Did I
miss something?

  In the examples

(),
there is one example (number 3, with interpolated transforms)
which uses secax.xaxis.set_minor_locator(AutoMinorLocator()), but
I don’t know if it is effective or not.

Best,

Pierre

···

https://stackoverflow.com/questions/55907892/matplotlib-secondary-axis-with-values-mapped-from-primary-axis

https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/secondary_axis.html

The fact that Opion 1 does not work is a bug. This has been fixed
in the meantime, so it should work with the yet to be released
matplotlib 3.2.

  The fact that Opion 2 does not work can be considered a missing

feature. Feel free to open an issue about it, which can be tagged
as feature request/wishlist feature.
( might be
related.)

···

https://github.com/matplotlib/matplotlib/pull/14463
Am 14.10.2019 um 17:38 schrieb Pierre
Haessig:

Hello,

I’ve a question on the secondary
axis feature introduced in matplotlib 3.1
. I’m on version
3.1.1.

    My use case is to plot log values but also display the

exponentiated values. I can use a twin axes with the shared
scale and a functional formatter. Here is an example:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import LogLocator, FuncFormatter

fig, ax = plt.subplots(1,1)

      # twin ax with shared scale
      # cf. @ImportanceOfBeingErnest at

ax2 = ax.twiny()
ax.get_shared_x_axes().join(ax, ax2)

Plot

ax.plot([-1,2,5], [1,2,3], ‘d-’)
ax.grid()

x axis labeling

ax.set_xlabel(‘log2 x-value’)
ax2.xaxis.set_major_formatter(FuncFormatter(lambda x,pos:
f"{2**x:.3g}"))
ax2.set_xlabel(‘x-value’);

    This twinx/y approach works, but I wanted originally to use the

new secondary axis feature. I see to options for this:

  1. use a secondary axes with the log transform
  2.       use a secondary axes with no transform, and then transform
    

the display ticks using a FuncFormatter
Option 1 works initially, but breaks when I want to use a
LogLocator to have equally spaced log values:

fig, ax = plt.subplots(1,1)

      ax.plot([-1,2,5], [1,2,3], 'd-')

      ax2 = ax.secondary_xaxis('top', functions=(lambda x: 2**x,

np.log2))
# Place ticks at log equally spaced location [doesn’t work]
ax2.xaxis.set_major_locator(LogLocator(2))

    Option 2 doesn't work either due. Setting the formatter has no

effect

fig, ax = plt.subplots(1,1)

      ax.plot([-1,2,5], [1,2,3], 'd-')

      ax2 = ax.secondary_xaxis('top')
      # Format the log values as exponentiated values [doesn't work]
      ax2.xaxis.set_major_formatter(FuncFormatter(lambda x,pos:

f"{2**x:.3g}"))

    Is it an expected behavior (or a known bug) that changing the

locator and the formatter of a secondary axis has no effect? Did
I miss something?

    In the examples

(),
there is one example (number 3, with interpolated transforms)
which uses secax.xaxis.set_minor_locator(AutoMinorLocator()),
but I don’t know if it is effective or not.

Best,

Pierre

https://stackoverflow.com/questions/55907892/matplotlib-secondary-axis-with-values-mapped-from-primary-axis

https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/secondary_axis.html

_______________________________________________
Matplotlib-users mailing list

Matplotlib-users@python.orghttps://mail.python.org/mailman/listinfo/matplotlib-users

Thank you very much for the feedback!

Best,

Pierre

···

Le 14/10/2019 à 19:49, Elan Ernest a écrit :

The fact that Opion 1 does not work is a bug. This has been fixed in
the meantime, so it should work with the yet to be released matplotlib
3.2.

The fact that Opion 2 does not work can be considered a missing
feature. Feel free to open an issue about it, which can be tagged as
feature request/wishlist feature.
(Improve(?) implementation of secondary_axis. by anntzer · Pull Request #14463 · matplotlib/matplotlib · GitHub might be related.)

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@python.org
https://mail.python.org/mailman/listinfo/matplotlib-users