pythonmatplotlibaxisxticks

How to manually set axis offset with custom tick labels?


Consider the plot below. Both axis have custom labels, to label the rows and columns in an imshow-plot. The problem now is that the y-axis has very large values. Ideally I'd like to manually set an axis-offset (i.e. on top of the axis somethng like 1e5) such that the ticks are only show a smaller number. How can I achieve that?

There was a solution provided here but it does not work in this case, as we do not have a ScalarFormatter due to the custom labels:

import numpy as np
import matplotlib.pyplot as plt
s = 10000000
x, y = [1, 1, 2, 3, 5], [2*s, 3*s, 5*s, 7*s]
x, y = np.meshgrid(x, y)
z = np.random.rand(x.shape[0], x.shape[1])
plt.imshow(z)
plt.gca().set_yticks(range(len(y[..., 0])))
plt.gca().set_xticks(range(len(x[0, ...])))
plt.gca().set_yticklabels(y[..., 0])
plt.gca().set_xticklabels(x[0, ...])
plt.show()

enter image description here


Solution

  • You could use matplotlib.ticker.FuncFormatter.set_offset_string() like this:

    import numpy as np
    import matplotlib.pyplot as plt
    s = 100000 # 1e+05
    x = [1, 1, 2, 3, 5]
    original_y = [20000000, 30000000, 50000000, 70000000]
    y = [oy / s for oy in original_y]
    x, y = np.meshgrid(x, y)
    z = np.random.rand(x.shape[0], x.shape[1])
    plt.imshow(z)
    plt.gca().set_yticks(range(len(y[..., 0])))
    plt.gca().set_xticks(range(len(x[0, ...])))
    plt.gca().set_yticklabels(y[..., 0])
    plt.gca().set_xticklabels(x[0, ...])
    plt.gca().yaxis.get_major_formatter().set_offset_string('{:.0e}'.format(s))
    plt.show()
    

    The result:

    enter image description here