Matplotlib: -- how to show all digits on ticks? [duplicate]

Solution 1:

The axis numbers are defined according to a given Formatter. Unfortunately (AFAIK), matplotlib does not expose a way to control the threshold to go from the numbers to a smaller number + offset. A brute force approach would be setting all the xtick strings:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(100, 100.1, 100)
y = np.arange(100)

fig = plt.figure()
plt.plot(x, y)
plt.show()  # original problem

enter image description here

# setting the xticks to have 3 decimal places
xx, locs = plt.xticks()
ll = ['%.3f' % a for a in xx]
plt.xticks(xx, ll)
plt.show()

enter image description here

This is actually the same as setting a FixedFormatter with the strings:

from matplotlib.ticker import FixedFormatter
plt.gca().xaxis.set_major_formatter(FixedFormatter(ll))

However, the problem of this approach is that the labels are fixed. If you want to resize/pan the plot, you have to start over again. A more flexible approach is using the FuncFormatter:

def form3(x, pos):
    """ This function returns a string with 3 decimal places, given the input x"""
    return '%.3f' % x

from matplotlib.ticker import FuncFormatter
formatter = FuncFormatter(form3)
gca().xaxis.set_major_formatter(FuncFormatter(formatter))

And now you can move the plot and still maintain the same precision. But sometimes this is not ideal. One doesn't always want a fixed precision. One would like to preserve the default Formatter behaviour, just increase the threshold to when it starts adding an offset. There is no exposed mechanism for this, so what I end up doing is to change the source code. It's pretty easy, just change one character in one line in ticker.py. If you look at that github version, it's on line 497:

if np.absolute(ave_oom - range_oom) >= 3:  # four sig-figs

I usually change it to:

if np.absolute(ave_oom - range_oom) >= 5:  # four sig-figs

and find that it works fine for my uses. Change that file in your matplotlib installation, and then remember to restart python before it takes effect.

Solution 2:

You can also just turn the offset off: (almost exact copy of How to remove relative shift in matplotlib axis)

import matlplotlib is plt

plt.plot([1000, 1001, 1002], [1, 2, 3])
plt.gca().get_xaxis().get_major_formatter().set_useOffset(False)
plt.draw()

This grabs the current axes, gets the x-axis axis object and then the major formatter object and sets useOffset to false (doc).