Skip to content
Snippets Groups Projects
06_plotting.ipynb 8.73 KiB
Newer Older
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plotting with python\n",
    "\n",
    "The main plotting module in python is `matplotlib`.  There is a lot\n",
    "that can be done with it - see the [webpage](https://matplotlib.org/gallery/index.html)\n",
    "\n",
    "\n",
    "## Contents\n",
    "\n",
    "\n",
    "If you are impatient, feel free to dive straight in to the exercises, and use the\n",
    "other sections as a reference. You might miss out on some neat tricks though.\n",
    "\n",
    "\n",
    "* [Running inside a notebook](#inside-notebook)\n",
    " * [2D plots](#2D-plots)\n",
    " * [Histograms and Bar Plots](#histograms)\n",
    " * [Scatter plots](#scatter-plots)\n",
    " * [Subplots](#subplots)\n",
    " * [Displaying Images](#displaying-images)\n",
    " * [3D plots](#3D-plots)\n",
    "* [Running in a standalone script](#plotting-in-scripts)\n",
    "* [Exercise](#exercise)\n",
    "\n",
    "\n",
    "<a class=\"anchor\" id=\"inside-notebook\"></a>\n",
    "## Inside a notebook\n",
    "\n",
    "Inside a jupyter notebook you get access to this in a slightly\n",
    "different way, compared to other modules:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This only needs to be done once in a notebook, like for standard imports.\n",
    "\n",
    "> There are also other alternatives, including interactive versions - see the practical on Jupyter notebooks for more information about this.\n",
    "\n",
    "\n",
    "The library works very similarly to plotting in matlab.  Let's start\n",
    "with some simple examples.\n",
    "\n",
    "<a class=\"anchor\" id=\"2D-plots\"></a>\n",
    "### 2D plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "plt.style.use('bmh')\n",
    "\n",
    "x = np.linspace(-np.pi, np.pi, 256)\n",
    "cosx, sinx = np.cos(x), np.sin(x)\n",
    "\n",
    "plt.plot(x, cosx)\n",
    "plt.plot(x, sinx, color='red', linewidth=4, linestyle='-.')\n",
    "plt.plot(x, sinx**2)\n",
    "plt.xlim(-np.pi, np.pi)\n",
    "plt.title('Our first plots')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Note that the `plt.style.use('bmh')` command is not necessary, but it\n",
    "> does make nicer looking plots in general.  You can use `ggplot`\n",
    "> instead of `bmh` if you want something resembling plots made by R.\n",
    "> For a list of options run: `print(plt.style.available)`\n",
    "\n",
    "<a class=\"anchor\" id=\"histograms\"></a>\n",
    "### Histograms and bar charts\n",
    "\n",
    "For a simple histogram you can do this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "source": [
    "r = np.random.rand(1000)\n",
    "n,bins,_ = plt.hist((r-0.5)**2, bins=30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "where it also returns the number of elements in each bin, as `n`, and\n",
    "the bin centres, as `bins`.\n",
    "\n",
    "> The `_` in the third part on the left\n",
    "> hand side is a shorthand for just throwing away the corresponding part\n",
    "> of the return structure.\n",
    "\n",
    "\n",
    "There is also a call for doing bar plots:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "source": [
    "samp1 = r[0:10]\n",
    "samp2 = r[10:20]\n",
    "bwidth = 0.3\n",
    "xcoord = np.arange(10)\n",
    "plt.bar(xcoord-bwidth, samp1, width=bwidth, color='red', label='Sample 1')\n",
    "plt.bar(xcoord, samp2, width=bwidth, color='blue', label='Sample 2')\n",
    "plt.legend(loc='upper left')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a class=\"anchor\" id=\"scatter-plots\"></a>\n",
    "### Scatter plots\n",
    "\n",
    "It would be possible to use `plot()` to create a scatter plot, but\n",
    "there is also an alternative: `scatter()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "source": [
    "fig, ax = plt.subplots()\n",
