4

So what I want is to have my pyplot ticks in scientific notation. So each tick looks like 1x10^6 rather than 1 and then the 10^6 on the axis. The only way I've been able to do this so far is by manually setting each ticklabel as r'$1\times10^6$', but this puts it in the mathematical expression font and set_yticklabels wont listen if I try to pass a fontdict.

How would I accomplish this?

hachteja
  • 91
  • 1
  • 5
  • http://stackoverflow.com/questions/11855363/how-to-remove-relative-shift-in-matplotlib-axis/11858063#11858063 – tacaswell Nov 21 '13 at 17:24
  • possible duplicate of [How to prevent numbers being changed to exponential form in Python matplotlib figure](http://stackoverflow.com/questions/14711655/how-to-prevent-numbers-being-changed-to-exponential-form-in-python-matplotlib-fi) – tacaswell Nov 21 '13 at 17:25
  • http://stackoverflow.com/questions/16777110/pyplot-display-large-numbers-in-interactive-mode?lq=1 – tacaswell Nov 21 '13 at 17:25
  • This is not a duplicate of any of those topics. I want scientific notation, and I have no offset, it just separates the order of magnitude from each tick label. I don't want it to do that. – hachteja Apr 11 '14 at 21:03

3 Answers3

5

I'm not sure if I understand your question correctly, but do you want something like this?

import matplotlib.pyplot as plt
import numpy as np
plt.plot(np.logspace(1,10,10),np.logspace(1,5,10))
ax = plt.gca()
ax.get_xaxis().set_major_formatter(plt.LogFormatter(10,  labelOnlyBase=False))
ax.get_yaxis().set_major_formatter(plt.LogFormatter(10,  labelOnlyBase=False))

which gives
enter image description here

Update:

The approach shown above only works if the data range is big enough. If the scientific notation is wanted for a smaller range a custom Formatter can be used as

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

def MyFormatter(x,lim):
    if x == 0:
        return 0
    return '{0:.2f}e{1:.2f}'.format(np.sign(x)*10**(-np.floor(np.log10(abs(x)))+np.log10(abs(x))),np.floor(np.log10(abs(x))))
    #The first argument of the format gives the first significant digits of the number with the sign preserved and brought to a range between [1-10), The next argument gives the  numbers integer exponent of 10
    #Both the first and second arguments are formatted to display only 2 decimal places due to the lack of space.

majorFormatter = FuncFormatter(MyFormatter)

t = np.arange(0.0, 100.0, 0.1)
s = np.sin(0.1*np.pi*t)*np.exp(-t*0.01)

fig, ax = plt.subplots()
plt.plot(t,s)

ax.xaxis.set_major_formatter(majorFormatter)

This gives a plot like
enter image description here

Vikramark
  • 137
  • 13
Jakob
  • 19,815
  • 6
  • 75
  • 94
  • Yes this is what I want, but I don't know how to do that with ScalarFormatter rather than LogFormatter – hachteja Apr 11 '14 at 21:04
  • The scientific notation is created using the LogFormatter, so I don't see your point. – Jakob Apr 11 '14 at 21:18
0

The (updated) answer did not work for me with negative values (since log(x) returns Nan for negative x).

Also, I think the following is much simpler:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

def MyFormatter(x,lim):
  if x == 0:
      return 0
  else:
    x = str(x).split("e")
    return x[0] + r"$\times 10^{" + x[1] + r"}$"
  # end if/else
# end def
majorFormatter = FuncFormatter(MyFormatter)

t = np.arange(0.0, 100.0, 0.1)
s = np.sin(0.1*np.pi*t)*np.exp(-t*0.01)

fig, ax = plt.subplots()
plt.plot(t,s)

ax.xaxis.set_major_formatter(majorFormatter)
Ryan Farber
  • 343
  • 1
  • 4
  • 11
0

building on the answer of Jakob but using python's built in scientific notation string formatting

from matplotlib.ticker import FuncFormatter
from matplotlib import pyplot as plt

def sci_format(x,lim):
    return '{:.1e}'.format(x)

major_formatter = FuncFormatter(sci_format)

t = np.arange(0.0, 100.0, 0.1)
s = np.sin(0.1*np.pi*t) * np.exp(-t*0.01)

fig, ax = plt.subplots()
plt.plot(t, s)

ax.xaxis.set_major_formatter(major_formatter)
lunguini
  • 896
  • 1
  • 9
  • 14