2

I'm trying to get the text in the offset of the scientific notation of matplotlib, but get_offset() or get_offset_text() returns an empty string. I have checked these questions, but they didn't work:

How to move the y axis scale factor to the position next to the y axis label?

Adjust exponent text after setting scientific limits on matplotlib axis

prevent scientific notation in matplotlib.pyplot

Here is a simple example:

import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter
import numpy as np

x = np.arange(1,20)
y = np.exp(x)

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

ax.plot(x,y)

ax.yaxis.set_major_formatter(ScalarFormatter(useMathText=True)) 

print(ax.yaxis.get_offset_text())
print(ax.yaxis.get_major_formatter().get_offset())

fmt = ax.yaxis.get_major_formatter()
offset = ax.yaxis.get_major_formatter().get_offset()
print(offset)


plt.show()

That generates: enter image description here

I'd like to get the x10^8, but it returns only:

Text(0, 0.5, '')


The same happens if I don't use the ScalarFormatter. Am I missing something? Is there a separate function to get the multiplier (instead of the offset)?

edit: I'm currently using Python 3.9.0 with matplotlib 3.4.2 on a MacBook Pro, and I just run python3 test.py.

edit2: I have installed Python 3.9.5, and the solution with fig.canvas.draw() still does not work. The same with Linux works.

edit3: The problem happens when using the MacOSX backend. When changing to TkAgg or Agg, the get_offset works with the provided solution.

Filipe
  • 532
  • 4
  • 16

1 Answers1

4

You first need to draw the figure for the object to not hold some default values. From the source code on FigureCanvasBase.draw:

"""
Render the `.Figure`.
It is important that this method actually walk the artist tree
even if not output is produced because this will trigger
deferred work (like computing limits auto-limits and tick
values) that users may want access to before saving to disk.
"""

Simply call fig.canvas.draw() and then ax.yaxis.get_offset_text() will have the updated values you want.

x = np.arange(1, 20)
y = np.exp(x)

fig, ax = plt.subplots(1, 1)
ax.plot(x, y)
ax.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))

fig.canvas.draw()
         
offset = ax.yaxis.get_major_formatter().get_offset()
print(offset)
# $\times\mathdefault{10^{8}}\mathdefault{}$
Alex
  • 6,610
  • 3
  • 20
  • 38
Reti43
  • 9,656
  • 3
  • 28
  • 44
  • I'm not sure I understood correctly: I have added `fig.canvas.draw()` below the `ax.plot`, but the `get_offset` and `get_offset_text` still return empty... – Filipe May 31 '21 at 19:08
  • @Filipe The call to `draw()` should be after you've set the formatter, see the snippet I've added. – Alex May 31 '21 at 19:34
  • I have also tested that, and it still gives me blank! Can it be something on my installation? I'm using python 3.9.0 with matplotlib 3.4.2... – Filipe May 31 '21 at 19:39
  • I am using py 3.9.2 and mpl 3.4.1, so I don't think it will be the versions. How are you plotting? Maybe update the question. – Alex May 31 '21 at 19:42
  • I have added, and it seems to be something with the version or the installation indeed: I have plotted in other machines, and I get the expected output! :/ – Filipe May 31 '21 at 19:46
  • Very strange: I have just installed Python 3.9.5, and it still doesn't print the offset on my mac (the same version on linux prints it). Anyway, I have tested my initial version, and the solution, and they still make sense, so I'll keep them, and also accept the answer. Thank you for the help! – Filipe May 31 '21 at 19:59
  • @Filipe Out of curiosity, what backend are you using? `maplotlib.get_backend()`. It could be that whatever backend inherits from `FigureCanvasBase` don't do the drawing properly. Does the offset still show correctly when you call `plt.show()`? – Reti43 May 31 '21 at 20:08
  • That's it! The default one is `MacOSX`... If I change to `TkAgg` or `Agg`, I do get the string `$\times\mathdefault{10^{8}}\mathdefault{}$`... – Filipe May 31 '21 at 20:13
  • @Filipe Aha! I got suspicious the moment you mentioned different machines. It's probably worthwhile submitting a bug ticket for that. – Reti43 May 31 '21 at 20:15
  • Thank you! I have edited (again) the question to explain the current issue. – Filipe May 31 '21 at 20:17