{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Log scale\n\nExamples of plots with logarithmic axes.\n\nYou can set the x/y axes to be logarithmic by passing \"log\" to `~.Axes.set_xscale` /\n`~.Axes.set_yscale`.\n\n## Convenience functions ``semilogx``, ``semilogy``, and ``loglog``\nSince plotting data on semi-logarithmic or double-logarithmic scales is very common,\nthe functions `~.Axes.semilogx`, `~.Axes.semilogy`, and `~.Axes.loglog` are shortcuts\nfor setting the scale and plotting data; e.g. ``ax.semilogx(x, y)`` is equivalent to\n``ax.set_xscale('log'); ax.plot(x, y)``.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nfig, (ax1, ax2, ax3) = plt.subplots(1, 3, layout='constrained', figsize=(7, 7/3))\n# log x axis\nt = np.arange(0.01, 10.0, 0.01)\nax1.semilogx(t, np.sin(2 * np.pi * t))\nax1.set(title='semilogx')\nax1.grid()\nax1.grid(which=\"minor\", color=\"0.9\")\n\n# log y axis\nx = np.arange(4)\nax2.semilogy(4*x, 10**x, 'o--')\nax2.set(title='semilogy')\nax2.grid()\nax2.grid(which=\"minor\", color=\"0.9\")\n\n# log x and y axis\nx = np.array([1, 10, 100, 1000])\nax3.loglog(x, 5 * x, 'o--')\nax3.set(title='loglog')\nax3.grid()\nax3.grid(which=\"minor\", color=\"0.9\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Logarithms with other bases\nBy default, the log scale is to the base 10. One can change this via the *base*\nparameter.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig, ax = plt.subplots()\nax.bar([\"L1 cache\", \"L2 cache\", \"L3 cache\", \"RAM\", \"SSD\"],\n       [32, 1_000, 32_000, 16_000_000, 512_000_000])\nax.set_yscale('log', base=2)\nax.set_yticks([1, 2**10, 2**20, 2**30], labels=['kB', 'MB', 'GB', 'TB'])\nax.set_title(\"Typical memory sizes\")\nax.yaxis.grid()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Dealing with negative values\nNon-positive values cannot be displayed on a log scale. The scale has two options\nto handle these. Either mask the values so that they are ignored, or clip them\nto a small positive value. Which one is more suited depends on the type of the\ndata and the visualization.\n\nThe following example contains errorbars going negative. If we mask these values,\nthe bar vanishes, which is not desirable. In contrast, clipping makes the value\nsmall positive (but well below the used scale) so that the error bar is drawn\nto the edge of the Axes.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "x = np.linspace(0.0, 2.0, 10)\ny = 10**x\nyerr = 1.75 + 0.75*y\n\nfig, (ax1, ax2) = plt.subplots(1, 2, layout=\"constrained\", figsize=(6, 3))\nfig.suptitle(\"errorbars going negative\")\nax1.set_yscale(\"log\", nonpositive='mask')\nax1.set_title('nonpositive=\"mask\"')\nax1.errorbar(x, y, yerr=yerr, fmt='o', capsize=5)\n\nax2.set_yscale(\"log\", nonpositive='clip')\nax2.set_title('nonpositive=\"clip\"')\nax2.errorbar(x, y, yerr=yerr, fmt='o', capsize=5)\n\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.14.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}