14

I have an image:

enter image description here

Here in the y-axis I would like to get 5x10^-5 4x10^-5 and so on instead of 0.00005 0.00004.

What I have tried so far is:

fig = plt.figure()
ax = fig.add_subplot(111)
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=True)
ax.yaxis.set_major_formatter(y_formatter)

ax.plot(m_plot,densities1,'-ro',label='0.0<z<0.5')
ax.plot(m_plot,densities2, '-bo',label='0.5<z<1.0')


ax.legend(loc='best',scatterpoints=1)
plt.legend()
plt.show() 

This does not seem to work. The document page for tickers does not seem to provide a direct answer.

user3397243
  • 567
  • 2
  • 10
  • 20

2 Answers2

22

You can use matplotlib.ticker.FuncFormatter to choose the format of your ticks with a function as shown in the example code below. Effectively all the function is doing is converting the input (a float) into exponential notation and then replacing the 'e' with 'x10^' so you get the format that you want.

import matplotlib.pyplot as plt
import matplotlib.ticker as tick
import numpy as np

x = np.linspace(0, 10, 1000)
y = 0.000001*np.sin(10*x)

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(x, y)

def y_fmt(x, y):
    return '{:2.2e}'.format(x).replace('e', 'x10^')

ax.yaxis.set_major_formatter(tick.FuncFormatter(y_fmt))

plt.show()

image

If you're willing to use exponential notation (i.e. 5.0e-6.0) however then there is a much tidier solution where you use matplotlib.ticker.FormatStrFormatter to choose a format string as shown below. The string format is given by the standard Python string formatting rules.

...

y_fmt = tick.FormatStrFormatter('%2.2e')
ax.yaxis.set_major_formatter(y_fmt)

...
Ffisegydd
  • 51,807
  • 15
  • 147
  • 125
  • 2
    what does the `%2.2e` in your short solution do? – user3397243 Aug 04 '14 at 13:45
  • 4
    `%2.2e` chooses the format that you want your strings to be in. The numbers choose now many decimal places you want and the e chooses scientific notation. You can find more detail [here](https://docs.python.org/2/library/stdtypes.html#string-formatting). – Ffisegydd Aug 04 '14 at 13:48
  • the function y_fmt(x,y) has two arguments but I don't see y, used in the function. I have seen this behavior before, what is it called? And how should I read it? – JMJ Nov 08 '16 at 04:03
  • x is the value and y the index of the tick. You do not need "y" in general. Of course "y" can be used to do formatting based on tick position. – nvd Mar 03 '17 at 14:15
  • 2
    if I have 1000, 2000, ...10000, do you know how I can show them as 1K, 2K, 10K? – weefwefwqg3 Feb 21 '18 at 05:22
  • @weefwefwqg3 write an appropriate function and use `tick.FuncFormatter` – abukaj Apr 27 '18 at 16:34
  • @JMJ From the [docs](https://matplotlib.org/3.3.1/gallery/ticks_and_spines/tick-formatters.html): _A function can also be used directly as a formatter. The function must take two arguments: ``x`` for the tick value and ``pos`` for the tick position, and must return a ``str`` This creates a FuncFormatter automatically._ – pfabri Sep 28 '20 at 10:05
1

Just a brief modification to the solution for better string formatting: I would recommend changing the format function to include latex formatting:

def y_fmt(x, y):
    return '${:2.1e}'.format(x).replace('e', '\\cdot 10^{') + '}$'

enter image description here

DisabledWhale
  • 771
  • 1
  • 7
  • 15