Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding + sign to exponent in matplotlib axes

I have a log-log plot where the range goes from 10^-3 to 10^+3. I would like values ≥10^0 to have a + sign in the exponent analogous to how values <10^0 have a - sign in the exponent. Is there an easy way to do this in matplotlib?

I looked into FuncFormatter but it seems overly complex to achieve this and also I couldn't get it to work.

like image 753
nluigi Avatar asked Feb 15 '16 17:02

nluigi


1 Answers

You can do this with a FuncFormatter from the matplotlib.ticker module. You need a condition on whether the tick's value is greater than or less than 1. So, if log10(tick value) is >0, then add the + sign in the label string, if not, then it will get its minus sign automatically.

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

# sample data
x = y = np.logspace(-3,3)

# create a figure
fig,ax = plt.subplots(1)

# plot sample data
ax.loglog(x,y)

# this is the function the FuncFormatter will use
def mylogfmt(x,pos):
    logx = np.log10(x) # to get the exponent
    if logx < 0:
        # negative sign is added automatically  
        return u"$10^{{{:.0f}}}$".format(logx)
    else:
        # we need to explicitly add the positive sign
        return u"$10^{{+{:.0f}}}$".format(logx)

# Define the formatter
formatter = ticker.FuncFormatter(mylogfmt)

# Set the major_formatter on x and/or y axes here
ax.xaxis.set_major_formatter(formatter)
ax.yaxis.set_major_formatter(formatter)

plt.show()

enter image description here

Some explanation of the format string:

"$10^{{+{:.0f}}}$".format(logx)

the double braces {{ and }} are passed to LaTeX, to signify everything within them should be raised as an exponent. We need double braces, because the single braces are used by python to contain the format string, in this case {:.0f}. For more explanation of format specifications, see the docs here, but the TL;DR for your case is we are formatting a float with a precision of 0 decimal places (i.e. printing it essentially as an integer); the exponent is a float in this case because np.log10 returns a float. (one could alternatively convert the output of np.log10 to an int, and then format the string as an int - just a matter of your preference which you prefer).

like image 162
tmdavison Avatar answered Oct 11 '22 02:10

tmdavison