{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n.. redirect-from:: /tutorials/introductory/pyplot\n\n\n# Pyplot tutorial\n\nAn introduction to the pyplot interface. Please also see\n`quick_start` for an overview of how Matplotlib\nworks and `api_interfaces` for an explanation of the trade-offs between the\nsupported user APIs.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction to pyplot\n\n:mod:`matplotlib.pyplot` is a collection of functions that make matplotlib\nwork like MATLAB. Each ``pyplot`` function makes some change to a figure:\ne.g., creates a figure, creates a plotting area in a figure, plots some lines\nin a plotting area, decorates the plot with labels, etc.\n\nIn :mod:`matplotlib.pyplot` various states are preserved\nacross function calls, so that it keeps track of things like\nthe current figure and plotting area, and the plotting\nfunctions are directed to the current Axes (please note that we use uppercase\nAxes to refer to the `~.axes.Axes` concept, which is a central\n`part of a figure `\nand not only the plural of *axis*).\n\n

Note

The implicit pyplot API is generally less verbose but also not as flexible as the\n explicit API. Most of the function calls you see here can also be called\n as methods from an ``Axes`` object. We recommend browsing the tutorials\n and examples to see how this works. See `api_interfaces` for an\n explanation of the trade-off of the supported user APIs.

\n\nGenerating visualizations with pyplot is very quick:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n\nplt.plot([1, 2, 3, 4])\nplt.ylabel('some numbers')\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may be wondering why the x-axis ranges from 0-3 and the y-axis\nfrom 1-4. If you provide a single list or array to\n`~.pyplot.plot`, matplotlib assumes it is a\nsequence of y values, and automatically generates the x values for\nyou. Since python ranges start with 0, the default x vector has the\nsame length as y but starts with 0; therefore, the x data are\n``[0, 1, 2, 3]``.\n\n`~.pyplot.plot` is a versatile function, and will take an arbitrary number of\narguments. For example, to plot x versus y, you can write:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "plt.plot([1, 2, 3, 4], [1, 4, 9, 16])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Formatting the style of your plot\n\nFor every x, y pair of arguments, there is an optional third argument\nwhich is the format string that indicates the color and line type of\nthe plot. The letters and symbols of the format string are from\nMATLAB, and you concatenate a color string with a line style string.\nThe default format string is 'b-', which is a solid blue line. For\nexample, to plot the above with red circles, you would issue\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro')\nplt.axis((0, 6, 0, 20))\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See the `~.pyplot.plot` documentation for a complete\nlist of line styles and format strings. The\n`~.pyplot.axis` function in the example above takes a\nlist of ``[xmin, xmax, ymin, ymax]`` and specifies the viewport of the\nAxes.\n\nIf matplotlib were limited to working with lists, it would be fairly\nuseless for numeric processing. Generally, you will use [numpy](https://numpy.org/) arrays. In fact, all sequences are\nconverted to numpy arrays internally. The example below illustrates\nplotting several lines with different format styles in one function call\nusing arrays.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\n# evenly sampled time at 200ms intervals\nt = np.arange(0., 5., 0.2)\n\n# red dashes, blue squares and green triangles\nplt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n## Plotting with keyword strings\n\nThere are some instances where you have data in a format that lets you\naccess particular variables with strings. For example, with `structured arrays`_\nor `pandas.DataFrame`.\n\n\nMatplotlib allows you to provide such an object with\nthe ``data`` keyword argument. If provided, then you may generate plots with\nthe strings corresponding to these variables.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = {'a': np.arange(50),\n 'c': np.random.randint(0, 50, 50),\n 'd': np.random.randn(50)}\ndata['b'] = data['a'] + 10 * np.random.randn(50)\ndata['d'] = np.abs(data['d']) * 100\n\nplt.scatter('a', 'b', c='c', s='d', data=data)\nplt.xlabel('entry a')\nplt.ylabel('entry b')\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n## Plotting with categorical variables\n\nIt is also possible to create a plot using categorical variables.\nMatplotlib allows you to pass categorical variables directly to\nmany plotting functions. For example:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "names = ['group_a', 'group_b', 'group_c']\nvalues = [1, 10, 100]\n\nplt.figure(figsize=(9, 3))\n\nplt.subplot(131)\nplt.bar(names, values)\nplt.subplot(132)\nplt.scatter(names, values)\nplt.subplot(133)\nplt.plot(names, values)\nplt.suptitle('Categorical Plotting')\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n## Controlling line properties\n\nLines have many attributes that you can set: linewidth, dash style,\nantialiased, etc; see `matplotlib.lines.Line2D`. There are\nseveral ways to set line properties\n\n* Use keyword arguments::\n\n plt.plot(x, y, linewidth=2.0)\n\n\n* Use the setter methods of a ``Line2D`` instance. ``plot`` returns a list\n of ``Line2D`` objects; e.g., ``line1, line2 = plot(x1, y1, x2, y2)``. In the code\n below we will suppose that we have only\n one line so that the list returned is of length 1. We use tuple unpacking with\n ``line,`` to get the first element of that list::\n\n line, = plt.plot(x, y, '-')\n line.set_antialiased(False) # turn off antialiasing\n\n* Use `~.pyplot.setp`. The example below\n uses a MATLAB-style function to set multiple properties\n on a list of lines. ``setp`` works transparently with a list of objects\n or a single object. You can either use python keyword arguments or\n MATLAB-style string/value pairs::\n\n lines = plt.plot(x1, y1, x2, y2)\n # use keyword arguments\n plt.setp(lines, color='r', linewidth=2.0)\n # or MATLAB style string value pairs\n plt.setp(lines, 'color', 'r', 'linewidth', 2.0)\n\n\nHere are the available `~.lines.Line2D` properties.\n\n====================== ==================================================\nProperty Value Type\n====================== ==================================================\nalpha float\nanimated [True | False]\nantialiased or aa [True | False]\nclip_box a matplotlib.transform.Bbox instance\nclip_on [True | False]\nclip_path a Path instance and a Transform instance, a Patch\ncolor or c any matplotlib color\ncontains the hit testing function\ndash_capstyle [``'butt'`` | ``'round'`` | ``'projecting'``]\ndash_joinstyle [``'miter'`` | ``'round'`` | ``'bevel'``]\ndashes sequence of on/off ink in points\ndata (np.array xdata, np.array ydata)\nfigure a matplotlib.figure.Figure instance\nlabel any string\nlinestyle or ls [ ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'steps'`` | ...]\nlinewidth or lw float value in points\nmarker [ ``'+'`` | ``','`` | ``'.'`` | ``'1'`` | ``'2'`` | ``'3'`` | ``'4'`` ]\nmarkeredgecolor or mec any matplotlib color\nmarkeredgewidth or mew float value in points\nmarkerfacecolor or mfc any matplotlib color\nmarkersize or ms float\nmarkevery [ None | integer | (startind, stride) ]\npicker used in interactive line selection\npickradius the line pick selection radius\nsolid_capstyle [``'butt'`` | ``'round'`` | ``'projecting'``]\nsolid_joinstyle [``'miter'`` | ``'round'`` | ``'bevel'``]\ntransform a matplotlib.transforms.Transform instance\nvisible [True | False]\nxdata np.array\nydata np.array\nzorder any number\n====================== ==================================================\n\nTo get a list of settable line properties, call the\n`~.pyplot.setp` function with a line or lines as argument\n\n.. sourcecode:: ipython\n\n In [69]: lines = plt.plot([1, 2, 3])\n\n In [70]: plt.setp(lines)\n alpha: float\n animated: [True | False]\n antialiased or aa: [True | False]\n ...snip\n\n\n\n## Working with multiple figures and Axes\n\nMATLAB, and :mod:`.pyplot`, have the concept of the current figure\nand the current Axes. All plotting functions apply to the current\nAxes. The function `~.pyplot.gca` returns the current Axes (a\n`matplotlib.axes.Axes` instance), and `~.pyplot.gcf` returns the current\nfigure (a `matplotlib.figure.Figure` instance). Normally, you don't have to\nworry about this, because it is all taken care of behind the scenes. Below\nis a script to create two subplots.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def f(t):\n return np.exp(-t) * np.cos(2*np.pi*t)\n\nt1 = np.arange(0.0, 5.0, 0.1)\nt2 = np.arange(0.0, 5.0, 0.02)\n\nplt.figure()\nplt.subplot(211)\nplt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')\n\nplt.subplot(212)\nplt.plot(t2, np.cos(2*np.pi*t2), 'r--')\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `~.pyplot.figure` call here is optional because a figure will be created\nif none exists, just as an Axes will be created (equivalent to an explicit\n``subplot()`` call) if none exists.\nThe `~.pyplot.subplot` call specifies ``numrows,\nnumcols, plot_number`` where ``plot_number`` ranges from 1 to\n``numrows*numcols``. The commas in the ``subplot`` call are\noptional if ``numrows*numcols<10``. So ``subplot(211)`` is identical\nto ``subplot(2, 1, 1)``.\n\nYou can create an arbitrary number of subplots\nand Axes. If you want to place an Axes manually, i.e., not on a\nrectangular grid, use `~.pyplot.axes`,\nwhich allows you to specify the location as ``axes([left, bottom,\nwidth, height])`` where all values are in fractional (0 to 1)\ncoordinates. See :doc:`/gallery/subplots_axes_and_figures/axes_demo` for an example of\nplacing Axes manually and :doc:`/gallery/subplots_axes_and_figures/subplot` for an\nexample with lots of subplots.\n\nYou can create multiple figures by using multiple\n`~.pyplot.figure` calls with an increasing figure\nnumber. Of course, each figure can contain as many Axes and subplots\nas your heart desires::\n\n import matplotlib.pyplot as plt\n plt.figure(1) # the first figure\n plt.subplot(211) # the first subplot in the first figure\n plt.plot([1, 2, 3])\n plt.subplot(212) # the second subplot in the first figure\n plt.plot([4, 5, 6])\n\n\n plt.figure(2) # a second figure\n plt.plot([4, 5, 6]) # creates a subplot() by default\n\n plt.figure(1) # first figure current;\n # subplot(212) still current\n plt.subplot(211) # make subplot(211) in the first figure\n # current\n plt.title('Easy as 1, 2, 3') # subplot 211 title\n\nYou can clear the current figure with `~.pyplot.clf`\nand the current Axes with `~.pyplot.cla`. If you find\nit annoying that states (specifically the current image, figure and Axes)\nare being maintained for you behind the scenes, don't despair: this is just a thin\nstateful wrapper around an object-oriented API, which you can use\ninstead (see `artists_tutorial`)\n\nIf you are making lots of figures, you need to be aware of one\nmore thing: the memory required for a figure is not completely\nreleased until the figure is explicitly closed with\n`~.pyplot.close`. Deleting all references to the\nfigure, and/or using the window manager to kill the window in which\nthe figure appears on the screen, is not enough, because pyplot\nmaintains internal references until `~.pyplot.close`\nis called.\n\n\n## Working with text\n\n`~.pyplot.text` can be used to add text in an arbitrary location, and\n`~.pyplot.xlabel`, `~.pyplot.ylabel` and `~.pyplot.title` are used to add\ntext in the indicated locations (see `text_intro` for a\nmore detailed example)\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mu, sigma = 100, 15\nx = mu + sigma * np.random.randn(10000)\n\n# the histogram of the data\nn, bins, patches = plt.hist(x, 50, density=True, facecolor='g', alpha=0.75)\n\n\nplt.xlabel('Smarts')\nplt.ylabel('Probability')\nplt.title('Histogram of IQ')\nplt.text(60, .025, r'$\\mu=100,\\ \\sigma=15$')\nplt.axis([40, 160, 0, 0.03])\nplt.grid(True)\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All of the `~.pyplot.text` functions return a `matplotlib.text.Text`\ninstance. Just as with lines above, you can customize the properties by\npassing keyword arguments into the text functions or using `~.pyplot.setp`::\n\n t = plt.xlabel('my data', fontsize=14, color='red')\n\nThese properties are covered in more detail in `text_props`.\n\n\n### Using mathematical expressions in text\n\nMatplotlib accepts TeX equation expressions in any text expression.\nFor example to write the expression $\\sigma_i=15$ in the title,\nyou can write a TeX expression surrounded by dollar signs::\n\n plt.title(r'$\\sigma_i=15$')\n\nThe ``r`` preceding the title string is important -- it signifies\nthat the string is a *raw* string and not to treat backslashes as\npython escapes. matplotlib has a built-in TeX expression parser and\nlayout engine, and ships its own math fonts -- for details see\n`mathtext`. Thus, you can use mathematical text across\nplatforms without requiring a TeX installation. For those who have LaTeX\nand dvipng installed, you can also use LaTeX to format your text and\nincorporate the output directly into your display figures or saved\npostscript -- see `usetex`.\n\n\n### Annotating text\n\nThe uses of the basic `~.pyplot.text` function above\nplace text at an arbitrary position on the Axes. A common use for\ntext is to annotate some feature of the plot, and the\n`~.pyplot.annotate` method provides helper\nfunctionality to make annotations easy. In an annotation, there are\ntwo points to consider: the location being annotated represented by\nthe argument ``xy`` and the location of the text ``xytext``. Both of\nthese arguments are ``(x, y)`` tuples.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ax = plt.subplot()\n\nt = np.arange(0.0, 5.0, 0.01)\ns = np.cos(2*np.pi*t)\nline, = plt.plot(t, s, lw=2)\n\nplt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),\n arrowprops=dict(facecolor='black', shrink=0.05),\n )\n\nplt.ylim(-2, 2)\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this basic example, both the ``xy`` (arrow tip) and ``xytext``\nlocations (text location) are in data coordinates. There are a\nvariety of other coordinate systems one can choose -- see\n`annotations-tutorial` and `plotting-guide-annotation` for\ndetails. More examples can be found in\n:doc:`/gallery/text_labels_and_annotations/annotation_demo`.\n\n\n## Logarithmic and other nonlinear axes\n\n:mod:`matplotlib.pyplot` supports not only linear axis scales, but also\nlogarithmic and logit scales. This is commonly used if data spans many orders\nof magnitude. Changing the scale of an axis is easy::\n\n plt.xscale('log')\n\nAn example of four plots with the same data and different scales for the y-axis\nis shown below.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Fixing random state for reproducibility\nnp.random.seed(19680801)\n\n# make up some data in the open interval (0, 1)\ny = np.random.normal(loc=0.5, scale=0.4, size=1000)\ny = y[(y > 0) & (y < 1)]\ny.sort()\nx = np.arange(len(y))\n\n# plot with various axes scales\nplt.figure()\n\n# linear\nplt.subplot(221)\nplt.plot(x, y)\nplt.yscale('linear')\nplt.title('linear')\nplt.grid(True)\n\n# log\nplt.subplot(222)\nplt.plot(x, y)\nplt.yscale('log')\nplt.title('log')\nplt.grid(True)\n\n# symmetric log\nplt.subplot(223)\nplt.plot(x, y - y.mean())\nplt.yscale('symlog', linthresh=0.01)\nplt.title('symlog')\nplt.grid(True)\n\n# logit\nplt.subplot(224)\nplt.plot(x, y)\nplt.yscale('logit')\nplt.title('logit')\nplt.grid(True)\n# Adjust the subplot layout, because the logit one may take more space\n# than usual, due to y-tick labels like \"1 - 10^{-3}\"\nplt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,\n wspace=0.35)\n\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is also possible to add your own scale, see `matplotlib.scale` for\ndetails.\n\n" ] } ], "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 }