Bug with changing formatter and locator of a secondary axis ?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug with changing formatter and locator of a secondary axis ?

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 https://stackoverflow.com/questions/55907892/matplotlib-secondary-axis-with-values-mapped-from-primary-axis
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 (https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/secondary_axis.html), 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


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Bug with changing formatter and locator of a secondary axis ?

Elan Ernest

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. (https://github.com/matplotlib/matplotlib/pull/14463 might be related.)

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 https://stackoverflow.com/questions/55907892/matplotlib-secondary-axis-with-values-mapped-from-primary-axis
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 (https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/secondary_axis.html), 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


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Bug with changing formatter and locator of a secondary axis ?

Pierre Haessig
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.
> (https://github.com/matplotlib/matplotlib/pull/14463 might be related.)
>

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users