Log scale#

Examples of plots with logarithmic axes.

You can set the x/y axes to be logarithmic by passing "log" to set_xscale / set_yscale.

Convenience functions semilogx, semilogy, and loglog#

Since plotting data on semi-logarithmic or double-logarithmic scales is very common, the functions semilogx, semilogy, and loglog are shortcuts for setting the scale and plotting data; e.g. ax.semilogx(x, y) is equivalent to ax.set_xscale('log'); ax.plot(x, y).

import matplotlib.pyplot as plt
import numpy as np

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, layout='constrained', figsize=(7, 7/3))
# log x axis
t = np.arange(0.01, 10.0, 0.01)
ax1.semilogx(t, np.sin(2 * np.pi * t))
ax1.set(title='semilogx')
ax1.grid()
ax1.grid(which="minor", color="0.9")

# log y axis
x = np.arange(4)
ax2.semilogy(4*x, 10**x, 'o--')
ax2.set(title='semilogy')
ax2.grid()
ax2.grid(which="minor", color="0.9")

# log x and y axis
x = np.array([1, 10, 100, 1000])
ax3.loglog(x, 5 * x, 'o--')
ax3.set(title='loglog')
ax3.grid()
ax3.grid(which="minor", color="0.9")
semilogx, semilogy, loglog

Logarithms with other bases#

By default, the log scale is to the base 10. One can change this via the base parameter.

fig, ax = plt.subplots()
ax.bar(["L1 cache", "L2 cache", "L3 cache", "RAM", "SSD"],
       [32, 1_000, 32_000, 16_000_000, 512_000_000])
ax.set_yscale('log', base=2)
ax.set_yticks([1, 2**10, 2**20, 2**30], labels=['kB', 'MB', 'GB', 'TB'])
ax.set_title("Typical memory sizes")
ax.yaxis.grid()
Typical memory sizes

Dealing with negative values#

Non-positive values cannot be displayed on a log scale. The scale has two options to handle these. Either mask the values so that they are ignored, or clip them to a small positive value. Which one is more suited depends on the type of the data and the visualization.

The following example contains errorbars going negative. If we mask these values, the bar vanishes, which is not desirable. In contrast, clipping makes the value small positive (but well below the used scale) so that the error bar is drawn to the edge of the Axes.

x = np.linspace(0.0, 2.0, 10)
y = 10**x
yerr = 1.75 + 0.75*y

fig, (ax1, ax2) = plt.subplots(1, 2, layout="constrained", figsize=(6, 3))
fig.suptitle("errorbars going negative")
ax1.set_yscale("log", nonpositive='mask')
ax1.set_title('nonpositive="mask"')
ax1.errorbar(x, y, yerr=yerr, fmt='o', capsize=5)

ax2.set_yscale("log", nonpositive='clip')
ax2.set_title('nonpositive="clip"')
ax2.errorbar(x, y, yerr=yerr, fmt='o', capsize=5)

plt.show()
errorbars going negative, nonpositive=

Total running time of the script: (0 minutes 2.707 seconds)

Gallery generated by Sphinx-Gallery