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()
Before:

After:
