2

On the axes tick labels in matplotlib, there are two kinds of possible offsets: factors and shifts:

enter image description here

In the lower right corner 1e-8 would be a "factor" and 1.441249698e1 would be a "shift".

There are a lot of answers here showing how to manipulate both of them:

I would like to just remove the shifts and can't seem to figure out how to do it. So matplotlib should only be allowed to scale my axis, but not to move the zero point. Is there a simple way to achieve this behaviour?

Wolpertinger
  • 1,169
  • 2
  • 13
  • 30
  • It's not actually clear how you would like the ticks to be labeled, when no shift is possible in the case from the question. Can you please state explicitely which numbers you want to show on the axes and which number below (as factor)? – ImportanceOfBeingErnest Jul 25 '17 at 16:36
  • @ImportanceOfBeingErnest Indeed, sorry about that. In this example for the y-axis I would like it to simply show 1.1 on all the axis ticks and 1e-2 as the factor. Alternatively just one single axis tick with 1.1 and 1e-2 as the factor (i.e. in both cases to show that the resolution of the small differences is irrelevant). – Wolpertinger Jul 26 '17 at 07:36

1 Answers1

0

You can fix the order of magnitude to show on the axis as shown in this question. The idea is to subclass the usual ScalarFormatter and fix the order of magnitude to show. Then setting the useOffset to False will prevent showing some offset, but still shows the factor.

Thwe format "%1.1f" will show only one decimal place. Finally using a MaxNLocator allows to set the maximum number of ticks on the axes.

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

class OOMFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self, order=0, fformat="%1.1f", offset=False, mathText=True):
        self.oom = order
        self.fformat = fformat
        matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,useMathText=mathText)
    def _set_orderOfMagnitude(self, nothing):
        self.orderOfMagnitude = self.oom
    def _set_format(self, vmin, vmax):
        self.format = self.fformat
        if self._useMathText:
            self.format = '$%s$' % self.format

x = [0.6e-8+14.41249698, 3.4e-8+14.41249698]
y = [-7.7e-11-1.110934954e-2, -0.8e-11-1.110934954e-2]

fig, ax = plt.subplots()
ax.plot(x,y)

y_formatter = OOMFormatter(-2, "%1.1f")
ax.yaxis.set_major_formatter(y_formatter)
x_formatter = OOMFormatter(1, "%1.1f")
ax.xaxis.set_major_formatter(x_formatter)

ax.xaxis.set_major_locator(matplotlib.ticker.MaxNLocator(2))
ax.yaxis.set_major_locator(matplotlib.ticker.MaxNLocator(2))

plt.show()

enter image description here

Keep in mind that this plot is inaccurate and you shouldn't use it in any kind of report you hand to other people as they wouldn't know how to interprete it.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712