{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Axis ticks\n\nThe x and y Axis on each Axes have default tick \"locators\" and \"formatters\"\nthat depend on the scale being used (see `user_axes_scales`). It is\npossible to customize the ticks and tick labels with either high-level methods\nlike `~.axes.Axes.set_xticks` or set the locators and formatters directly on\nthe axis.\n\n## Manual location and formats\n\nThe simplest method to customize the tick locations and formats is to use\n`~.axes.Axes.set_xticks` and `~.axes.Axes.set_yticks`. These can be used on\neither the major or the minor ticks.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\nimport matplotlib.pyplot as plt\n\nimport matplotlib.ticker as ticker\n\n\nfig, axs = plt.subplots(2, 1, figsize=(5.4, 5.4), layout='constrained')\nx = np.arange(100)\nfor nn, ax in enumerate(axs):\n ax.plot(x, x)\n if nn == 1:\n ax.set_title('Manual ticks')\n ax.set_yticks(np.arange(0, 100.1, 100/3))\n xticks = np.arange(0.50, 101, 20)\n xlabels = [f'\\\\${x:1.2f}' for x in xticks]\n ax.set_xticks(xticks, labels=xlabels)\n else:\n ax.set_title('Automatic ticks')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the length of the ``labels`` argument must have the same length as\nthe array used to specify the ticks.\n\nBy default `~.axes.Axes.set_xticks` and `~.axes.Axes.set_yticks` act on the\nmajor ticks of an Axis, however it is possible to add minor ticks:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(2, 1, figsize=(5.4, 5.4), layout='constrained')\nx = np.arange(100)\nfor nn, ax in enumerate(axs):\n ax.plot(x, x)\n if nn == 1:\n ax.set_title('Manual ticks')\n ax.set_yticks(np.arange(0, 100.1, 100/3))\n ax.set_yticks(np.arange(0, 100.1, 100/30), minor=True)\n else:\n ax.set_title('Automatic ticks')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Locators and Formatters\n\nManually setting the ticks as above works well for specific final plots, but\ndoes not adapt as the user interacts with the Axes. At a lower level,\nMatplotlib has ``Locators`` that are meant to automatically choose ticks\ndepending on the current view limits of the axis, and ``Formatters`` that are\nmeant to format the tick labels automatically.\n\nThe full list of locators provided by Matplotlib are listed at\n`locators`, and the formatters at `formatters`.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def setup(ax, title):\n \"\"\"Set up common parameters for the Axes in the example.\"\"\"\n # only show the bottom spine\n ax.yaxis.set_major_locator(ticker.NullLocator())\n ax.spines[['left', 'right', 'top']].set_visible(False)\n\n ax.xaxis.set_ticks_position('bottom')\n ax.tick_params(which='major', width=1.00, length=5)\n ax.tick_params(which='minor', width=0.75, length=2.5)\n ax.set_xlim(0, 5)\n ax.set_ylim(0, 1)\n ax.text(0.0, 0.2, title, transform=ax.transAxes,\n fontsize=14, fontname='Monospace', color='tab:blue')\n\n\nfig, axs = plt.subplots(8, 1, layout='constrained')\n\n# Null Locator\nsetup(axs[0], title=\"NullLocator()\")\naxs[0].xaxis.set_major_locator(ticker.NullLocator())\naxs[0].xaxis.set_minor_locator(ticker.NullLocator())\n\n# Multiple Locator\nsetup(axs[1], title=\"MultipleLocator(0.5)\")\naxs[1].xaxis.set_major_locator(ticker.MultipleLocator(0.5))\naxs[1].xaxis.set_minor_locator(ticker.MultipleLocator(0.1))\n\n# Fixed Locator\nsetup(axs[2], title=\"FixedLocator([0, 1, 5])\")\naxs[2].xaxis.set_major_locator(ticker.FixedLocator([0, 1, 5]))\naxs[2].xaxis.set_minor_locator(ticker.FixedLocator(np.linspace(0.2, 0.8, 4)))\n\n# Linear Locator\nsetup(axs[3], title=\"LinearLocator(numticks=3)\")\naxs[3].xaxis.set_major_locator(ticker.LinearLocator(3))\naxs[3].xaxis.set_minor_locator(ticker.LinearLocator(31))\n\n# Index Locator\nsetup(axs[4], title=\"IndexLocator(base=0.5, offset=0.25)\")\naxs[4].plot(range(0, 5), [0]*5, color='white')\naxs[4].xaxis.set_major_locator(ticker.IndexLocator(base=0.5, offset=0.25))\n\n# Auto Locator\nsetup(axs[5], title=\"AutoLocator()\")\naxs[5].xaxis.set_major_locator(ticker.AutoLocator())\naxs[5].xaxis.set_minor_locator(ticker.AutoMinorLocator())\n\n# MaxN Locator\nsetup(axs[6], title=\"MaxNLocator(n=4)\")\naxs[6].xaxis.set_major_locator(ticker.MaxNLocator(4))\naxs[6].xaxis.set_minor_locator(ticker.MaxNLocator(40))\n\n# Log Locator\nsetup(axs[7], title=\"LogLocator(base=10, numticks=15)\")\naxs[7].set_xlim(10**3, 10**10)\naxs[7].set_xscale('log')\naxs[7].xaxis.set_major_locator(ticker.LogLocator(base=10, numticks=15))\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, we can specify \"Formatters\" for the major and minor ticks on each\naxis.\n\nThe tick format is configured via the function `~.Axis.set_major_formatter`\nor `~.Axis.set_minor_formatter`. It accepts:\n\n- a format string, which implicitly creates a `.StrMethodFormatter`.\n- a function, implicitly creates a `.FuncFormatter`.\n- an instance of a `.Formatter` subclass. The most common are\n\n - `.NullFormatter`: No labels on the ticks.\n - `.StrMethodFormatter`: Use string `str.format` method.\n - `.FormatStrFormatter`: Use %-style formatting.\n - `.FuncFormatter`: Define labels through a function.\n - `.FixedFormatter`: Set the label strings explicitly.\n - `.ScalarFormatter`: Default formatter for scalars: auto-pick the format string.\n - `.PercentFormatter`: Format labels as a percentage.\n\nSee `formatters` for the complete list.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def setup(ax, title):\n \"\"\"Set up common parameters for the Axes in the example.\"\"\"\n # only show the bottom spine\n ax.yaxis.set_major_locator(ticker.NullLocator())\n ax.spines[['left', 'right', 'top']].set_visible(False)\n\n # define tick positions\n ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))\n ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))\n\n ax.xaxis.set_ticks_position('bottom')\n ax.tick_params(which='major', width=1.00, length=5)\n ax.tick_params(which='minor', width=0.75, length=2.5, labelsize=10)\n ax.set_xlim(0, 5)\n ax.set_ylim(0, 1)\n ax.text(0.0, 0.2, title, transform=ax.transAxes,\n fontsize=14, fontname='Monospace', color='tab:blue')\n\n\nfig = plt.figure(figsize=(8, 8), layout='constrained')\nfig0, fig1, fig2 = fig.subfigures(3, height_ratios=[1.5, 1.5, 7.5])\n\nfig0.suptitle('String Formatting', fontsize=16, x=0, ha='left')\nax0 = fig0.subplots()\n\nsetup(ax0, title=\"'{x} km'\")\nax0.xaxis.set_major_formatter('{x} km')\n\nfig1.suptitle('Function Formatting', fontsize=16, x=0, ha='left')\nax1 = fig1.subplots()\n\nsetup(ax1, title=\"def(x, pos): return str(x-5)\")\nax1.xaxis.set_major_formatter(lambda x, pos: str(x-5))\n\nfig2.suptitle('Formatter Object Formatting', fontsize=16, x=0, ha='left')\naxs2 = fig2.subplots(7, 1)\n\nsetup(axs2[0], title=\"NullFormatter()\")\naxs2[0].xaxis.set_major_formatter(ticker.NullFormatter())\n\nsetup(axs2[1], title=\"StrMethodFormatter('{x:.3f}')\")\naxs2[1].xaxis.set_major_formatter(ticker.StrMethodFormatter(\"{x:.3f}\"))\n\nsetup(axs2[2], title=\"FormatStrFormatter('#%d')\")\naxs2[2].xaxis.set_major_formatter(ticker.FormatStrFormatter(\"#%d\"))\n\n\ndef fmt_two_digits(x, pos):\n return f'[{x:.2f}]'\n\n\nsetup(axs2[3], title='FuncFormatter(\"[{:.2f}]\".format)')\naxs2[3].xaxis.set_major_formatter(ticker.FuncFormatter(fmt_two_digits))\n\nsetup(axs2[4], title=\"FixedFormatter(['A', 'B', 'C', 'D', 'E', 'F'])\")\n# FixedFormatter should only be used together with FixedLocator.\n# Otherwise, one cannot be sure where the labels will end up.\npositions = [0, 1, 2, 3, 4, 5]\nlabels = ['A', 'B', 'C', 'D', 'E', 'F']\naxs2[4].xaxis.set_major_locator(ticker.FixedLocator(positions))\naxs2[4].xaxis.set_major_formatter(ticker.FixedFormatter(labels))\n\nsetup(axs2[5], title=\"ScalarFormatter()\")\naxs2[5].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))\n\nsetup(axs2[6], title=\"PercentFormatter(xmax=5)\")\naxs2[6].xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Styling ticks (tick parameters)\n\nThe appearance of ticks can be controlled at a low level by finding the\nindividual `~.axis.Tick` on the axis. However, usually it is simplest to\nuse `~.axes.Axes.tick_params` to change all the objects at once.\n\nThe ``tick_params`` method can change the properties of ticks:\n\n- length\n- direction (in or out of the frame)\n- colors\n- width and length\n- and whether the ticks are drawn at the bottom, top, left, or right of the\n Axes.\n\nIt also can control the tick labels:\n\n- labelsize (fontsize)\n- labelcolor (color of the label)\n- labelrotation\n- labelbottom, labeltop, labelleft, labelright\n\nIn addition there is a *pad* keyword argument that specifies how far the tick\nlabel is from the tick.\n\nFinally, the grid linestyles can be set:\n\n- grid_color\n- grid_alpha\n- grid_linewidth\n- grid_linestyle\n\nAll these properties can be restricted to one axis, and can be applied to\njust the major or minor ticks\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(1, 2, figsize=(6.4, 3.2), layout='constrained')\n\nfor nn, ax in enumerate(axs):\n ax.plot(np.arange(100))\n if nn == 1:\n ax.grid('on')\n ax.tick_params(right=True, left=False, axis='y', color='r', length=16,\n grid_color='none')\n ax.tick_params(axis='x', color='m', length=4, direction='in', width=4,\n labelcolor='g', grid_color='b')" ] } ], "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.13.2" } }, "nbformat": 4, "nbformat_minor": 0 }