diff --git a/index.ipynb b/index.ipynb index 1a83ab69..f955f2e4 100644 --- a/index.ipynb +++ b/index.ipynb @@ -24,6 +24,7 @@ "\n", "# Libraries\n", "\n", + "- [Matplotlib](./library_matplotlib.ipynb)\n", "- [NumPy](./library_numpy.ipynb)\n", "- [scikit-learn](./library_sklearn.ipynb)\n", "- [SciPy](./library_scipy.ipynb)" diff --git a/library_matplotlib.ipynb b/library_matplotlib.ipynb new file mode 100644 index 00000000..add3da11 --- /dev/null +++ b/library_matplotlib.ipynb @@ -0,0 +1,1210 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Visualization with Matplotlib" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Table of Contents\n", + " - [References](#References)\n", + " - [Introduction](#Introduction)\n", + " - [Key Features](#Key-Features)\n", + " - [Customization & Extensibility](#Customization-&-Extensibility)\n", + " - [Integration with other libraries](#Integration-with-other-libraries)\n", + " - [Integration with Jupyter Notebooks](#Integration-with-Jupyter-Notebooks)\n", + " - [Display Basics](#Display-Basics)\n", + " - [Figure](#Figure)\n", + " - [Artist](#Artist)\n", + " - [Axes](#Axes)\n", + " - [Axis](#Axis)\n", + " - [The Basics of `Figure`](#The-Basics-of-Figure)\n", + " - [Helper functions](#Helper-functions)\n", + " - [Displaying Multiple Outputs](#Displaying-Multiple-Outputs)\n", + " - [Saving Figures in a File](#Saving-Figures-in-a-File)\n", + " - [The Basics of `Axes`](#The-Basics-of-Axes)\n", + " - [Labels and Text](#Labels-and-Text)\n", + " - [`Axis` Scales and Ticks](#Axis-Scales-and-Ticks)\n", + " - [Styling and Customizations](#Styling-and-Customizations)\n", + " - [Colors](#Colors)\n", + " - [Annotations and Legends](#Annotations-and-Legends)\n", + " - [Plot Types](#Plot-Types)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References\n", + "\n", + "- [Matplotlib Documentation](https://matplotlib.org/)\n", + "- [Matplotlib Cheat-sheet](https://matplotlib.org/cheatsheets/)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction\n", + "\n", + "Matplotlib is a comprehensive Python library for creating static, animated, and interactive visualizations in various formats.\n", + "It offers a wide range of functionalities for plotting graphs, histograms, bar charts, and more.\n", + "\n", + "It is widely used in various domains such as data analysis or machine learning, for visualizing data and results in a more understandable manner." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Key Features\n", + "\n", + "### Customization & Extensibility\n", + "\n", + "Matplotlib provides high-quality and publication-ready plots with customization options for colors, labels, annotations, and more. It is highly extensible and allows users to create custom plots or modify existing ones.\n", + "\n", + "### Integration with other libraries\n", + "\n", + "Matplotlib integrates seamlessly with NumPy or Pandas, making it easy to plot data directly from NumPy arrays or Pandas DataFrames.\n", + "\n", + "### Integration with Jupyter Notebooks\n", + "\n", + "Matplotlib works well with Jupyter Notebooks, allowing users to create inline visualizations for data analysis." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Display Basics: Figures and axes\n", + "\n", + "On Matplotlib, the basic unit of a graphic is called a [`Figure`](https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure).\n", + "Each `Figure` can contain one or more [`Axes`](https://matplotlib.org/stable/api/axes_api.html#the-axes-class).\n", + "An `Axes` is an area where points can be specified in terms of coordinates (x-y in a 2D plot, x-y-z in a 3D plot, etc.).\n", + "The simplest way of creating a `Figure` with an `Axes` is using `pyplot.subplots`.\n", + "\n", + "\n", + "The `Figure` keeps track of all the child `Axes`, a group of 'special' `Artists`, or even nested subfigures.\n", + "It is often convenient to create the `Axes` together with the `Figure`, but you can also manually add `Axes` later on. \n", + "\n", + "### Artist\n", + "\n", + "Basically, everything visible in the `Figure` is an `Artist`, i.e. titles, figure legends, collections objects, and even `Figure` and `Axis` objects.\n", + "When the `Figure` is rendered, all of the `Artists` are drawn to the canvas.\n", + "Most `Artists` are tied to an `Axes`; such an `Artist` cannot be shared by multiple `Axes`, or moved from one to another.\n", + "\n", + "### Axes\n", + "\n", + "An `Axes` is an `Artist` attached to a `Figure` that contains a region for plotting data, and usually includes `Axis` objects \n", + "Each `Axes` also has a title (set via `set_title()`), an x-label (set via `set_xlabel()`), and a y-label set via `set_ylabel()`).\n", + "\n", + "### Axis\n", + "\n", + "These objects set the scale and limits and generate ticks (the marks on the Axis) and ticklabels (strings labeling the ticks)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's now look at first simple example.\n", + "To do that, we must first import `pyplot` from the library.\n", + "The standard way to do that is the following:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following example creates a `Figure` containing a single `Axes`.\n", + "It then plots some sample data on the `Axes`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "fig, ax = plt.subplots()\n", + "ax.plot([1, 2, 3, 4], [1, 4, 2, 3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that your `Jupyter Notebook` directly prints the output of the code.\n", + "Depending on your backend (i.e. displaying on screen, writing to a file, etc), you sometimes may have to use `plt.show()` to display the output." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Basics of `Figure`\n", + "\n", + "The most common way to use Matplotlib, is to explicitly create `Figures` and `Axes`, and call methods on them.\n", + "This is called the **object-oriented (OO) style**. \n", + "Let's see an example:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "fig, ax = plt.subplots()\n", + "ax.plot([1, 2, 3, 4], [5, 4, 2, 3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we create a set of `Figure` and `Axes` using `subplots` and then attach a new `Artist` to the `Axes` using the `plot()` method.\n", + "This is in contrast with the older style of using the `matplotlib.pyplot` module; the **stateful style**.\n", + "In this approach you can generate plots with single commands as it is traditionally done in Matlab:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.figure()\n", + "plt.plot([0,1], [1,0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even if this seems convenient, is suggested **not to use this style**, particularly for complicated plots, or functions and scripts that are intended to be reused as part of a larger project." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Helper functions\n", + "\n", + "If you need to make the same plots multiple times with different data sets, you may use a function like the one below, which you would then call twice to populate two subplots." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib.axes import Axes\n", + "import numpy as np\n", + "\n", + "def my_plotter(ax: Axes, data1, data2):\n", + " \"\"\"\n", + " A helper function to make a graph.\n", + " \"\"\"\n", + " out = ax.plot(data1, data2)\n", + " return out\n", + "\n", + "# Make 4 random data sets. They will represent 2 2-D data sets, each with 10 points\n", + "data1, data2, data3, data4 = np.random.randn(4, 10)\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 3))\n", + "my_plotter(ax1, data1, data2)\n", + "my_plotter(ax2, data3, data4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Displaying Multiple Outputs\n", + "\n", + "You can open multiple `Figures` with multiple calls to `fig = plt.figure()` or `fig2, ax = plt.subplots()`.\n", + "By keeping the object references you can add `Artists` to either `Figure`.\n", + "\n", + "Multiple Axes can be added a number of ways, but the most common is `plt.subplots()` as used above. \n", + "This takes two arguments (1 and 2 in the example above): these are the numbers of rows and columns you want to use to arrange your `Axes`.\n", + "You can achieve more complex layouts, with `Axes` objects, using `subplot_mosaic`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib.axes import Axes\n", + "import numpy as np\n", + "fig, axd = plt.subplot_mosaic([['upleft', 'right'], ['lowleft', 'right']], layout='constrained')\n", + "\n", + "data1, data2, data3, data4, data5, data6 = np.random.randn(6, 4)\n", + "my_plotter(axd['upleft'], data1, data2)\n", + "my_plotter(axd['lowleft'], data3, data4)\n", + "my_plotter(axd['right'], data5, data6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Saving Figures in a File\n", + "\n", + "`Figures` can be saved to disk using the `savefig` method.\n", + "The following line of code will save a PNG formatted figure to the file `MyFigure.png` in the current directory on disk with 200 dots-per-inch resolution.\n", + "\n", + "Note that the filename can include a relative or absolute path to any place on the file system.\n", + "\n", + "Many types of output are supported, including formats like PNG, GIF, JPEG, TIFF and vector formats like PDF, EPS, and SVG." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fig.savefig('MyFigure.png', dpi=200)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Basics of `Axes`\n", + "\n", + "Matplotlib `Axes` are the gateway to creating your data visualizations.\n", + "Once an `Axes` is placed on a `Figure` there are many methods that can be used to add data to it.\n", + "An `Axes` typically has a pair of `Axis` `Artists` that define the data coordinate system, and include methods to add annotations like x- and y-labels, titles, and legends.\n", + "\n", + "Axes are added using methods on Figure objects, or via the `pyplot` interface as we described above.\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Labels and Text\n", + "\n", + "To add text in specific locations of your plot, you may use `set_xlabel`, `set_ylabel`, and `set_title` respectively.\n", + "Same as above, you can also customize these properties by passing keyword arguments into the functions, for `color`, `fontsize`, and more. Note that, instead of text for the labels, you are also free to use mathematical expressions.\n", + "\n", + "Text can also be directly added to plots using `text`, which takes parameters `x, y` for the position that the text will be placed, and parameter `s` for the text itself." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib.axes import Axes\n", + "import numpy as np\n", + "fig, ax = plt.subplots(figsize=(5, 3))\n", + "ax.plot([1, 2, 3, 4], [1, 4, 2, 3])\n", + "\n", + "ax.set_xlabel('x-Axis')\n", + "ax.set_ylabel('y-Axis',)\n", + "ax.set_title('My Example', fontsize=14, color='red')\n", + "ax.text(1.5, 2, r'$\\sigma_i=15$')\n", + "ax.grid(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `Axis` Scales and Ticks\n", + "\n", + "Each `Axes` has two (or three) `Axis` objects representing the x-axis and y-axis.\n", + "These control the scale of the `Axis`, the tick locators and the tick formatters.\n", + "\n", + "The scale sets the mapping from data values to spacing along the `Axis`.\n", + "This happens in both directions, and gets combined into a transform, which is the way that Matplotlib maps from data coordinates to `Axes` or `Figure`.\n", + "In addition to the linear scale, Matplotlib supplies non-linear scales, such as a log-scale.\n", + "Here we set the scale manually:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fig, axs = plt.subplots(1, 2, figsize=(5, 3), layout='constrained')\n", + "data1 = np.random.randn(100, 1)\n", + "xdata = np.arange(len(data1))\n", + "data = 10**data1\n", + "axs[0].plot(xdata, data)\n", + "\n", + "axs[1].set_yscale('log')\n", + "axs[1].plot(xdata, data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each `Axis` has a tick locator and formatter that choose where along the `Axis` objects to put tick marks. \n", + "Different scales can have different locators and formatters.\n", + "A simple interface to this is `set_xticks`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fig, axs = plt.subplots(2, 1, layout='constrained')\n", + "axs[0].plot(xdata, data1)\n", + "axs[0].set_title('Automatic ticks')\n", + "\n", + "axs[1].plot(xdata, data1)\n", + "axs[1].set_xticks(np.arange(0, 100, 30), ['zero', '30', 'sixty', '90'])\n", + "axs[1].set_yticks([-1.5, 0, 1.5])\n", + "axs[1].set_title('Manual ticks')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's also see how you can change the alignment of ticks:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fig, axs = plt.subplots(figsize=(6, 2))\n", + "axs.plot(xdata, data1)\n", + "axs.set_xticks(np.arange(0, 100, 30), ['zero', 'thirty', 'sixty', 'ninety'])\n", + "axs.set_yticks([-1.5, 0, 1.5])\n", + "axs.tick_params(axis='x', rotation=55)\n", + "fig.align_labels()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Styling and Customizations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Colors\n", + "\n", + "Matplotlib has a very flexible array of colors that can be used with most `Artists`.\n", + "See [Specifying colors](https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def) for a list of allowable color definitions.\n", + "\n", + "Some `Artists` may also take multiple colors, i.e. for a scatter plot, the edge of the markers can be different colors from the interior:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 3))\n", + "data1, data2 = np.random.randn(2, 30)\n", + "\n", + "ax.scatter(data1, data2, facecolor='aquamarine', edgecolor='k')\n", + "fig.set_facecolor('paleturquoise')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Annotations and Legends\n", + "\n", + "We can also annotate points on a plot, often by connecting an arrow pointing to `xy`, to a piece of text at `xytext`, where both `xy` and `xytext` are in data coordinates.\n", + "\n", + "Additionaly, we often want to identify lines or markers with a `Axes`.\n", + "To do that we may use `Legends`, which are quite flexible in layout, placement, and in what `Artists` they can represent." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 3))\n", + "ax.plot([1, 2, 3, 4], [1, 4, 2, 3], label='data1')\n", + "\n", + "ax.annotate('local min', xy=(3, 2), xytext=(3, 1), arrowprops=dict(facecolor='black', shrink=0.03))\n", + "ax.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot Types\n", + "\n", + "Let's have a look at some examples of more plot types.\n", + "\n", + "**Point data:** `scatter(x, y)`:\n", + "\n", + "For a complete reference, check the [documentation](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.scatter.html)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "# create data\n", + "np.random.seed(3)\n", + "x = 4 + np.random.normal(0, 2, 24)\n", + "y = 4 + np.random.normal(0, 2, len(x))\n", + "\n", + "# plot\n", + "fig, ax = plt.subplots()\n", + "ax.scatter(x, y)\n", + "ax.set(xlim=(0, 8), xticks=np.arange(1, 8),\n", + " ylim=(0, 8), yticks=np.arange(1, 8))\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can adjust the size and the color of the points by using `s` and `color` arguments; the shape of the point can be changed using `marker`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "fig, ax = plt.subplots()\n", + "x = np.linspace(0, 2 * np.pi, 100)\n", + "y = np.sin(x)\n", + "ax.scatter(x, y, color='lightblue', marker='*', s=4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `c` and `s `arguments can be used to map color and size to data:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "fig, ax = plt.subplots()\n", + "x = np.linspace(0, 2 * np.pi, 100)\n", + "y = np.sin(x)\n", + "c = np.cos(x)\n", + "ax.scatter(x, y, c=c)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default, Matplotlib [normalizes](https://matplotlib.org/stable/users/explain/colors/colormapnorms.html) the values in `c` between 0 and 1 and uses them to pick the corresponding color from the so-called **colormap**. \n", + "For a list of colormaps, see the documentation [here](https://matplotlib.org/stable/users/explain/colors/colormaps.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Line plot:** `plot(x, y)`\n", + "To generate a line plot, you can use the `plot` method on an `Axes`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "fig, ax = plt.subplots()\n", + "x = np.linspace(0, 2 * np.pi, 100)\n", + "y = np.sin(x)\n", + "ax.plot(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can customize the appearance of the line using various keyword arguments such as `linestyle`, `linewidth`, `marker` and many more.\n", + "For a reference, check the documentation [here](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html).\n", + "Let's see an example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "fig, ax = plt.subplots()\n", + "x = np.linspace(0, 2 * np.pi, 100)\n", + "y = np.sin(x**2)\n", + "ax.plot(x, y, marker=\"*\", color=\"lightblue\", linestyle=\"dashed\", linewidth=0.5, markersize=10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Bar plot:** `bar(x, height)`\n", + "\n", + "You can create a bar plot by using the `bar` method on an `Axes`. \n", + "The `x` argument gives the location of the bar, `height` the height of the bar.\n", + "This can be a numeric vector or a list of string for categorical data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# create data, labels, colors\n", + "import matplotlib.pyplot as plt\n", + "fruits = ['apple', 'blueberry', 'orange']\n", + "counts = [40, 100, 55]\n", + "bar_labels = ['red', 'blue', 'orange']\n", + "bar_colors = ['tab:red', 'tab:blue', 'tab:orange']\n", + "\n", + "# plot\n", + "fig, ax = plt.subplots(figsize=(4, 3))\n", + "ax.bar(fruits, counts, label=bar_labels, color=bar_colors)\n", + "ax.set_ylabel('Fruit supply')\n", + "ax.set_title('Fruit supply by kind and color')\n", + "ax.legend(title='Fruit color')\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Pairwise data:** `stem(x, y)`\n", + "The **stem plot** is similar to a point plot but adds lines from the y=0 line to the point.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "# create data\n", + "x = np.linspace(0.1, 2 * np.pi, 41)\n", + "y = np.exp(np.sin(x))\n", + "\n", + "# plot\n", + "fig, ax = plt.subplots()\n", + "ax.stem(x, y)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Statistical distribution:** `errorbar(x, y, xerr, yerr)`\n", + "\n", + "If you want to display error bars on your plot, you can use `errorbar`.\n", + "For documentation, see [here](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.errorbar.html)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "np.random.seed(3)\n", + "n_x = 100\n", + "n_rel = 10\n", + "x_var = 0.1\n", + "y_var = 0.2\n", + "#Generate data\n", + "x = np.linspace(0, 2 * np.pi, n_x)\n", + "y = np.sin(x**2)\n", + "#Generate errors\n", + "x_err = x_var * np.random.randn(n_x, n_rel)\n", + "y_err = y_var * np.random.randn(n_x, n_rel)\n", + "#Combine data and errors using broadcasting\n", + "x_data = x[:, np.newaxis] + x_err\n", + "y_data = y[:, np.newaxis] + y_err\n", + "#Compute mean and standard deviation\n", + "y_std = np.std(y_data, axis=1)\n", + "y_mean = np.mean(y_data, axis=1)\n", + "x_std = np.std(x_data, axis=1)\n", + "x_mean = np.mean(x_data, axis=1)\n", + "#Plot data\n", + "fig, ax = plt.subplots()\n", + "ax.errorbar(x_mean, y_mean, xerr=x_std, yerr=y_std, fmt='o', color='darkblue',\n", + " ecolor='lightgray', elinewidth=3, capsize=0);\n", + "ax.plot(x_mean, y_mean, color='lightblue', linewidth=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Statistical distribution:** `boxplot(x)`\n", + "\n", + "`boxplot` can be used to plot a boxplot of statistical data.\n", + "For documentation, see [here](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.boxplot.html)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "function_score = [0.8, 0.6, 0.9, 0.8, 0.9]\n", + "classes_score = [0.6, 0.7, 0.8, 0.9, 0.95]\n", + "threads_score = [0.7, 0.8, 0.9, 0.7, 0.98]\n", + "data = np.stack([function_score, classes_score, threads_score], axis=1)\n", + "fig, ax = plt.subplots()\n", + "ax.boxplot(data, labels=['function', 'classes', 'threads'])\n", + "ax.set_ylabel('Score')\n", + "ax.set_title('Score of course modules')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Statistical distribution:** `hist(x)`\n", + "\n", + "Using `hist` we can display the historgram of a (one-dimensional) dataset. \n", + "The argument `bins` can take an integer number to specify the number of bins:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# create data\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "np.random.seed(1)\n", + "x = 4 + np.random.normal(0, 1.5, 200)\n", + "\n", + "# plot\n", + "fig, ax = plt.subplots()\n", + "ax.hist(x, bins=8, linewidth=0.5, edgecolor=\"white\")\n", + "ax.set(xlim=(0, 8), xticks=np.arange(1, 8),\n", + " ylim=(0, 56), yticks=np.linspace(0, 56, 9))\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In alternative you can pass a vector of bin edges if you want to bin data in non-uniform bins.\n", + "Here we are plotting the same dataset but in one case we are choosing logarithmically spaced bins:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# create data\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "np.random.seed(1)\n", + "x = 4 + np.random.exponential(30, 1000)\n", + "bins = np.logspace(1, 2, 20, base=10)\n", + "# plot\n", + "fig, (ax_lin, ax_log) = plt.subplots(2, 1, sharex=True, figsize=(5, 3))\n", + "ax_lin.hist(x, bins=30, linewidth=0.5, edgecolor=\"white\")\n", + "ax_log.hist(x, bins=bins, linewidth=0.5, edgecolor=\"white\")\n", + "ax.set_xlim(0, 100)\n", + "ax_lin.set_xlabel('x')\n", + "ax_lin.set_title('Linear bins')\n", + "ax_log.set_title('Log bins')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Statistical distribution:** `pie(x)`\n", + "\n", + "If you want to display the distribution of **categorical data** you can use the `pie(x)` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# create data\n", + "import matplotlib.pyplot as plt\n", + "x = [1, 2, 3, 4]\n", + "labels = 'Cats', 'Birds', 'Dogs', 'Frogs'\n", + "colors=['rosybrown', 'gray', 'saddlebrown', 'olivedrab']\n", + "\n", + "# plot\n", + "fig, ax = plt.subplots()\n", + "ax.pie(x, labels=labels, colors=colors, autopct='%1.1f%%', radius=2, center=(3, 3), \n", + " wedgeprops={\"linewidth\": 1, \"edgecolor\": \"white\"})\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Image data:** `imshow(x)`\n", + "If you want to display a 2D array as an image, you can use the `imshow` method.\n", + "For more information, see the documentation [here](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "# create data\n", + "x = np.linspace(0, 2 * np.pi, 100)\n", + "y = x\n", + "xx, yy = np.meshgrid(x, y)\n", + "z = np.sin(xx) * np.cos(yy)\n", + "\n", + "# plot\n", + "fig, ax = plt.subplots()\n", + "ax.imshow(z, origin=\"lower\", extent=[0, 2 * np.pi, 0, 2 * np.pi], cmap=\"viridis\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the `origin` argument, we can control where the axis are supposed to start with respect to the figure.\n", + "With `extent` we set the numerical extent of the axes.\n", + "`cmap` is used to set the colormap.\n", + "\n", + "
imshow
doesn't know the extent of\n",
+ " the dataset because it only receives a 2D array as an argument. \n",
+ " The parameter extent
is used to set the extent; make\n",
+ " sure the range you entered corresponds to the real x- and y- range of your data\n",
+ "