25

I know that this question has been asked before, but I tried all the possible solutions and none of them worked for me.

So, I have a log-log plot in matplotlib, and I would like to avoid scientific notation on the x-axis.

This is my code:

from numpy import array, log, pi
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import matplotlib.ticker as mticker

plt.rc('axes.formatter', useoffset=False)

tc = array([7499680.0, 12508380.0, 23858280.0, 34877020.0, 53970660.0, 89248580.0, 161032860.0, 326814160.0, 784460200.0])

theta = array([70, 60, 50, 45, 40, 35, 30, 25, 20])

plt.scatter(theta,tc)

ax=plt.gca()

ax.set_xscale('log')
ax.set_yscale('log')

ax.xaxis.set_major_formatter(mticker.ScalarFormatter())
ax.xaxis.get_major_formatter().set_scientific(False)
ax.xaxis.get_major_formatter().set_useOffset(False)

plt.show()

And this is the output: Output

As you can see, the numbers on the x-axis are still in scientific notation. I would like to display them as 20, 30, 40... I tried every possible solution with no result.

Thank you very much to everyone that will help.

NB. I can't use the plt.loglog() command, because I am doing some curve fitting on the data and I need it like that.

NB2. I noticed a very weird thing happening: if I change the code to yaxis.get_mayor_formatter()..., it works on the y-axis! It is just on the x one that it's not working. How is it possible?

Edit: maybe it is not clear, but if you look at the code, there are 3 methods that should affect the display of the x-ticks: plt.rc('axes.formatter', useoffset=False), ax.xaxis.set_major_formatter(mticker.ScalarFormatter()) and ax.xaxis.get_major_formatter().set_scientific(False). They are 3 methods that should all do the trick alone, according to what I found around, but they don't. Of course I also tried them one by one and not all together.

Tropilio
  • 1,395
  • 1
  • 9
  • 27

4 Answers4

25

Those are minor ticks on the x-axis (i.e. they are not on integer powers of 10), not major ticks. matplotlib automatically detemines if it should label the major or minor ticks - in this case because you don't have any major ticks displayed in the x range, the minor ticks are being labelled). So, you need to use the set_minor_formatter method:

ax.xaxis.set_minor_formatter(mticker.ScalarFormatter())

enter image description here

The reason it works on the y-axis is because those ticks are major ticks (i.e. on integer powers of 10), not minor ticks.

tmdavison
  • 64,360
  • 12
  • 187
  • 165
  • (This can replace the other 3 `ax.xaxis` statements in the question.) – Max Ghenis Apr 11 '19 at 18:08
  • I'm still having issues with data points that cross an order of magnitude: https://stackoverflow.com/questions/55638913/inconsistent-decimals-in-tick-labels-when-using-a-log-axis – Max Ghenis Apr 11 '19 at 18:26
  • 1
    You probably mean `set_major_formatter`. And you can also use `mticker.FormatStrFormatter('%d')` to get `1` instead of `1.0`. – Suuuehgi Feb 25 '22 at 12:05
  • @tmdavison It's regarding your answer. – Suuuehgi Feb 26 '22 at 18:21
  • @Suuuehgi ok, then I don't understand what you are saying. This is definitely not a case where you need a major formatter. If you look at the x-axis, you can see the ticks are all minor ticks, as they are between the integer powers of 10 on the log scale. Also, while the `FormatStrFormatter` you suggest would work here. the `ScalarFormatter` I have used is clearly sufficient, as seen in my attached image – tmdavison Feb 28 '22 at 11:01
  • For some reason, each major tick greater than or equal to 1 ends up ending with ".0" (i.e. "1.0", "10.0", "100.0", etc.), which feels unnecessary since they are all integers anyway, while the minor ticks don't. Do you have any idea why that may be the case or how to make them not end with ".0"? – HelloGoodbye Aug 09 '22 at 18:54
13

The following can be used as a workaround (original answer):

from matplotlib.ticker import StrMethodFormatter, NullFormatter
ax.yaxis.set_major_formatter(StrMethodFormatter('{x:.0f}'))
ax.yaxis.set_minor_formatter(NullFormatter())
im2527
  • 391
  • 3
  • 4
0

If you want to set just the xaxis to no longer use scientific notation you need to change the fromatter and then you can set it to plain.

ax.xaxis.set_minor_formatter(mticker.ScalarFormatter())
ax.ticklabel_format(style='plain', axis='x')
-3

If you want to disable both the offset and scientific notaion, you'd use ax.ticklabel_format(useOffset=False, style='plain')

Aditya
  • 2,380
  • 2
  • 14
  • 39