Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the value of the axis multiplier in matplotlib?

I have to plot values in the range (0, 32000). When I do, I get the following tick labels:

0, 5000, 10000, 15000, 20000, 25000, 30000, 35000

but I would like to have the following:

0, 5, 10, 15, 20, 25, 30, 35

with the axis multiplier (that small number just below the tick labels) x 10^3. I really need x 10^3.

I know how to force matplotlib to use an axis multiplier. When I use the following:

fmt = ScalarFormatter()
fmt.set_powerlimits((-3, 3))
ax.xaxis.set_major_formatter(fmt)

or this:

pylab.ticklabel_format(axis='x', style='sci', scilimits=(-3, 3),
                       useOffset=False)

matplotlib always returns with the axis multiplier x 10^4, so I get these ugly tick labels:

0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5

You will agree that the multiplier x 10^3 results in a lot nicer tick labels. How do I set 10^3 instead of 10^4?

This question is similar but does not concern setting a concrete value for the axis multiplier.

like image 572
nedim Avatar asked Mar 06 '15 17:03

nedim


People also ask

How do you change axis increments in Python?

To change the range of X and Y axes, we can use xlim() and ylim() methods.

How do I control the number of Xticks in Matplotlib?

locator_params() to change the number of ticks on an axis. Call matplotlib. pyplot. locator_params(axis=an_axis, nbins=num_ticks) with either "x" or "y" for an_axis to set the number of ticks to num_ticks .


1 Answers

From the available tickers, two options are:

  1. EngFormatter()
  2. FuncFormatter()

Using EngFormatter you get the SI prefixes, and optionally a unit by passing unit='Hz' for example.

More generally, you can define your own formatter

scale_factor = 10**3
fmt = mpl.ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x/scale_factor))

Edit: You could also sub-class ScalarFormatter and override the order of magnitude determination, as in:

class MagnitudeFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self, exponent=None):
        super().__init__()
        self._fixed_exponent = exponent

    def _set_order_of_magnitude(self):
        if self._fixed_exponent:
            self.orderOfMagnitude = self._fixed_exponent
        else:
            super()._set_order_of_magnitude()

Then using MagnitudeFormatter(3) as your formatter. This has the benefit in that it retains the "1e3" axis decoration.

like image 66
Graeme Avatar answered Sep 18 '22 20:09

Graeme