I am using the following tick label formatting:
ax.ticklabel_format(axis="y", style="sci", useOffset=True, scilimits=(0,0))
My problem is that the labels are floats. So the lowest values might be something like 0.5 (times the offset) and the highest might be 2.0 (times the offset). In this case I would like the respective labels to be 5 and 20 and change the offset by a factor of 10.
Do I have to set the ticklabels and the offset text manually or is there an simple command that does exactly that? I can't imagine that customizing the tick labels like this is not built in but I could not find anything in my searches so far.
Credit for the solution to ImportanceOfBeingErnest. The solution is based on this:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import matplotlib
from matplotlib import pyplot as plt
from matplotlib.ticker import ScalarFormatter
import numpy as np
class ModifiedFormatter(ScalarFormatter):
def __init__(self, order, fformat="%.0f", offset=True, mathText=True):
self.oom = order
self.fformat = fformat
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$" % matplotlib.ticker._mathdefault(self.format)
def test():
fig, ax = plt.subplots(nrows=1,ncols=1,figsize=(15,8))
xv = np.random.normal(0,1,100000)
xmin, xmax = -3, 3
nbins = 100
ax.hist(xv, bins=nbins, range=(xmin,xmax), histtype="step", color="blue")
# determine the new order of major formatter
# since I want 2 digits accuracy, new_order = old_order - 1
ymin, ymax = ax.get_ylim()
order = int("{:1.8e}".format(ymax).split("e")[1])-1
ax.yaxis.set_major_formatter(ModifiedFormatter(order))
ax.ticklabel_format(axis="y", style="sci", useOffset=True, scilimits=(0,0))
ax.tick_params(axis="both", labelsize=20)
ax.yaxis.get_offset_text().set_fontsize(18)
ax.set_xlabel("x axis label", fontsize=20)
ax.set_ylabel("y axis label", fontsize=20)
plt.subplots_adjust(top=0.9,bottom=0.1,left=0.065,right=0.99,hspace=0.2,wspace=0.2)
plt.show()
if __name__ == '__main__':
test()