Change matplotlib offset notation from scientific to plain

Viewed 1163

I want to set the formatting of the y-axis offset in my plot to non-scientific notation, but I can't find a setting to do this. Other questions and their solutions describe how to either remove the offset altogether, or set the y-ticks to scientific/plain notation; I haven't found an answer for setting the notation of the offset itself.

I've already tried using these two options, but I think they're meant for the y-ticks, not the offsets:

ax.ticklabel_format(axis='y', style='plain', useOffset=6378.1)

and

ax.get_yaxis().get_major_formatter().set_scientific(False)

So, the actual result is +6.3781e3, when I want +6378.1

Any way to do this?

Edit: Added example code and figure:

#!/usr/bin/env python

from matplotlib import pyplot as plt
from matplotlib import ticker
plt.rcParams['font.family'] = 'monospace'
import random

Date = range(10)
R = [6373.1+10*random.random() for i in range(10)]

fig, ax = plt.subplots(figsize=(9,6))
ax.plot(Date,R,'-D',zorder=2,markersize=3)
ax.ticklabel_format(axis='y', style='plain', useOffset=6378.1)
ax.set_ylabel('Mean R (km)',fontsize='small',labelpad=1)

plt.show()

Example image with data centered around the offset I want

2 Answers

You can subclass the default ScalarFormatter and replace the get_offset method, such that it would simply return the offset as it is. Note that if you wanted to make this compatible with the multiplicative "offset", this solution would need to be adapted (currently it just prints a warning).

from matplotlib import pyplot as plt
import matplotlib.ticker
import random

class PlainOffsetScalarFormatter(matplotlib.ticker.ScalarFormatter):
    def get_offset(self):
        if len(self.locs) == 0:
            return ''
        if self.orderOfMagnitude:
            print("Your plot will likely be labelled incorrectly")
        return self.offset

Date = range(10)
R = [6373.1+10*random.random() for i in range(10)]

fig, ax = plt.subplots(figsize=(9,6))
ax.plot(Date,R,'-D',zorder=2,markersize=3)

ax.yaxis.set_major_formatter(PlainOffsetScalarFormatter())
ax.ticklabel_format(axis='y', style='plain', useOffset=6378.1)
ax.set_ylabel('Mean R (km)',fontsize='small',labelpad=1)

plt.show()

enter image description here

A way to do this is to disable the offset text itself and add your custom ax.text there as follows

from matplotlib import pyplot as plt
import random

plt.rcParams['font.family'] = 'monospace'

offset = 6378.1

Date = range(10)
R = [offset+10*random.random() for i in range(10)]

fig, ax = plt.subplots(figsize=(9,6))
ax.plot(Date,R,'-D',zorder=2,markersize=3)
ax.ticklabel_format(axis='y', style='plain', useOffset=offset)
ax.set_ylabel('Mean R (km)',fontsize='small',labelpad=1)

ax.yaxis.offsetText.set_visible(False)
ax.text(x = 0.0, y = 1.01, s = str(offset), transform=ax.transAxes)
plt.show()

enter image description here

Related