Mark Jenkinson's avatar
Mark Jenkinson committed
    "# setup some sizes for each point (arbitrarily example here)\n",
    "ssize = 100*abs(samp1-samp2) + 10 \n",
    "ax.scatter(samp1, samp2, s=ssize, alpha=0.5)\n",
Mark Jenkinson's avatar
Mark Jenkinson committed
    "# now add the y=x line\n",
    "allsamps = np.hstack((samp1,samp2))\n",
    "ax.plot([min(allsamps),max(allsamps)],[min(allsamps),max(allsamps)], color='red', linestyle='--')\n",
    "plt.xlim(min(allsamps),max(allsamps))\n",
    "plt.ylim(min(allsamps),max(allsamps))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Note that in this case we use the first line return to get a handle to\n",
    "> the axis, `ax`, and the figure ,`fig`. The axis can be used instead of\n",
    "> `plt` in most cases, although the `xlim()` and `ylim()` calls can only\n",
    "> be done through `plt`.\n",
    "\n",
    "\n",
    "<a class=\"anchor\" id=\"subplots\"></a>\n",
    "### Subplots\n",
    "\n",
    "These are very similar to matlab:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "source": [
    "plt.subplot(2, 1, 1)\n",
    "plt.plot(x,cosx, '.-')\n",
    "plt.xlim(-np.pi, np.pi)\n",
    "plt.ylabel('Full sampling')\n",
    "plt.subplot(2, 1, 2)\n",
    "plt.plot(x[::30], cosx[::30], '.-')\n",
    "plt.xlim(-np.pi, np.pi)\n",
    "plt.ylabel('Subsampled')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a class=\"anchor\" id=\"displaying-images\"></a>\n",
    "### Displaying images\n",
    "\n",
    "The main command for displaying images is `imshow()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "source": [
    "import nibabel as nib\n",
    "import os.path as op\n",
    "nim = nib.load(op.expandvars('${FSLDIR}/data/standard/MNI152_T1_1mm.nii.gz'), mmap=False)\n",
    "imdat = nim.get_data().astype(float)\n",
    "plt.imshow(imdat[:,:,70], cmap=plt.cm.gray)\n",
    "plt.colorbar()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a class=\"anchor\" id=\"3D-plots\"></a>\n",
    "### 3D plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "source": [
    "# Taken from https://matplotlib.org/gallery/mplot3d/wire3d.html#sphx-glr-gallery-mplot3d-wire3d-py\n",
    "\n",
    "from mpl_toolkits.mplot3d import axes3d\n",
    "\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111, projection='3d')\n",
    "\n",
    "# Grab some test data.\n",
    "X, Y, Z = axes3d.get_test_data(0.05)\n",
    "\n",
    "# Plot a basic wireframe.\n",
    "ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Surface renderings are many other plots are possible - see 3D examples on\n",
    "the [matplotlib webpage](https://matplotlib.org/gallery/index.html#mplot3d-examples-index)\n",
    "\n",
    "---\n",
    "\n",
    "<a class=\"anchor\" id=\"plotting-in-scripts\"></a>\n",
    "## Plotting from standalone scripts\n",
    "\n",
    "When running from a standalone script, the same `matplotlib` import is required,\n",
    "but the line `%matplotlib <backend>` should *not* be used.\n",
    "\n",
    "In a script it is also necessary to  _finish_ with `plt.show()` as\n",
    "otherwise nothing is actually displayed.  For example, the above\n",
    "examples would setup a plot but the actual graphic would only appear\n",
    "after the `plt.show()` command was executed.  Furthermore, control is\n",
    "not returned to the script immediately as the plot is interactive by default.\n",
    "\n",
    "---\n",
    "\n",
    "<a class=\"anchor\" id=\"exercise\"></a>\n",
    "## Exercise\n",
    "\n",
    "Find a different type of plot (e.g., boxplot, violin plot, quiver\n",
    "plot, pie chart, etc.), look up\n",
    "the documentation and then write _your own code that calls this_ to create a plot\n",
    "from some data that you create yourself (i.e., don't just blindly copy example code from the docs)."
Mark Jenkinson's avatar
Mark Jenkinson committed
 "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.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}