28

I am having an issue with the format of the tick labels of an axis. I disabled the offset from the y_axis:

ax1.ticklabel_format(style = 'sci', useOffset=False)

and tried to put it a scientific format but all I get is:

0.00355872

but I expected something like:

3.55872...E-2

or similar.

what I really want is something like:

3.55872... (on the tick label)
x 10^2  (or something similar - on the axis label)

I could try to set the labels as static,, but in the end I will have a few tens or hundreds of plots with different values, so it needs to be set dynamically.

An alternative would be to place the y_axis offset as the label, but I also have no clue on how to do this.

tacaswell
  • 84,579
  • 22
  • 210
  • 199
jorgehumberto
  • 1,047
  • 5
  • 15
  • 33

2 Answers2

36

You should also specify axis and threshold limits:

ax1.ticklabel_format(axis='y', style='sci', scilimits=(-2,2))

This would use sci format on y axis when figures are out of the [0.01, 99] bounds.

Adobe
  • 12,967
  • 10
  • 85
  • 126
25

There are a number of ways to do this

You could just tweak the power limits (doc)

ax1.xaxis.get_major_formatter().set_powerlimits((0, 1))

which set the powers where ScalerFormatter switches to scientific notation

Or, you could use a FuncFormatter which gives you a good deal of control (but you can blow your foot off).

from matplotlib import ticker

scale_pow = 2
def my_formatter_fun(x, p):
    return "%.2f" % (x * (10 ** scale_pow))
ax1.get_xaxis().set_major_formatter(ticker.FuncFormatter(my_formatter_fun))
ax1.set_xlabel('my label ' + '$10^{{{0:d}}}$'.format(scale_pow))

FuncFormatter (doc) takes a 2 argument function that returns a string and uses that function to format the label. (Be aware, this will also change how the values are displayed in the corner of interactive figures). The second argument is for 'position' which is an argument handed when the formatter makes the labels. You can safely ignore it, but you must take it (other wise you will get errors from wrong number of arguments). This is a consequence of the unified API of all the formatters and using the formatter for displaying the location of the mouse in interactive.

tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • Cool, used FuncFormatter, but with a couple of corrections 'ax1.get_yaxis().set_major_formatter(ticker.FuncFormatter(lambda x,p :"%.2f"%(x*(10**scale_pow))))'. Just a couple of doubts: I still do not understand what are 'lambda' and 'p'. Many Thanks! :) – jorgehumberto Feb 08 '13 at 16:09
  • I guess that `FuncFormatter` wants a function with two arguments. `lambda x,p: do something` creates a function that accepts two arguments (`x` and `p`) and perform whatever operation you need to do. [See here for a tutorial](http://www.secnetix.de/olli/Python/lambda_functions.hawk) – Francesco Montesano Feb 08 '13 at 16:32
  • @jorgehumberto removed the `lambda` and added a bit of explanation about `p`. `lambda` is just a way to make a function with out `def`, it is fancy-pants python not really needed for this answer. Sorry for making it more complicated than need be. – tacaswell Feb 08 '13 at 16:39
  • @jorgehumberto your right on the `/` -> `*`, I was thinking about it differently than you asked (I wanted displayed value * 10**pow = correct value) – tacaswell Feb 08 '13 at 16:45
  • @Francesco Montesano ah, ok, so p is just a dummy argument. At first I tought it would correspond to y_axis. Thanks! :) – jorgehumberto Feb 08 '13 at 16:49
  • @tcaswell now I understand what lambda stands for. I had seen it before, but never understood why people used t, but now it makes sense :) thanks! :) – jorgehumberto Feb 08 '13 at 16:51
  • @wordsforthewise despite the review failure, your edit is correct (and I have applied it). – tacaswell Jan 14 '17 at 20:40