LogFormatter tickmarks scientific format limits
Asked Answered
S

1

3

I'm trying to plot over a wide range with a log-scaled axis, but I want to show 10^{-1}, 10^0, 10^1 as just 0.1, 1, 10. ScalarFormatter will change everything to integers instead of scientific notation, but I'd like most of the tickmark labels to be scientific; I'm only wanting to change a few of the labels. So the MWE is

import numpy as np
import matplotlib as plt
fig = plt.figure(figsize=[7,7])
ax1 = fig.add_subplot(111)
ax1.set_yscale('log')
ax1.set_xscale('log')
ax1.plot(np.logspace(-4,4), np.logspace(-4,4))
plt.show()

and I want the middle labels on each axis to read 0.1, 1, 10 instead of 10^{-1}, 10^0, 10^1

Thanks for any help!

Shatterproof answered 11/5, 2017 at 19:21 Comment(0)
M
4

When setting set_xscale('log'), you're using a LogFormatterSciNotation (not a ScalarFormatter). You may subclass LogFormatterSciNotation to return the desired values 0.1,1,10 if they happen to be marked as ticks.

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

class CustomTicker(LogFormatterSciNotation):
    def __call__(self, x, pos=None):
        if x not in [0.1,1,10]:
            return LogFormatterSciNotation.__call__(self,x, pos=None)
        else:
            return "{x:g}".format(x=x)


fig = plt.figure(figsize=[7,7])
ax = fig.add_subplot(111)
ax.set_yscale('log')
ax.set_xscale('log')
ax.plot(np.logspace(-4,4), np.logspace(-4,4))

ax.xaxis.set_major_formatter(CustomTicker())
plt.show()

enter image description here


Update: With matplotlib 2.1 there is now a new option

Specify minimum value to format as scalar for LogFormatterMathtext
LogFormatterMathtext now includes the option to specify a minimum value exponent to format as a scalar (i.e., 0.001 instead of 10-3).

This can be done as follows, by using the rcParams (plt.rcParams['axes.formatter.min_exponent'] = 2):

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['axes.formatter.min_exponent'] = 2

fig = plt.figure(figsize=[7,7])
ax = fig.add_subplot(111)
ax.set_yscale('log')
ax.set_xscale('log')
ax.plot(np.logspace(-4,4), np.logspace(-4,4))

plt.show()

This results in the same plot as above.

Note however that this limit is symmetric, it would not allow to set only 1 and 10, but not 0.1. Hence the initial solution is more generic.

Marabelle answered 11/5, 2017 at 22:9 Comment(1)
thank you, this is excellent and I've accepted your answer and changed the title accordingly!Shatterproof

© 2022 - 2024 — McMap. All rights reserved.