From f47431a24916c347356586de70d10e9edcd6c9f8 Mon Sep 17 00:00:00 2001 From: "Patrick L.S. Connor" <connorpa@mail.desy.de> Date: Fri, 9 Apr 2021 17:34:00 +0200 Subject: [PATCH] removing tmp directory --- .../IPython_and_Jupyter-checkpoint.ipynb | 957 ------ .../Intro_Numpy-checkpoint.ipynb | 2767 ----------------- .../Matplotlib_Cheatsheet-checkpoint.ipynb | 1971 ------------ 3 files changed, 5695 deletions(-) delete mode 100644 .ipynb_checkpoints/IPython_and_Jupyter-checkpoint.ipynb delete mode 100644 .ipynb_checkpoints/Intro_Numpy-checkpoint.ipynb delete mode 100644 .ipynb_checkpoints/Matplotlib_Cheatsheet-checkpoint.ipynb diff --git a/.ipynb_checkpoints/IPython_and_Jupyter-checkpoint.ipynb b/.ipynb_checkpoints/IPython_and_Jupyter-checkpoint.ipynb deleted file mode 100644 index 2a3ecbf..0000000 --- a/.ipynb_checkpoints/IPython_and_Jupyter-checkpoint.ipynb +++ /dev/null @@ -1,957 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# IPython\n", - "\n", - "**IPython** (Interactive Python) is an enhanced Python shell which provides a more robust and productive development environment for users. There are several key features that set it apart from the standard Python shell.\n", - "Jupyter is the web variant. It provides an interactive shell within a browser.\n", - "### History\n", - "\n", - "In IPython, all your inputs and outputs are saved. There are two variables named `In` and `Out` which are assigned as you work with your results. All outputs are saved automatically to variables of the form `_N`, where `N` is the prompt number, and inputs to `_iN`. This allows you to recover quickly the result of a prior computation by referring to its number even if you forgot to store it as a variable. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.sin(4)**2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "_1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "_i1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "_1 / 4." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Output is asynchronous\n", - "\n", - "All output is displayed asynchronously as it is generated in the Kernel. If you execute the next cell, you will see the output one piece at a time, not all at the end." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import time, sys\n", - "for i in range(8):\n", - " print(i)\n", - " time.sleep(0.5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Introspection\n", - "\n", - "If you want details regarding the properties and functionality of any Python objects currently loaded into IPython, you can use the `?` to reveal any details that are available:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "some_dict = {}\n", - "some_dict?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If available, additional detail is provided with two question marks, including the source code of the object itself." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy.linalg import svd\n", - "svd??" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This syntax can also be used to search namespaces with wildcards (\\*)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "import pylab as plt\n", - "plt.*plot*?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Tab completion\n", - "\n", - "Because IPython allows for introspection, it is able to afford the user the ability to tab-complete commands that have been partially typed. This is done by pressing the `<tab>` key at any point during the process of typing a command.\n", - "\n", - "**Place your cursor after the partially-completed command below and press tab:**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.ar # hit TAB behind np.ar|" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.hist() # hit tab within np.hist(|)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This can even be used to help with specifying arguments to functions, which can sometimes be difficult to remember:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### System commands\n", - "\n", - "In IPython, you can type `ls` to see your files or `cd` to change directories, just like you would at a regular system prompt:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ls " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Virtually any system command can be accessed by prepending `!`, which passes any subsequent command directly to the OS." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "# !locate sklearn | grep xgboost" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can even use Python variables in commands sent to the OS:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fil = 'tensor'\n", - "#! echo $fil\n", - "!ls {fil}*.ipynb" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The output of a system command using the exclamation point syntax can be assigned to a Python variable." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data_files = !ls " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!ls" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data_files" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Qt Console\n", - "\n", - "If you type at the system prompt:\n", - "\n", - " $ ipython qtconsole\n", - "\n", - "instead of opening in a terminal, IPython will start a graphical console that at first sight appears just like a terminal, but which is in fact much more capable than a text-only terminal. This is a specialized terminal designed for interactive scientific work, and it supports full multi-line editing with color highlighting and graphical calltips for functions, it can keep multiple IPython sessions open simultaneously in tabs, and when scripts run it can display the figures inline directly in the work area.\n", - "\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Jupyter Notebook\n", - "\n", - "Over time, the IPython project grew to include several components, including:\n", - "\n", - "* an interactive shell\n", - "* a REPL protocol\n", - "* a notebook document fromat\n", - "* a notebook document conversion tool\n", - "* a web-based notebook authoring tool\n", - "* tools for building interactive UI (widgets)\n", - "* interactive parallel Python\n", - "\n", - "As each component has evolved, several had grown to the point that they warrented projects of their own. For example, pieces like the notebook and protocol are not even specific to Python. As the result, the IPython team created Project Jupyter, which is the new home of language-agnostic projects that began as part of IPython, such as the notebook in which you are reading this text.\n", - "\n", - "The HTML notebook that is part of the Jupyter project supports **interactive data visualization** and easy high-performance **parallel computing**.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "#plt.style.use('fivethirtyeight')\n", - "#DK\n", - "plt.style.use('dark_background')\n", - "\n", - "def f(x):\n", - " return (x-3)*(x-5)*(x-7)+85\n", - "\n", - "import numpy as np\n", - "x = np.linspace(0, 10, 200)\n", - "y = f(x)\n", - "plt.plot(x,y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The notebook lets you document your workflow using either HTML or Markdown.\n", - "\n", - "The Jupyter Notebook consists of two related components:\n", - "\n", - "* A JSON based Notebook document format for recording and distributing Python code and rich text.\n", - "* A web-based user interface for authoring and running notebook documents.\n", - "\n", - "The Notebook can be used by starting the Notebook server with the command:\n", - "\n", - " $ jupyter notebook\n", - " \n", - "This initiates an **iPython engine**, which is a Python instance that takes Python commands over a network connection.\n", - "\n", - "The **IPython controller** provides an interface for working with a set of engines, to which one or more **iPython clients** can connect.\n", - "\n", - "The Notebook gives you everything that a browser gives you. For example, you can embed images, videos, or entire websites." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from IPython.display import HTML\n", - "HTML(\"<iframe src=http://pytorch.org width=700 height=350></iframe>\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "outputs": [], - "source": [ - "from IPython.display import YouTubeVideo\n", - "YouTubeVideo(\"rl5DaFbLc60\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Remote Code\n", - "\n", - "Use `%load` to add remote code\n", - "\n", - "This becomes the following cell" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# %load http://matplotlib.org/mpl_examples/shapes_and_collections/scatter_demo.py\n", - "\"\"\"\n", - "Simple demo of a scatter plot.\n", - "\"\"\"\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "\n", - "N = 50\n", - "x = np.random.rand(N)\n", - "y = np.random.rand(N)\n", - "colors = np.random.rand(N)\n", - "area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radii\n", - "\n", - "plt.scatter(x, y, s=area, c=colors, alpha=0.5)\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# %load http://matplotlib.org/mpl_examples/shapes_and_collections/scatter_demo.py\n", - "\"\"\"\n", - "Simple demo of a scatter plot.\n", - "\"\"\"\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "\n", - "N = 50\n", - "x = np.random.rand(N)\n", - "y = np.random.rand(N)\n", - "colors = np.random.rand(N)\n", - "area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radii\n", - "\n", - "plt.scatter(x, y, s=area, c=colors, alpha=0.5)\n", - "plt.show()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Mathjax Support\n", - "\n", - "Mathjax ia a javascript implementation $\\alpha$ of LaTeX that allows equations to be embedded into HTML. For example, this markup:\n", - "\n", - " \"\"\"$$ \\int_{a}^{b} f(x)\\, dx \\approx \\frac{1}{2} \\sum_{k=1}^{N} \\left( x_{k} - x_{k-1} \\right) \\left( f(x_{k}) + f(x_{k-1}) \\right). $$\"\"\"\n", - " \n", - "becomes this:\n", - "\n", - "$$\n", - "\\int_{a}^{b} f(x)\\, dx \\approx \\frac{1}{2} \\sum_{k=1}^{N} \\left( x_{k} - x_{k-1} \\right) \\left( f(x_{k}) + f(x_{k-1}) \\right).\n", - "$$" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## SymPy Support\n", - "\n", - "SymPy is a Python library for symbolic mathematics. It supports:\n", - "\n", - "* polynomials\n", - "* calculus\n", - "* solving equations\n", - "* discrete math\n", - "* matrices" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from sympy import *\n", - "init_printing()\n", - "x, y = symbols(\"x y\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "eq = ((x+y)**2 * (x+1))\n", - "eq" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "expand(eq)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(1/cos(x)).series(x, 0, 6)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "limit((sin(x)-x)/x**3, x, 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "diff(cos(x**2)**2 / (1+x), x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Magic functions\n", - "\n", - "IPython has a set of predefined ‘magic functions’ that you can call with a command line style syntax. These include:\n", - "\n", - "* `%run`\n", - "* `%edit`\n", - "* `%debug`\n", - "* `%timeit`\n", - "* `%paste`\n", - "* `%load_ext`\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Timing the execution of code; the `timeit` magic exists both in line and cell form:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%timeit np.linalg.eigvals(np.random.rand(100,100))\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%%timeit a = np.random.rand(100, 100)\n", - "np.linalg.eigvals(a)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%%timeit\n", - "A = np.random.rand(100,100)\n", - "w = np.linalg.eig(A)\n", - "w" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "IPython also creates aliases for a few common interpreters, such as bash, ruby, perl, etc.\n", - "\n", - "These are all equivalent to `%%script <name>`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.style.use('dark_background')\n", - "\n", - "\n", - "n=200\n", - "max=n-1\n", - "#max=n\n", - "xx = np.linspace(0,n-1,n)[:max] # consider x values 0, 1, .., 100\n", - "\n", - "A_uni = np.random.rand(n,n)\n", - "A_norm = np.random.normal(loc=0,scale=1/3.14,size=(n,n))\n", - "A_lap = np.random.laplace(loc=0,scale=.707/3.14,size=(n,n))\n", - "A_exp = np.random.exponential(scale=1,size=(n,n))\n", - "#A_lap=np.sin(A_norm)\n", - "#A_exp=np.cos(A_norm)\n", - "w_uni = np.linalg.eig(A_uni)\n", - "w_norm = np.linalg.eig(A_norm)\n", - "w_lap = np.linalg.eig(A_lap)\n", - "w_exp = np.linalg.eig(A_exp)\n", - "ev_uni = np.array(np.sort(np.linalg.eigvals(A_uni)))\n", - "ev_norm = np.array(np.sort(np.linalg.eigvals(A_norm)))\n", - "ev_lap = np.array(np.sort(np.linalg.eigvals(A_lap)))\n", - "ev_exp = np.array(np.sort(np.linalg.eigvals(A_exp)))\n", - "\n", - "plt.plot(xx, ev_norm[:max],label=\"ev. normsl\")\n", - "plt.plot(xx, ev_uni[:max],label=\"ev. uniform \")\n", - "plt.plot(xx, ev_lap[:max],label=\"ev. laplace \")\n", - "plt.plot(xx, ev_exp[:max],label=\"ev. exponential \")\n", - "plt.legend()\n", - "plt.show() \n", - "print 'uni ',ev_uni[0],ev_uni[n-1]\n", - "print 'normal ',ev_norm[0],ev_norm[n-1]\n", - "print 'exp ',ev_exp[0],ev_exp[n-1]\n", - "print 'laplace ',ev_lap[0],ev_lap[n-1]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%timeit EigenV = np.array(np.sort(np.linalg.eigvals(np.random.exponential(scale=1,size=(1000,1000)))))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%%ruby\n", - "puts \"Hello from Ruby #{RUBY_VERSION}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%%bash\n", - "echo \"hello from $BASH\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "IPython has an `rmagic` extension that contains a some magic functions for working with R via rpy2. This extension can be loaded using the `%load_ext` magic as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext rpy2.ipython" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If the above generates an error, it is likely that you do not have the `rpy2` module installed. You can install this now via:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#!pip install rpy2\n", - "#\n", - "#!conda install rpy2\n", - "# by hand" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# x,y = np.arange(10), np.random.normal(size=10)\n", - "# %R print(lm(rnorm(10)~rnorm(10)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# %%R -i x,y -o XYcoef\n", - "# lm.fit <- lm(y~x)\n", - "# par(mfrow=c(2,2))\n", - "# print(summary(lm.fit))\n", - "# plot(lm.fit)\n", - "# XYcoef <- coef(lm.fit)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# XYcoef" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### LaTeX\n", - "\n", - "In addition to MathJax support, you may declare a LaTeX cell using the `%latex` magic:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%%latex\n", - "\\begin{align}\n", - "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\\n", - "\\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\n", - "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\n", - "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0\n", - "\\end{align}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Javscript\n", - "\n", - "Jupyter also enables objects to declare a JavaScript representation. At first, this may seem odd as output is inherently visual and JavaScript is a programming language. However, this opens the door for rich output that leverages the full power of JavaScript and associated libraries such as D3 for output." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%%javascript\n", - "\n", - "alert(\"Hello world!\");" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exporting and Converting Notebooks\n", - "\n", - "In Jupyter, one can convert an `.ipynb` notebook document file into various static formats via the `nbconvert` tool. Currently, nbconvert is a command line tool, run as a script using Jupyter." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#!jupyter nbconvert --to html IPython_and_Jupyter.ipynb" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Currently, `nbconvert` supports HTML (default), LaTeX, Markdown, reStructuredText, Python and HTML5 slides for presentations. Some types can be post-processed, such as LaTeX to PDF (this requires [Pandoc](http://johnmacfarlane.net/pandoc/) to be installed, however)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reproducible Research\n", - "\n", - "> reproducing conclusions from a single experiment based on the measurements from that experiment\n", - "\n", - "The most basic form of reproducibility is a complete description of the data and associated analyses (including code!) so the results can be *exactly* reproduced by others.\n", - "\n", - "Reproducing calculations can be onerous, even with one's own work!\n", - "\n", - "Scientific data are becoming larger and more complex, making simple descriptions inadequate for reproducibility. As a result, most modern research is irreproducible without tremendous effort.\n", - "\n", - "*** Reproducible research is not yet part of the culture of science in general, or scientific computing in particular. ***" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Scientific Computing Workflow\n", - "\n", - "There are a number of steps to scientific endeavors that involve computing:\n", - "\n", - "\n", - "\n", - "\n", - "Many of the standard tools impose barriers between one or more of these steps. This can make it difficult to iterate, reproduce work.\n", - "\n", - "The Jupyter notebook eliminates or reduces these barriers to reproducibility." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Parallel iPython\n", - "\n", - "At a high level, there are three basic components to parallel IPython:\n", - "\n", - "* Engine(s) - the remote or distributed processes where your code runs.\n", - "* Client - your interface to running code on Engines.\n", - "* Controller - the collection of processes that coordinate Engines and Clients.\n", - "\n", - "These components live in the `IPython.parallel` package, which has been rolled out into its own model that requires installation.\n", - "\n", - "To install ipyparallel:\n", - "\n", - "```bash\n", - "pip install ipyparallel\n", - "```\n", - "\n", - "or via `conda`:\n", - "\n", - "```bash\n", - "conda install ipyparallel\n", - "```\n", - "\n", - "To install the IPython Clusters tab in Jupyter Notebook, add this to your `jupyter_notebook_config.py`:\n", - "\n", - "```python\n", - "c.NotebookApp.server_extensions.append('ipyparallel.nbextension')\n", - "```\n", - "\n", - "This file resides in your `~/.jupyter` subdirectory of your home directory, and should be created if it does not already exist." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Before running the next cell, make sure you have first started your cluster, you can use the [clusters tab in the dashboard](/#tab2) to do so. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#from ipyparallel import Client\n", - "#client = Client()\n", - "#dv = client.direct_view()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#len(dv)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#def where_am_i():\n", - "# import os\n", - "# import socket\n", - "# \n", - "# return \"In process with pid {0} on host: '{1}'\".format(\n", - "# os.getpid(), socket.gethostname())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#where_am_i_direct_results = dv.apply(where_am_i)\n", - "#where_am_i_direct_results.get()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Links and References" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[IPython Notebook Viewer](http://nbviewer.ipython.org) Displays static HTML versions of notebooks, and includes a gallery of notebook examples." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[NotebookCloud](https://notebookcloud.appspot.com) A service that allows you to launch and control IPython Notebook servers on Amazon EC2 from your browser." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[A Reference-Free Algorithm for Computational Normalization of Shotgun Sequencing Data](http://ged.msu.edu/papers/2012-diginorm/) A landmark example of reproducible research in genomics: Git repo, iPython notebook, data and scripts.\n", - "\n", - "Jacques Ravel and K Eric Wommack. 2014. [All Hail Reproducibility in Microbiome Research](http://www.microbiomejournal.com/content/pdf/2049-2618-2-8.pdf). Microbiome, 2:8.\n", - "\n", - "Benjamin Ragan-Kelley et al.. 2013. [Collaborative cloud-enabled tools allow rapid, reproducible biological insights](http://www.nature.com/ismej/journal/v7/n3/full/ismej2012123a.html). The ISME Journal, 7, 461–464; doi:10.1038/ismej.2012.123;" - ] - } - ], - "metadata": { - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "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.8.5" - }, - "nav_menu": {}, - "toc": { - "navigate_menu": true, - "number_sections": false, - "sideBar": true, - "threshold": 6, - "toc_cell": false, - "toc_section_display": "block", - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/.ipynb_checkpoints/Intro_Numpy-checkpoint.ipynb b/.ipynb_checkpoints/Intro_Numpy-checkpoint.ipynb deleted file mode 100644 index 8d5efac..0000000 --- a/.ipynb_checkpoints/Intro_Numpy-checkpoint.ipynb +++ /dev/null @@ -1,2767 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Numpy - multidimensional data arrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Inspired by J.R. Johansson (robert@riken.jp) http://jrjohansson.github.io/numericalpython.html" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# we need this later for plotting\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Introduction" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `numpy` package (module) is used in almost all numerical computation using Python. It is a package that provide high-performance vector, matrix and higher-dimensional data structures for Python. It is implemented in C and Fortran so when calculations are vectorized (formulated with vectors and matrices), performance is very good. \n", - "\n", - "To use `numpy` we need to import the module:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the `numpy` package the terminology used for vectors, matrices and higher-dimensional data sets is *array*. \n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating `numpy` arrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are a number of ways to initialize new numpy arrays, for example from\n", - "\n", - "* a Python list or tuples\n", - "* using functions that are dedicated to generating numpy arrays, such as `arange`, `linspace`, etc.\n", - "* reading data from files" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From lists" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, to create new vector and matrix arrays from Python lists we can use the `numpy.array` function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# a vector: the argument to the array function is a Python list\n", - "v = np.array([1,2,3,4])\n", - "\n", - "v" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# a matrix: the argument to the array function is a nested Python list\n", - "M = np.array([[1, 2], [3, 4]])\n", - "\n", - "M" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `v` and `M` objects are both of the type `ndarray` that the `numpy` module provides." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "type(v), type(M)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The difference between the `v` and `M` arrays is only their shapes. We can get information about the shape of an array by using the `ndarray.shape` property." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v.shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The number of elements in the array is available through the `ndarray.size` property:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M.size" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Equivalently, we could use the function `numpy.shape` and `numpy.size`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.shape(M)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.size(M)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So far the `numpy.ndarray` looks awefully much like a Python list (or nested list). Why not simply use Python lists for computations instead of creating a new array type? \n", - "\n", - "There are several reasons:\n", - "\n", - "* Python lists are very general. They can contain any kind of object. They are dynamically typed. They do not support mathematical functions such as matrix and dot multiplications, etc. Implementating such functions for Python lists would not be very efficient because of the dynamic typing.\n", - "* Numpy arrays are **statically typed** and **homogeneous**. The type of the elements is determined when array is created.\n", - "* Numpy arrays are memory efficient.\n", - "* Because of the static typing, fast implementation of mathematical functions such as multiplication and addition of `numpy` arrays can be implemented in a compiled language (C and Fortran is used).\n", - "\n", - "Using the `dtype` (data type) property of an `ndarray`, we can see what type the data of an array has:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M.dtype" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We get an error if we try to assign a value of the wrong type to an element in a numpy array:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M[0,0] = \"hello\" # error on purpose" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we want, we can explicitly define the type of the array data when we create it, using the `dtype` keyword argument: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M = np.array([[1, 2], [3, 4]], dtype=complex)\n", - "\n", - "M" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Common type that can be used with `dtype` are: `int`, `float`, `complex`, `bool`, `object`, etc.\n", - "\n", - "We can also explicitly define the bit size of the data types, for example: `int64`, `int16`, `float128`, `complex128`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Using array-generating functions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For larger arrays it is inpractical to initialize the data manually, using explicit python lists. Instead we can use one of the many functions in `numpy` that generates arrays of different forms. Some of the more common are:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### arange" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# create a range\n", - "\n", - "x = np.arange(0, 10, 1) # arguments: start, stop, step\n", - "\n", - "x" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.arange(-1, 1, 0.1)\n", - "\n", - "x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### linspace and logspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# using linspace, both end points ARE included\n", - "np.linspace(0, 10, 25)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.logspace(0, 10, 10, base=np.e)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### mgrid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x, y = np.mgrid[0:5, 0:5] # similar to meshgrid in MATLAB" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### random data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# uniform random numbers in [0,1]\n", - "np.random.rand(5,5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# standard normal distributed random numbers\n", - "np.random.randn(5,5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### diag" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# a diagonal matrix\n", - "np.diag([1,2,3])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# diagonal with offset from the main diagonal\n", - "np.diag([1,2,3], k=1) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### zeros and ones" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.zeros((3,3))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.ones((3,3))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## File I/O" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Comma-separated values (CSV)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A very common file format for data files are the comma-separated values (CSV), or related format such as TSV (tab-separated values). To read data from such file into Numpy arrays we can use the `numpy.genfromtxt` function. For example, " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!head stockholm_td_adj.dat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = np.genfromtxt('stockholm_td_adj.dat')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data.shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig, ax = plt.subplots(figsize=(14,4))\n", - "ax.plot(data[:,0]+data[:,1]/12.0+data[:,2]/365, data[:,5])\n", - "ax.axis('tight')\n", - "ax.set_title('tempeatures in Stockholm')\n", - "ax.set_xlabel('year')\n", - "ax.set_ylabel('temperature (C)');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using `numpy.savetxt` we can store a Numpy array to a file in CSV format:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M = np.random.rand(3,3)\n", - "\n", - "M" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.savetxt(\"random-matrix.csv\", M)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!cat random-matrix.csv" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.savetxt(\"random-matrix.csv\", M, fmt='%.5f') # fmt specifies the format\n", - "\n", - "!cat random-matrix.csv" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Numpy's native file format" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Useful when storing and reading back numpy array data. Use the functions `numpy.save` and `numpy.load`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.save(\"random-matrix.npy\", M)\n", - "\n", - "!file random-matrix.npy" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.load(\"random-matrix.npy\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## More properties of the numpy arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M.itemsize # bytes per element" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M.nbytes # number of bytes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M.ndim # number of dimensions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Manipulating arrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Indexing" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can index elements in an array using the square bracket and indices:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# v is a vector, and has only one dimension, taking one index\n", - "v[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# M is a matrix, or a 2 dimensional array, taking two indices \n", - "M[1,1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we omit an index of a multidimensional array it returns the whole row (or, in general, a N-1 dimensional array) " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M[1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The same thing can be achieved with using `:` instead of an index: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M[1,:] # row 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M[:,1] # column 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can assign new values to elements in an array using indexing:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M[0,0] = 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# also works for rows and columns\n", - "M[1,:] = 0\n", - "M[:,2] = -1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Index slicing" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Index slicing is the technical name for the syntax `M[lower:upper:step]` to extract part of an array:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = np.array([1,2,3,4,5])\n", - "A" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[1:3]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Array slices are *mutable*: if they are assigned a new value the original array from which the slice was extracted is modified:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[1:3] = [-2,-3]\n", - "\n", - "A" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can omit any of the three parameters in `M[lower:upper:step]`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[::] # lower, upper, step all take the default values" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[::2] # step is 2, lower and upper defaults to the beginning and end of the array" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[:3] # first three elements" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[3:] # elements from index 3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Negative indices counts from the end of the array (positive index from the begining):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = np.array([1,2,3,4,5])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[-1] # the last element in the array" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A[-3:] # the last three elements" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Index slicing works exactly the same way for multidimensional arrays:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = np.array([[n+m*10 for n in range(5)] for m in range(5)])\n", - "\n", - "A" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# a block from the original array\n", - "A[1:4,1:4] # do not confuse this with A[1:4][1:4]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# strides\n", - "A[::2, ::2]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Fancy indexing" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Fancy indexing is the name for when an array or list is used in-place of an index: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row_indices = [1, 2, 3]\n", - "# this picks row 1, 2 and 3\n", - "A[row_indices]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "col_indices = [1, 2, -1] # remember, index -1 means the last element\n", - "A[row_indices,col_indices] # this picks A[1,1],A[2,2],A[3,-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also index masks: If the index mask is an Numpy array of with data type `bool`, then an element is selected (True) or not (False) depending on the value of the index mask at the position each element: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "B = np.arange(5)\n", - "B" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row_mask = np.array([True, False, True, False, False])\n", - "B[row_mask]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# same thing\n", - "row_mask = np.array([1,0,1,0,0], dtype=bool) # bool type is essential here\n", - "B[row_mask]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This feature is very useful to conditionally select elements from an array, using for example comparison operators:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.arange(0, 10, 0.5)\n", - "x" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = (5 < x) * (x < 7.5)\n", - "\n", - "mask" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[mask]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Functions for extracting data from arrays and creating arrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### where" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The index mask can be converted to position index using the `where` function" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "indices = np.where(mask)\n", - "\n", - "indices" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[indices] # this indexing is equivalent to the fancy indexing x[mask]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### diag" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With the diag function we can also extract the diagonal and subdiagonals of an array:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.diag(A)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.diag(A, -1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### take" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `take` function is similar to fancy indexing described above:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v2 = np.arange(-3,3)\n", - "v2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row_indices = [1, 3, 5]\n", - "v2[row_indices] # fancy indexing" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v2.take(row_indices)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But `take` also works on lists and other objects:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#e.g. from a python list\n", - "np.take([-3, -2, -1, 0, 1, 2], row_indices) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### choose" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Constructs and array by picking elements form several arrays:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "which = [1, 0, 1, 0]\n", - "choices = [[-2,-2,-2,-2], [5,5,5,5]]\n", - "\n", - "np.choose(which, choices)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Linear algebra" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Vectorizing code is the key to writing efficient numerical calculation with Python/Numpy. That means that as much as possible of a program should be formulated in terms of matrix and vector operations, like matrix-matrix multiplication." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Scalar-array operations" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can use the usual arithmetic operators to multiply, add, subtract, and divide arrays with scalar numbers." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v1 = np.arange(0, 5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v1 * 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v1 + 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A * 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A + 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Element-wise array-array operations" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When we add, subtract, multiply and divide arrays with each other, the default behaviour is **element-wise** operations:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A * A # element-wise multiplication" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v1 * v1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Broadcasting\n", - "(see https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)\n", - "\n", - "If we multiply arrays with compatible shapes, we get an element-wise multiplication of each row:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A.shape, v1.shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A * v1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Matrix algebra" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What about matrix mutiplication? There are two ways. We can either use the `dot` function, which applies a matrix-matrix, matrix-vector, or inner vector multiplication to its two arguments: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.dot(A, A)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.dot(A, v1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.dot(v1, v1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Alternatively, we can cast the array objects to the type `matrix`. This changes the behavior of the standard arithmetic operators `+, -, *` to use matrix algebra." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M = np.matrix(A)\n", - "v = np.matrix(v1).T # make it a column vector" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M * M" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M * v" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# inner product\n", - "v.T * v" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# with matrix objects, standard matrix algebra applies\n", - "v + M*v" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we try to add, subtract or multiply objects with incomplatible shapes we get an error:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = np.matrix([1,2,3,4,5,6]).T" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.shape(M), np.shape(v)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M * v" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "See also the related functions: `inner`, `outer`, `cross`, `kron`, `tensordot`. Try for example `help(kron)`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Array/Matrix transformations" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Above we have used the `.T` to transpose the matrix object `v`. We could also have used the `transpose` function to accomplish the same thing. \n", - "\n", - "Other mathematical functions that transforms matrix objects are:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "C = np.matrix([[1j, 2j], [3j, 4j]])\n", - "C" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.conjugate(C)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Hermitian conjugate: transpose + conjugate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "C.H" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can extract the real and imaginary parts of complex-valued arrays using `real` and `imag`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.real(C) # same as: C.real" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.imag(C) # same as: C.imag" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or the complex argument and absolute value" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.angle(C+1) # heads up MATLAB Users, angle is used instead of arg" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.abs(C)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are also member to access the real or imaginary parts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "C.real" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "C.imag" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Matrix computations" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Inverse" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.linalg.inv(C) # equivalent to C.I " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "C.I * C" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Determinant" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.linalg.det(C)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.linalg.det(C.I)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data processing" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Often it is useful to store datasets in Numpy arrays. Numpy provides a number of functions to calculate statistics of datasets in arrays. \n", - "\n", - "For example, let's calculate some properties data from the Stockholm temperature dataset used above." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# reminder, the tempeature dataset is stored in the data variable:\n", - "np.shape(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### mean" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# the temperature data is in column 3\n", - "np.mean(data[:,3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The daily mean temperature in Stockholm over the last 200 year so has been about 6.2 C." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### standard deviations and variance" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(data[:,3]), np.var(data[:,3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### min and max" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# lowest daily average temperature\n", - "data[:,3].min()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# highest daily average temperature\n", - "data[:,3].max()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### sum, prod, and trace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "d = np.arange(0, 10)\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# sum up all elements\n", - "np.sum(d)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# product of all elements\n", - "np.prod(d+1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# cummulative sum\n", - "np.cumsum(d)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# cummulative product\n", - "np.cumprod(d+1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# same as: diag(A).sum()\n", - "np.trace(A)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Computations on subsets of arrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can compute with subsets of the data in an array using indexing, fancy indexing, and the other methods of extracting data from an array (described above).\n", - "\n", - "For example, let's go back to the temperature dataset:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!head -n 3 stockholm_td_adj.dat" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The dataformat is: year, month, day, daily average temperature, low, high, location.\n", - "\n", - "If we are interested in the average temperature only in a particular month, say February, then we can create a index mask and use the select out only the data for that month using:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data.shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.unique(data[:,1]) # the month column takes values from 1 to 12" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask_feb = data[:,1] == 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# the temperature data is in column 3\n", - "np.mean(data[mask_feb,3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With these tools we have very powerful data processing capabilities at our disposal. For example, to extract the average monthly average temperatures for each month of the year only takes a few lines of code: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "months = np.arange(1,13)\n", - "monthly_mean = [np.mean(data[data[:,1] == month, 3]) for month in months]\n", - "\n", - "fig, ax = plt.subplots()\n", - "ax.bar(months, monthly_mean)\n", - "ax.set_xlabel(\"Month\")\n", - "ax.set_ylabel(\"Monthly avg. temp.\");" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Calculations with higher-dimensional data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When functions such as `min`, `max`, etc., is applied to multidimensional arrays, it is sometimes useful to apply the calculation to the entire array, and sometimes only on a row or column basis. Using the `axis` argument we can specify how these functions should behave: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "m = np.random.rand(3,3)\n", - "m" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# global max\n", - "m.max()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# max in each column\n", - "m.max(axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# max in each row\n", - "m.max(axis=1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Many other functions and methods in the `array` and `matrix` classes accept the same (optional) `axis` keyword argument." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Copy and \"deep copy\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To achieve high performance, assignments in Python usually do not copy the underlaying objects. This is important for example when objects are passed between functions, to avoid an excessive amount of memory copying when it is not necessary (techincal term: pass by reference). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = np.array([[1, 2], [3, 4]])\n", - "A" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# now B is referring to the same array data as A \n", - "B = A " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# changing B affects A\n", - "B[0,0] = 10\n", - "B" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we want to avoid this behavior, so that when we get a new completely independent object `B` copied from `A`, then we need to do a so-called \"deep copy\" using the function `copy`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "B = np.copy(A)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# now, if we modify B, A is not affected\n", - "B[0,0] = -5\n", - "B" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reshaping, resizing and stacking arrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The shape of an Numpy array can be modified without copying the underlaying data, which makes it a fast operation even for large arrays." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n, m = A.shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "B = A.reshape((1,n*m))\n", - "B" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "B[0,0:5] = 5 # modify the array\n", - "B" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A # and the original variable is also changed. B is only a different view of the same data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also use the function `flatten` to make a higher-dimensional array into a vector. But this function create a copy of the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "B = A.flatten()\n", - "B" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "B[0:5] = 10\n", - "B" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A # now A has not changed, because B's data is a copy of A's, not refering to the same data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Adding a new dimension: newaxis" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With `newaxis`, we can insert new dimensions in an array, for example converting a vector to a column or row matrix:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = np.array([1,2,3])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.shape(v)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# make a column matrix of the vector v\n", - "v[:, np.newaxis]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# column matrix\n", - "v[:,np.newaxis].shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# row matrix\n", - "v[np.newaxis,:].shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Stacking and repeating arrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using function `repeat`, `tile`, `vstack`, `hstack`, and `concatenate` we can create larger vectors and matrices from smaller ones:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### tile and repeat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# repeat each element 3 times\n", - "np.repeat([1,2,5], 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = np.array([[1, 2], [3, 4]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# repeat each element froma 3 times\n", - "np.repeat(a, 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# tile the matrix a 3 times \n", - "np.tile(a, 3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### concatenate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b = np.array([[5, 6]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.concatenate((a, b), axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.concatenate((a, b.T), axis=1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### hstack and vstack" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.vstack((a,b))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.hstack((a,b.T))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Iterating over array elements" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Generally, we want to avoid iterating over the elements of arrays whenever we can (at all costs). The reason is that in a interpreted language like Python (or MATLAB), iterations are really slow compared to vectorized operations. \n", - "\n", - "However, sometimes iterations are unavoidable. For such cases, the Python `for` loop is the most convenient way to iterate over an array:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = np.array([1,2,3,4])\n", - "\n", - "for element in v:\n", - " print(element)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M = np.array([[1,2], [3,4]])\n", - "\n", - "for row in M:\n", - " print(\"row\", row)\n", - " \n", - " for element in row:\n", - " print(element)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When we need to iterate over each element of an array and modify its elements, it is convenient to use the `enumerate` function to obtain both the element and its index in the `for` loop: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for row_idx, row in enumerate(M):\n", - " print(\"row_idx\", row_idx, \"row\", row)\n", - " \n", - " for col_idx, element in enumerate(row):\n", - " print(\"col_idx\", col_idx, \"element\", element)\n", - " \n", - " # update the matrix M: square each element\n", - " M[row_idx, col_idx] = element ** 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# each element in M is now squared\n", - "M" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Vectorizing functions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As mentioned several times by now, to get good performance we should try to avoid looping over elements in our vectors and matrices, and instead use vectorized algorithms. The first step in converting a scalar algorithm to a vectorized algorithm is to make sure that the functions we write work with vector inputs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def Theta(x):\n", - " \"\"\"\n", - " Scalar implemenation of the Heaviside step function.\n", - " \"\"\"\n", - " if x >= 0:\n", - " return 1\n", - " else:\n", - " return 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Theta(np.array([-3,-2,-1,0,1,2,3])) # crashes!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "OK, that didn't work because we didn't write the `Theta` function so that it can handle with vector input... \n", - "\n", - "To get a vectorized version of Theta we can use the Numpy function `vectorize`. In many cases it can automatically vectorize a function:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Theta_vec = np.vectorize(Theta)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Theta_vec(np.array([-3,-2,-1,0,1,2,3]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also implement the function to accept vector input from the beginning (requires more effort but might give better performance):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# x is an array then (x >= 0) is an bool array and 1*(x >= 0) and int array\n", - "def Theta(x):\n", - " \"\"\"\n", - " Vector-aware implemenation of the Heaviside step function.\n", - " \"\"\"\n", - " return 1 * (x >= 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Theta(np.array([-3,-2,-1,0,1,2,3]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# still works for scalars as well\n", - "Theta(-1.2), Theta(2.6)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Timing\n", - "\n", - "The performance of numpy code can easily be compared with the help of the buildt-in Jupyter timing magic functions.\n", - "The %timeit magic runs a command several times to get an estimate on the run time" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 10000 random numbers\n", - "A=np.random.normal(0,1,10000)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# the slow for loop implementation\n", - "def Theta1(X):\n", - " out = np.empty_like(X,dtype=int)\n", - " for i,x in enumerate(X):\n", - " if x >= 0:\n", - " out[i]=1\n", - " else:\n", - " out[i]=0\n", - " return out\n", - "\n", - "# using np.vectorize on a scalar function. \n", - "# The vectorize function is provided primarily for convenience, not for performance.\n", - "# The implementation is essentially a for loop.\n", - "def Theta2(x):\n", - " \"\"\"\n", - " Scalar implemenation of the Heaviside step function.\n", - " \"\"\"\n", - " if x >= 0:\n", - " return 1\n", - " else:\n", - " return 0\n", - "Theta2_vec = np.vectorize(Theta2)\n", - "\n", - "# Vector-aware implemenation of the Heaviside step function\n", - "# This employs the full speed of numpy\n", - "def Theta3(x):\n", - " return 1 * (x >= 0)\n", - "print 'Theta1 - for loop:'\n", - "%timeit Theta1(A)\n", - "print 'Theta2 - vector aware implementation:'\n", - "%timeit Theta2_vec(A)\n", - "print 'Theta3 - vector aware implementation:'\n", - "%timeit Theta3(A)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Using arrays in conditions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When using arrays in conditions in for example `if` statements and other boolean expressions, one need to use one of `any` or `all`, which requires that any or all elements in the array evalutes to `True`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "if (M > 5).any():\n", - " print(\"at least one element in M is larger than 5\")\n", - "else:\n", - " print(\"no element in M is larger than 5\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "if (M > 5).all():\n", - " print(\"all elements in M are larger than 5\")\n", - "else:\n", - " print(\"all elements in M are not larger than 5\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Type casting" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since Numpy arrays are *statically typed*, the type of an array does not change once created. But we can explicitly cast an array of some type to another using the `astype` functions (see also the similar `asarray` function). This always create a new array of new type:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M.dtype" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M2 = M.astype(float)\n", - "\n", - "M2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M2.dtype" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M3 = M.astype(bool)\n", - "\n", - "M3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Further reading" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* http://numpy.org\n", - "* https://scipy.github.io/old-wiki/pages/Tentative_NumPy_Tutorial" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "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.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/.ipynb_checkpoints/Matplotlib_Cheatsheet-checkpoint.ipynb b/.ipynb_checkpoints/Matplotlib_Cheatsheet-checkpoint.ipynb deleted file mode 100644 index d5cd0b1..0000000 --- a/.ipynb_checkpoints/Matplotlib_Cheatsheet-checkpoint.ipynb +++ /dev/null @@ -1,1971 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Matplotlib Tips and Demos\n", - "\n", - "by jwink3101 https://github.com/Jwink3101/matplotlib_tips_examples\n", - "\n", - "When I first learned Python three years ago, I was often finding myself having to lookup the same thing again and again for Matplotlib. This was back pre-2.0 when there was even more issues (e.g. plotting `NaNs` with masked arrays). \n", - "\n", - "Some of this is super simple, some of it is more advanced. It is just my go-to reference" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Matplotlib Version: 3.0.3\n", - "NumPy Version: 1.16.2\n", - "Python Version: 3.7.3 (default, Mar 27 2019, 22:11:17) \n", - "[GCC 7.3.0]\n", - "Ran on 2019-05-12T09:47:46.641636\n" - ] - } - ], - "source": [ - "import numpy as np\n", - "import matplotlib as mpl\n", - "import matplotlib.pylab as plt\n", - "#%matplotlib inline # Display inline -- May not be needed on newer platforms\n", - "\n", - "\n", - "import sys\n", - "\n", - "print('Matplotlib Version: ' + mpl.__version__)\n", - "print('NumPy Version: ' + np.version.full_version)\n", - "print('Python Version: ' + sys.version)\n", - "\n", - "import datetime\n", - "now = datetime.datetime.now().isoformat()\n", - "print('Ran on ' + now)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The basics\n", - "\n", - "With *few* exception, all examples use the object-oriented interface via `plt.subplots()`. In general, there is full parity between `pyplot` and the object-oriented interface. My personal opinion is `plt.(...)` for quick-and-dirty and then use `ax.(...)` when I want more control.\n", - "\n", - "### Basic Plot\n", - "\n", - "With labels, etc. The code `exPlot` builds the basics with the set configurations" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.linspace(0,2*np.pi,10**3)\n", - "y = np.sin(x) + np.cos(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "def exPlot(useteX=False):\n", - " fig,ax = plt.subplots(1,1,figsize=(3,3),dpi=100,num=1)\n", - " ax.plot(x,y,'-k')\n", - " ax.set_xlabel(r'x label with math (ex: $x^2$)')\n", - " if not ueX:\n", - " ax.set_ylabel(r'y label with non-math math (ex: $\\mathregular{{x^2}}$)') # Doesn't work for LaTeX render\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Defaults" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "<Figure size 300x300 with 1 Axes>" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plt.rc('font', family='sans-serif') # These are the defaults\n", - "plt.rc('text', usetex=False)\n", - "\n", - "exPlot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Serif Only" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.rc('font', family='serif')\n", - "exPlot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### LaTeX\n", - "\n", - "... then reset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.rc('font', family='serif')\n", - "plt.rc('text', usetex=True)\n", - "exPlot(isTeX=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.rc('font', family='sans-serif')\n", - "plt.rc('text', usetex=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Scientific Notation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,(ax1,ax2) = plt.subplots(1,2,figsize=(7,3),dpi=100,num=1)\n", - "\n", - "# Regular\n", - "ax1.plot(x,1e4*y)\n", - "\n", - "# Scientific\n", - "ax2.plot(x,1e4*y)\n", - "\n", - "from matplotlib import ticker\n", - "formatter = ticker.ScalarFormatter(useMathText=True)\n", - "formatter.set_scientific(True) \n", - "formatter.set_powerlimits((-1,1))\n", - "\n", - "ax2.yaxis.set_major_formatter(formatter)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Standard Subplots\n", - "\n", - "### Adjustments" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def subdemo(axes):\n", - " for ii,ax in enumerate(axes.ravel()):\n", - " ax.plot(x,10**(ii)*y,'-k')\n", - " ax.yaxis.set_major_formatter(formatter) # Will always be the last one" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Default" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(7,3),dpi=100,num=1)\n", - "subdemo(axes)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Automatic\n", - "\n", - "This is the preffered way to do it" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(7,3),dpi=100,num=1)\n", - "subdemo(axes)\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Manual\n", - "\n", - "This example is not designed to look good. It is to show the results.\n", - "\n", - "This comes from <http://stackoverflow.com/a/6541482>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(7,3),dpi=100,num=1)\n", - "subdemo(axes)\n", - "\n", - "fig.subplots_adjust(hspace=0.45,wspace=0.35)\n", - "\n", - "## All Options w/ examples\n", - "# left = 0.125 # the left side of the subplots of the figure\n", - "# right = 0.9 # the right side of the subplots of the figure\n", - "# bottom = 0.1 # the bottom of the subplots of the figure\n", - "# top = 0.9 # the top of the subplots of the figure\n", - "# wspace = 0.2 # the amount of width reserved for blank space between subplots\n", - "# hspace = 0.2 # the amount of height reserved for white space between subplots" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Shared Axes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(7,3),dpi=100,\n", - " sharex=True)\n", - "subdemo(axes)\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also share the `y` axis, but it won't look good for this since they are different scales so this won't look good" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(7,3),dpi=100,\n", - " sharex=True,sharey=True)\n", - "subdemo(axes)\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Fancy Subplots\n", - "\n", - "There are a few ways to do this. \n", - "\n", - "* `gridspec` -- General purpose\n", - "* manually\n", - "* add subplots where you want -- doesn't have spans\n", - " * Regular subplots and then \"clear\" axis" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### `gridspec`\n", - "\n", - "Based on <http://matplotlib.org/users/gridspec.html>. You seem to have to rely on the `plt` tools to make all of the axes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure()\n", - "\n", - "ax = [None for _ in range(6)]\n", - "\n", - "ax[0] = plt.subplot2grid((3,4), (0,0), colspan=4)\n", - "\n", - "ax[1] = plt.subplot2grid((3,4), (1,0), colspan=1)\n", - "ax[2] = plt.subplot2grid((3,4), (1,1), colspan=1)\n", - "ax[3] = plt.subplot2grid((3,4), (1,2), colspan=1)\n", - "ax[4] = plt.subplot2grid((3,4), (1,3), colspan=1,rowspan=2)\n", - "\n", - "ax[5] = plt.subplot2grid((3,4), (2,0), colspan=3)\n", - "\n", - "for ix in range(6):\n", - " ax[ix].set_title('ax[{}]'.format(ix))\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Manually\n", - "\n", - "This example will be less complex to make life easier... In this case, you create the axes from the parent fig" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure()\n", - "\n", - "ax = [None for _ in range(3)]\n", - "\n", - "ax[0] = fig.add_axes([0.1,0.1,0.9,0.4]) # Bottom\n", - "ax[1] = fig.add_axes([0.15,0.6,0.25,0.6]) # They do not *need* to be in a grid\n", - "ax[2] = fig.add_axes([0.5,0.6,0.4,0.3])\n", - "\n", - "for ix in range(3):\n", - " ax[ix].set_title('ax[{}]'.format(ix))\n", - " \n", - "# fig.tight_layout() # does not work with this method" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Add subplots \n", - "\n", - "Can also do grids but harder (though not impossible) to do spanning" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure()\n", - "\n", - "ax = [None for _ in range(3)]\n", - "\n", - "ax[0] = fig.add_subplot(2,2,1)\n", - "ax[1] = fig.add_subplot(2,2,2)\n", - "ax[2] = fig.add_subplot(2,2,3)\n", - "\n", - "for ix in range(3):\n", - " ax[ix].set_title('ax[{}]'.format(ix))\n", - " \n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Regular plots with \"cleared\" axis" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2)\n", - "ax = axes[1,1]\n", - "ax.set_frame_on(False)\n", - "ax.set_xticks([])\n", - "ax.set_yticks([])\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### No Spacing Demo" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(3,3,sharex=True,sharey=True)\n", - "\n", - "np.random.seed(282)\n", - "X = np.random.normal(size=(30,3))\n", - "\n", - "import itertools\n", - "for ix,iy in itertools.product(range(3),range(3)):\n", - " ax = axes[ix,iy]\n", - " ax.plot(X[:,ix],X[:,iy],'ko')\n", - "\n", - "for ax in axes[-1,:]:\n", - " ax.set_xlabel('x')\n", - "for ax in axes[:,0]:\n", - " ax.set_ylabel('y')\n", - "\n", - "#fig.tight_layout(h_pad=0,w_pad=0)\n", - "fig.subplots_adjust(hspace=0,wspace=0)\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure()\n", - "\n", - "axes = []\n", - "\n", - "np.random.seed(282)\n", - "X = np.random.normal(size=(30,3))\n", - "\n", - "import itertools\n", - "for ii,(ix,iy) in enumerate(itertools.combinations([0,1,2],2)):\n", - " ax = fig.add_subplot(2,2,2*ix+iy)\n", - " ax.plot(X[:,ix],X[:,iy],'ko')\n", - " axes.append(ax)\n", - "\n", - "\n", - "#fig.tight_layout(h_pad=0,w_pad=0)\n", - "fig.subplots_adjust(hspace=0,wspace=0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Pcolor(mesh) & Colorbar (and nice colormap)\n", - "\n", - "Consider the following for making a nice `pcolor`-type plots with a colorbar. The colormaps are set with `cmap=plt.cm.Spectral_r` which is the nice one from ColorBrewer\n", - "\n", - "### Setup & Defaults" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.random.seed(362423)\n", - "A = np.random.uniform(size=(6,8))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,(ax1,ax2,ax3,ax4) = plt.subplots(1,4,figsize=(9,3),dpi=100)\n", - "def plotEX(ax,**kw):\n", - " ax.pcolormesh(A,**kw)\n", - "\n", - "plotEX(ax1)\n", - "plotEX(ax2,cmap=plt.cm.Spectral_r)\n", - "plotEX(ax3,cmap=plt.cm.Spectral_r,edgecolor='k')\n", - "plotEX(ax4,cmap=plt.cm.Spectral_r,shading='gouraud')\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Colorbars" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Standard colorbar\n", - "\n", - "The size of the figure was selected to show the problem with scale\n", - "\n", - "Also, since this invokes `fig`, it doesn’t play nice with subplots" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(3,5),dpi=100)\n", - "pl = ax.pcolormesh(A,cmap = plt.cm.Spectral_r,edgecolor='k')\n", - "ax.axis('image')\n", - "fig.colorbar(pl)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Scaled Colorbar\n", - "\n", - "This example scaled the colorbar. It also plays nicely with subplots (not demoed)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(3,5),dpi=100)\n", - "pl = ax.pcolormesh(A,cmap = plt.cm.Spectral_r,edgecolor='k')\n", - "ax.axis('image')\n", - "\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "divider = make_axes_locatable(ax)\n", - "cax = divider.append_axes(\"right\", size=\"5%\", pad=0.05)\n", - "cbar = fig.colorbar(pl,cax=cax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Set ranges" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(3,5),dpi=100)\n", - "pl = ax.pcolormesh(A,cmap = plt.cm.Spectral_r,edgecolor='k',vmin=-1,vmax=2.2)\n", - "ax.axis('image')\n", - "\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "divider = make_axes_locatable(ax)\n", - "cax = divider.append_axes(\"right\", size=\"5%\", pad=0.05)\n", - "cbar = fig.colorbar(pl,cax=cax)\n", - "cbar.set_ticks(np.linspace(-1,2.2,6))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Dealing with `nan` -- DEPRECATED\n", - "\n", - "This may be deprecated in Python 3 and/or later versions of matplotlib (not sure) but here is how to do it for this" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "B = A.copy()\n", - "B[2,3] = np.nan\n", - "\n", - "fig,(ax1,ax2) = plt.subplots(1,2,figsize=(7,5),dpi=100)\n", - "\n", - "ax1.pcolormesh(B,cmap = plt.cm.Spectral_r,edgecolor='k')\n", - "ax1.axis('image')\n", - "\n", - "B = np.ma.masked_array(B,np.isnan(B))\n", - "ax2.pcolormesh(B,cmap = plt.cm.Spectral_r,edgecolor='k')\n", - "ax2.axis('image')\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Ticks\n", - "\n", - "### Position\n", - "\n", - "The following shows some examples of setting the tick locations\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(7,5),dpi=100)\n", - "\n", - "X = np.linspace(0,2*np.pi,1000)\n", - "Y = np.sin(X)\n", - "\n", - "for ax in axes.ravel(): #plot\n", - " ax.plot(X,Y,'-k')\n", - "\n", - "ax = axes[0,0]\n", - "\n", - "ax = axes[0,1]\n", - "ax.tick_params(labeltop=True,labelbottom=False)\n", - "\n", - "ax = axes[1,0]\n", - "ax.tick_params(labelright=True,labelbottom=False,labelleft=False)\n", - "\n", - "ax = axes[1,1]\n", - "ax.tick_params(labeltop=True,labelbottom=True,labelright=True,labelleft=True)\n", - "\n", - "# Also add ticks\n", - "ax.tick_params(axis='both',bottom=True,top=True,left=True,right=True)\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### All sides + inside" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.logspace(0,3,600)\n", - "y = 1.2**(0.04*x)\n", - "fig,ax = plt.subplots(dpi=100)\n", - "ax.plot(x,y)\n", - "ax.set(xscale='log',yscale='log')\n", - "ax.tick_params(axis='both',bottom=True,top=True,left=True,right=True,direction='in',which='both')\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Grids\n", - "\n", - "Note that this is the same with and without a log scale but the log scale shows it better. The `zorder` makes sure the plot is in front of the grid lines" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,(ax1,ax2) = plt.subplots(1,2,sharey=True,figsize=(10,5))\n", - "x = np.logspace(0,3,600)\n", - "y = 1.2**(0.04*x)\n", - "\n", - "for ax in (ax1,ax2):\n", - " ax.plot(x,y,'-k')\n", - " ax.set(xscale='log',yscale='log')\n", - " ax.tick_params(axis='both',bottom=True,top=True,left=True,right=True,direction='in',which='both',zorder=10)\n", - "ax1.grid(which='major')\n", - "ax2.grid(which='both')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Labels\n", - "\n", - "Rotated text and `ha` (horizontal alignment)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(5,3),dpi=100)\n", - "\n", - "x = np.linspace(-10,10,100)\n", - "y = np.sin(x)/(x + np.spacing(1))\n", - "\n", - "labs = ['neg ten','neg five','zero','pos five','pos ten']\n", - "\n", - "for ax in axes.ravel():\n", - " ax.plot(x,y)\n", - " ax.set_xticks([-10,-5,0,5,10])\n", - "\n", - "axes[0,0].set_xticklabels(labs)\n", - "\n", - "axes[0,1].set_xticklabels(labs,rotation=-45)\n", - "axes[0,1].set_title('rotated')\n", - "\n", - "axes[1,0].set_xticklabels(labs,rotation=-45,ha='left')\n", - "axes[1,0].set_title('rotated, left')\n", - "\n", - "axes[1,1].set_xticklabels(labs,rotation=-45,ha='right')\n", - "axes[1,1].set_title('rotated, right')\n", - "\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Label Formats\n", - "\n", - "Also included are prettier x-labels" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X = np.linspace(0,2*np.pi,1000)\n", - "Y = np.cos(X)**2\n", - "\n", - "fig,(ax1,ax2,ax3) = plt.subplots(1,3,figsize=(8,3),dpi=100,num=1)\n", - "for ax in (ax1,ax2,ax3):\n", - " ax.plot(X,Y,'k-')\n", - " ax.set_yticks([0, 0.25, 0.5,0.75,1])\n", - " ax.set_xticks(np.linspace(0,2*np.pi,5))\n", - " ax.set_xticklabels([r'$0$',r'$\\frac{\\pi}{2}$',r'$\\pi$',r'$\\frac{3\\pi}{2}$',r'$2\\pi$'])\n", - "\n", - "ax1.set_title('Default')\n", - "\n", - "ax2.set_title('g formatting')\n", - "ax2.set_yticklabels( ['{:0.2g}'.format(l) for l in ax2.get_yticks()] )\n", - "\n", - "ax3.set_title('g formatting, force decimal')\n", - "ax3.set_yticklabels( ['{:0.2g}'.format(l) if int(l)!=float(l) else '{:0.1f}'.format(l) \n", - " for l in ax3.get_yticks()] )\n", - "\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Legends\n", - "\n", - "There are a few ways to work a legend. And there is a lot more that can be found on the web.\n", - "\n", - "The main takeaway is to have `label=` in the respective plot\n", - "\n", - "### Directly specify" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,(ax1,ax2) = plt.subplots(1,2,figsize=(7,3),dpi=100,num=1,sharey=True)\n", - "\n", - "X = np.linspace(0,2*np.pi,1000)\n", - "\n", - "def plotEX(ax):\n", - " pl = [None for i in range(3)]\n", - " \n", - " pl[0] = ax.plot(X,np.sin(X),label='One')\n", - " pl[1] = ax.plot(X,np.cos(X),label='Two')\n", - " pl[2] = ax.plot(X,np.sin(np.cos(X)),label='Three')\n", - " return [p[0] for p in pl] # makes it just the objects\n", - " \n", - "pl1 = plotEX(ax1) \n", - "ax1.legend()\n", - "\n", - "pl2 = plotEX(ax2) \n", - "ax2.legend([pl2[0],pl2[2]],['One','Three'])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Use `label`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,(ax1,ax2) = plt.subplots(1,2,figsize=(7,3),dpi=100,num=1,sharey=True)\n", - "\n", - "X = np.linspace(0,2*np.pi,1000)\n", - "\n", - "ax1.plot(X,np.sin(X),label='One')\n", - "ax1.plot(X,np.cos(X),label='Two')\n", - "ax1.plot(X,np.sin(np.cos(X)),label='Three')\n", - "ax1.legend()\n", - "\n", - "ax2.plot(X,np.sin(X),label='One')\n", - "ax2.plot(X,np.cos(X)) # NO LABEL\n", - "ax2.plot(X,np.sin(np.cos(X)),label='Three')\n", - "ax2.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Number of points\n", - "\n", - "Thankfully, the default was changed to one." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(1,4,figsize=(8,3),dpi=100,num=1,sharey=True)\n", - "\n", - "X = np.linspace(0,2*np.pi,8)\n", - "\n", - "\n", - "for ii,ax in enumerate(axes):\n", - " ax.plot(X,np.sin(X),'-o',label=r'Lab 1: $\\sin(x)$')\n", - " ax.plot(X,np.cos(X),'-s',label=r'Lab 1: $\\cos(x)$')\n", - " ax.legend(numpoints=(ii+1))\n", - " \n", - " \n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Dummy Legends\n", - "\n", - "This is useful if you want certain entries that are not to be plotted" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(5,3),dpi=100,num=1,sharey=True)\n", - "\n", - "X = np.linspace(0,2*np.pi,1000)\n", - "\n", - "# Real Lines\n", - "ax.plot(X,np.sin(X),'-')\n", - "ax.plot(X,np.cos(X),'-')\n", - "ax.plot(X,np.sin(np.cos(X)),'-')\n", - "\n", - "# Dummy lines\n", - "ax.plot([],'-rs',label='Dummy1')\n", - "ax.plot([],'k',label='Dummy2',LineWidth=8)\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Legend in its own plot" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(1,1))\n", - "ax.plot([],[],'-s',label='a',linewidth=2,ms=8)\n", - "ax.plot([],[],'-*',label='b',linewidth=2,ms=8)\n", - "ax.plot([],[],'-o',label='c',linewidth=2,ms=8)\n", - "ax.legend(loc='center',numpoints=1)\n", - "ax.set_frame_on(False)\n", - "ax.set_xticks([])\n", - "ax.set_yticks([])\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Multiple y-axes\n", - "\n", - "The first example is mine. The second is taken *nearly* verbatim from <http://stackoverflow.com/a/7734614>\n", - "\n", - "I will experiment a little with combining scientific notation as well as log scales but I won't go too crazy (until I have to do it at which point, I will update this)\n", - "\n", - "### Double y-axis\n", - "\n", - "**NOTE**: The keyword for `tick_params` is `colors` (with an **s**)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig, ax1 = plt.subplots(1,1,figsize=(5,3),dpi=100)\n", - "\n", - "X = np.linspace(-3*np.pi,3*np.pi,1000)\n", - "Y1 = np.sin(X)/(X+0.0001)\n", - "Y2 = 1e3 * np.cos(X)\n", - "Y3 = np.exp(np.abs(X))\n", - "\n", - "# Twin the axis\n", - "ax2 = ax1.twinx()\n", - "\n", - "# Plotting\n", - "ax1.plot(X,Y1,'-r')\n", - "ax2.plot(X,Y2,':b')\n", - "\n", - "# Color the axis and add labels\n", - "ax1.set_ylabel('Y1',color='r')\n", - "ax2.set_ylabel('Y2',color='b')\n", - "\n", - "ax1.tick_params(axis='y', colors='r')\n", - "ax2.tick_params(axis='y', colors='b')\n", - "\n", - "# Set the spine colors. Really only need to do ax2 since that is on top\n", - "# but this just makes 100% sure\n", - "for ax in (ax1,ax2):\n", - " ax.spines['left'].set_color('r')\n", - " ax.spines['right'].set_color('b')\n", - "\n", - "from matplotlib import ticker\n", - "formatter = ticker.ScalarFormatter(useMathText=True)\n", - "formatter.set_scientific(True) \n", - "formatter.set_powerlimits((-1,1)) \n", - "ax2.yaxis.set_major_formatter(formatter)\n", - "ax2.yaxis.get_offset_text().set_color('b') # Set the color of the power\n", - "\n", - "# Better X-Ticks\n", - "ax1.set_xlim((X.min(),X.max()))\n", - "ax1.set_xticks(np.arange(-3,4)*np.pi)\n", - "xticklabs = [r'$\\mathregular{{{0:d}\\pi}}$'.format(i) for i in np.arange(-3,4)]; xticklabs[3]='0'\n", - "ax1.set_xticklabels(xticklabs) \n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Triple y-axis\n", - "\n", - "Again, this is inspired by <http://stackoverflow.com/a/7734614> but I make a few changes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig, ax1 = plt.subplots(1,1,figsize=(6,4),dpi=100)\n", - "\n", - "# Twin the x-axis twice to make independent y-axes.\n", - "ax2 = ax1.twinx()\n", - "ax3 = ax1.twinx()\n", - "\n", - "# Make some space on the right side for the extra y-axis.\n", - "fig.subplots_adjust(right=0.75)\n", - "\n", - "# Move the last y-axis spine over to the right by 20% of the width of the axes\n", - "ax3.spines['right'].set_position(('axes', 1.2))\n", - "\n", - "# To make the border of the right-most axis visible, we need to turn the frame\n", - "# on. This hides the other plots, however, so we need to turn its fill off.\n", - "ax3.set_frame_on(True)\n", - "ax3.patch.set_visible(False)\n", - "\n", - "# Plot\n", - "ax1.plot(X,Y1,'-r')\n", - "ax2.plot(X,Y2,'-b')\n", - "ax3.plot(X,Y3,'-g')\n", - "\n", - "colors = ['r','b','g']\n", - "axes = [ax1,ax2,ax3]\n", - "names = ['Y1','Y2','Y3']\n", - "\n", - "for ax in (ax1,ax2,ax3):\n", - " ax.spines['left'].set_color(colors[0])\n", - " ax.spines['right'].set_color(colors[1])\n", - "ax3.spines['right'].set_color('g') # reset\n", - " \n", - "for ax,color,name in zip(axes,colors,names):\n", - " ax.set_ylabel(name,color=color)\n", - " ax.tick_params(axis='y', colors=color)\n", - "\n", - "# Nicer ax2 y axis\n", - "from matplotlib import ticker\n", - "formatter = ticker.ScalarFormatter(useMathText=True)\n", - "formatter.set_scientific(True) \n", - "formatter.set_powerlimits((-1,1)) \n", - "ax2.yaxis.set_major_formatter(formatter)\n", - "ax2.yaxis.get_offset_text().set_color('b') # Set the color of the power\n", - "\n", - "# Set ax3 to log\n", - "ax3.set_yscale('log')\n", - "\n", - "# Better X-Ticks\n", - "ax1.set_xlim((X.min(),X.max()))\n", - "ax1.set_xticks(np.arange(-3,4)*np.pi)\n", - "xticklabs = [r'$\\mathregular{{{0:d}\\pi}}$'.format(i) for i in np.arange(-3,4)]; xticklabs[3]='0'\n", - "ax1.set_xticklabels(xticklabs)\n", - "\n", - "fig.tight_layout()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3D Data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X1,X2 = np.meshgrid(*[np.linspace(-1,1,100)]*2)\n", - "F = (1.0 + (1.0/3.0)/(2.0 * X1 + X2 + 7.0/2.0) ) * np.exp(- (0.5 * (X2-1.0/5.0) * (X1 + 1.0))**2)\n", - "\n", - "def _set_axis(ax,z=True):\n", - " r =0.01\n", - " if z:\n", - " ax.set_zlim([0.25, 1.67])\n", - " ax.set_xlim([-1-2*r, 1+2*r])\n", - " ax.set_ylim([-1-2*r, 1+2*r])\n", - " ax.set_xlabel('x1');ax.set_ylabel('x2')\n", - " ax.set_aspect('equal')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Countour\n", - "\n", - "\n", - "`contourf` does *not* include the lines so it is helpful to set them yourself.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,2,figsize=(9,7))\n", - "\n", - "axes[0,0].contour(X1,X2,F,35)\n", - "axes[0,0].set_title('Defaults + N=35')\n", - "\n", - "axes[0,1].contourf(X1,X2,F,35)\n", - "axes[0,1].set_title('Defaults filled + N=35')\n", - "\n", - "axes[1,0].contourf(X1,X2,F,35)\n", - "axes[1,0].contour(X1,X2,F,35,colors='k',linewidths =0.5 )\n", - "axes[1,0].set_title('Filled + lines + N=35')\n", - "\n", - "axes[1,1].contourf(X1,X2,F,35,cmap=plt.cm.Greys)\n", - "axes[1,1].contour(X1,X2,F,35,colors='k',linewidths =0.5 )\n", - "axes[1,1].set_title('Filled + lines + N=35, greys')\n", - "\n", - "for ax in axes.ravel():\n", - " _set_axis(ax,z=False)\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Colorbar\n", - "\n", - "Same as above" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots()\n", - "obj = ax.contourf(X1,X2,F,35,cmap=plt.cm.Spectral_r)\n", - "ax.contour(X1,X2,F,35,colors='k',linewidths =0.5 )\n", - "\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "divider = make_axes_locatable(ax)\n", - "cax = divider.append_axes(\"right\", size=\"5%\", pad=0.05)\n", - "cbar = fig.colorbar(obj,cax=cax)\n", - "\n", - "_set_axis(ax,z=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Surface Plots\n", - "\n", - "Unlike Matlab, there is nothing wrong with setting your grid with a lot of points. You then use `cstride` and `rstride` to control that. In this example, I set with 100 points but use `cstride=4` to only plot a line every 4 spaces and `rstride=3` to plot a line every 3 in the other direction\n", - "\n", - "Must include the following to import `Axes3D`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from mpl_toolkits.mplot3d import Axes3D" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Default" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure(num=1)\n", - "ax = fig.add_subplot(111,projection='3d')\n", - "SF = ax.plot_surface(X1,X2,F,rstride=4,cstride=3,cmap=plt.cm.Spectral_r)\n", - "_set_axis(ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Wiremesh" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure(num=1)\n", - "ax = fig.add_subplot(111,projection='3d')\n", - "SF = ax.plot_wireframe(X1,X2,F,rstride=4,cstride=3,color='k')\n", - "_set_axis(ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Wiremesh + contour + white panes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure(num=1)\n", - "ax = fig.add_subplot(111,projection='3d')\n", - "\n", - "# White edges\n", - "ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) \n", - "ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) \n", - "ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) \n", - "\n", - "SF = ax.plot_wireframe(X1,X2,F,rstride=4,cstride=3,color='k')\n", - "CS = ax.contour(X1,X2,F,25,zdir='z',offset=0.25, colors='k')\n", - "_set_axis(ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### All together + rotation + colorbar" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cmap=plt.cm.RdBu\n", - "fig = plt.figure(num=1)\n", - "ax = fig.add_subplot(111,projection='3d')\n", - "SF = ax.plot_surface(X1,X2,F,rstride=4,cstride=3,cmap=cmap)\n", - "SF = ax.plot_wireframe(X1,X2,F,rstride=8,cstride=6,color='k')\n", - "CS = ax.contour(X1,X2,F,25,zdir='z',offset=0.25, colors='k')\n", - "\n", - "# Colorbar\n", - "m = plt.cm.ScalarMappable(cmap=cmap)\n", - "m.set_array(F)\n", - "fig.colorbar(m)\n", - "\n", - "# Rotate\n", - "ax.view_init(35,49)\n", - "\n", - "ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) \n", - "ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) \n", - "ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) \n", - "\n", - "_set_axis(ax)\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Interactive\n", - "\n", - "This shows how to do the plots interactive by changing \n", - "\n", - " %matplotlib inline\n", - " \n", - "to\n", - "\n", - " %matplotlib qt\n", - "\n", - "But it is to be commented out in the main one.\n", - "\n", - "It may need to be run twice...\n", - "\n", - "```python\n", - "%matplotlib qt\n", - "#%matplotlib inline\n", - "fig = plt.figure(num=1)\n", - "ax = fig.add_subplot(111,projection='3d')\n", - "SF = ax.plot_wireframe(X1,X2,F,rstride=4,cstride=3,color='k')\n", - "_set_axis(ax)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Violin Plots\n", - "\n", - "Pretty rudimentary for now" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from collections import OrderedDict\n", - "samples = OrderedDict()\n", - "np.random.seed(100)\n", - "\n", - "samples['uniform'] = np.random.uniform(size=200)\n", - "samples['normal'] = np.random.normal(size=200,scale=0.2)\n", - "samples['beta'] = np.random.beta(a=5,b=9,size=200)\n", - "samples['gamma'] = np.random.gamma(1,size=200,scale=0.1)\n", - "\n", - "fig,ax = plt.subplots()\n", - "\n", - "for ii,x in enumerate(samples.values()):\n", - " ax.violinplot(x,positions=[ii])\n", - " \n", - "ax.set_xticks(np.arange(len(samples)))\n", - "ax.set_xticklabels(list(samples.keys()))\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots()\n", - "\n", - "for ii,x in enumerate(samples.values()):\n", - " vp = ax.violinplot(x,positions=[ii])\n", - " color = vp['cbars'].get_color()[0]\n", - " \n", - " #plot the IQR\n", - " w = 0.075\n", - " xx = ii + np.array([-1,1])*w - 0.005\n", - " ax.fill_between(xx,*np.percentile(x,[25,75]),color=color,alpha=0.5)\n", - " \n", - " # These can also be done by ax.violinplot\n", - " ax.plot(xx,[np.median(x)]*2,'-',color=color)\n", - "ax.set_xticks(np.arange(len(samples)))\n", - "ax.set_xticklabels(list(samples.keys()))\n", - "\n", - "ax.fill_between([],[],color='k',label='IQR')\n", - "ax.plot([],[],color='k',label='median')\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Patches & hatches\n", - "\n", - "This discussion is largly taken from <http://matthiaseisen.com/pp/patterns/p0203/>\n", - "\n", - "### Simple patch object\n", - "\n", - "(again, see link above)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(1.62*4,4),dpi=100,num=1)\n", - "ax.add_patch(\n", - " mpl.patches.Rectangle(\n", - " (0.1, 0.1), # (x,y)\n", - " 0.5, # width\n", - " 0.5, # height\n", - " )\n", - ")\n", - "ax.add_patch(\n", - " mpl.patches.Rectangle((0.7,0.1),0.2,0.4,fill=False)\n", - " )\n", - "ax.add_patch(\n", - " mpl.patches.Rectangle((0.1,0.7),0.5,0.2,fill=False,hatch='//')\n", - " )\n", - "ax.set_xlim((0,1))\n", - "ax.set_ylim((0,1))\n", - "ax.set_aspect('equal')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Hatch Demos\n", - "\n", - "Below are many types of hatches. From the [documentation](http://matplotlib.org/api/collections_api.html#matplotlib.collections.Collection.set_hatch) only notes:\n", - "\n", - "```\n", - "/ - diagonal hatching\n", - "\\ - back diagonal\n", - "| - vertical\n", - "- - horizontal\n", - "+ - crossed\n", - "x - crossed diagonal\n", - "o - small circle\n", - "O - large circle\n", - ". - dots\n", - "* - stars\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hatches = ['/','\\\\','|','-','+','x','o','O','.','*']\n", - "fig,axes = plt.subplots(2,5,figsize=(4,3.3),dpi=100,num=1)\n", - "\n", - "def plotHatch(ax,hatch):\n", - " ax.add_patch(mpl.patches.Rectangle((0.05,0.05),0.85,1.85,fill=False,hatch=hatch))\n", - " ax.set_xlim((0,1))\n", - " ax.set_ylim((0,2))\n", - " ax.set_aspect('equal')\n", - " ax.axis('off')\n", - " ax.set_title(r\"' {:s} '\".format(hatch))\n", - "\n", - "for hatch,ax in zip(hatches,axes.ravel()):\n", - " plotHatch(ax,hatch)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Double, Triple, etc" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,5,figsize=(4,3.3),dpi=100,num=1)\n", - "for hatch,ax in zip(hatches,axes.ravel()):\n", - " plotHatch(ax,hatch*2)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,axes = plt.subplots(2,5,figsize=(4,3.3),dpi=100,num=1)\n", - "for hatch,ax in zip(hatches,axes.ravel()):\n", - " plotHatch(ax,hatch*3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Hatch filled plots" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(8,4),dpi=100)\n", - "X = np.linspace(0,2*np.pi,300)\n", - "Y = np.sin(X**1.2)**2\n", - "\n", - "ax.plot(X,1.0/(Y+1),'-k',zorder=-10) # Set behind by using zorder\n", - "ax.plot(X,Y,'-k',zorder=2)\n", - "\n", - "ax.fill_between(X,1.0/(Y+1),hatch='++',facecolor='w',label='A')\n", - "ax.fill_between(X,Y,hatch='xxx',facecolor='w',label='B')\n", - "ax.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(8,4),dpi=100)\n", - "np.random.seed(28832)\n", - "X = np.random.uniform(size=(10,4))\n", - "ax.scatter(X[:,0],X[:,1],s=250,color='w',edgecolors='k',hatch='xxx')\n", - "\n", - "ax.scatter(X[:,1],X[:,0],s=250,color='w',edgecolors='k',hatch='///')\n", - "ax.scatter(X[:,2],X[:,3],s=250,color='w',edgecolors='k',hatch='\\\\\\\\\\\\')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Inset Plots, Etc\n", - "\n", - "There are many ways to do inset plots. I will demo a few here\n", - "\n", - "### Built In Tools\n", - "\n", - "The following demos using a built in tool: `mpl_toolkits.axes_grid1.inset_locator.inset_axes`\n", - "\n", - "The whole thing is not well documented, but I followed the inheretance up to `mpl_toolkits.axes_grid1.inset_locator.AnchoredOffsetbox`. From that, I got the following location guides:\n", - "\n", - " 'upper right' : 1,\n", - " 'upper left' : 2,\n", - " 'lower left' : 3,\n", - " 'lower right' : 4,\n", - " 'right' : 5,\n", - " 'center left' : 6,\n", - " 'center right' : 7,\n", - " 'lower center' : 8,\n", - " 'upper center' : 9,\n", - " 'center' : 10,\n", - " \n", - "See [AxesGrid toolkit Overview](http://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html#insetlocator)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from mpl_toolkits.axes_grid1 import inset_locator\n", - "X = np.linspace(0,2*np.pi,1000)\n", - "np.random.seed(47344)\n", - "A = np.random.uniform(size=(4,7))\n", - "\n", - "fig,axes = plt.subplots(1,3,figsize=(7,3),dpi=100,sharey=True)\n", - "\n", - "locs = [1,2,6]\n", - "\n", - "ax_minis = []\n", - "for ax,loc in zip(axes,locs): \n", - " ax.plot(X,np.sin(X),'-b')\n", - " \n", - " ax_mini = inset_locator.inset_axes(ax,width='60%',height='20%',loc=loc)\n", - " \n", - " ax_mini.pcolormesh(A,cmap = plt.cm.Spectral_r,edgecolor='k')\n", - " ax_minis.append(ax_mini) # Smart to save it \n", - "\n", - "# The following will fail with this\n", - "# fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Alternative\n", - "\n", - "The general alternative is to use `fig.add_axes` and manually set all that is needed. See also <http://stackoverflow.com/a/17479417> " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Bar Charts\n", - "\n", - "See the below example for how to make multiple bar charts. \n", - "\n", - "Note that the width is decided based on the numbers" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig,ax = plt.subplots(1,1,figsize=(6,3),dpi=100,num=1)\n", - "\n", - "Nbins = 5\n", - "Nbars = 4 # Number of bars (items) per bin\n", - "\n", - "width = 1.0 /(Nbars+2)\n", - "ind = np.arange(Nbins)\n", - "\n", - "# generate random data for now\n", - "np.random.seed(44328)\n", - "Data = [np.random.uniform(size=Nbins) for i in range(Nbars)]\n", - "labels = ['x','y','z','w']\n", - "\n", - "for ii,dat_item in enumerate(Data):\n", - " ax.bar(ind + (ii+1)*width,dat_item,width,label=labels[ii])\n", - "\n", - "ax.set_xticks(ind+0.5)\n", - "ax.set_xticklabels(['a','b','c','d','e'])\n", - "ax.legend(loc=2,ncol=2) \n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Fancy Boxes\n", - "\n", - "These come directly from <http://stackoverflow.com/a/17087794>\n", - "\n", - "> The last two are \"Fancy\" bbox patches, so the padding, etc is set in a different manner. (Which is rather annoying for simple things like padding, though it makes the implementation simpler behind-the-scenes.)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "\n", - "ax.text(0.5, 0.8, 'Test', color='red', \n", - " bbox=dict(facecolor='none', edgecolor='red'))\n", - "ax.text(0.5, 0.6, 'Test', color='blue', \n", - " bbox=dict(facecolor='none', edgecolor='blue', pad=10.0))\n", - "ax.text(0.5, 0.4, 'Test', color='green', \n", - " bbox=dict(facecolor='none', edgecolor='green', \n", - " boxstyle='round'))\n", - "ax.text(0.5, 0.2, 'Test', color='black', \n", - " bbox=dict(facecolor='none', edgecolor='black', \n", - " boxstyle='round,pad=1'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Contours of scattered Data\n", - "\n", - "Two ways to contour scattered data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.random.seed(1002)\n", - "N = 100\n", - "X = np.random.uniform(size=N)\n", - "Y = np.random.uniform(size=N)\n", - "\n", - "Z = np.sin(X) + np.cos(Y)\n", - "\n", - "fig,axes = plt.subplots(1,2,figsize=(8,5))\n", - "\n", - "cmap = plt.cm.Spectral\n", - "\n", - "ax = axes[0]\n", - "ax.tripcolor(X,Y,Z,cmap=cmap)\n", - "ax.plot(X,Y,'.k')\n", - "ax.set_title('tripcolor')\n", - "ax.set_xlim([0,1]); ax.set_ylim([0,1])\n", - "\n", - "ax = axes[1]\n", - "ax.tricontourf(X,Y,Z,30,cmap=cmap)\n", - "ax.plot(X,Y,'.k')\n", - "ax.set_title('tricontourf')\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Scaled Colors\n", - "\n", - "### Lines" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X = np.linspace(0,1,1000);\n", - "\n", - "cmap = plt.cm.Spectral\n", - "vals = np.array([0.5,1,2,3,12])\n", - "vals01 = (vals - vals.min()) / (vals.max() - vals.min())\n", - "\n", - "colors = cmap(vals01)\n", - "\n", - "fig,ax = plt.subplots()\n", - "\n", - "# Fake a color bar\n", - "pcf = ax.pcolormesh([[0,12],[12,0]],cmap=cmap,vmin=0,vmax=12)\n", - "ax.clear()\n", - "\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "divider = make_axes_locatable(ax)\n", - "cax = divider.append_axes(\"right\", size=\"5%\", pad=0.05)\n", - "cbar = fig.colorbar(pcf,cax=cax)\n", - "\n", - "# Now plot\n", - "for color,val in zip(colors,vals):\n", - " ax.plot(X,np.sin(2*np.pi*X)+val,'-',color=color)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Filled \n", - "\n", - "Presented below are two different ways to do this. The first is **better** but I show the other as well. The first way doesn't require as much fiddling with the inputs and will handle expansion better.\n", - "\n", - "Notice there is a non-linear scaling" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cmap = plt.cm.RdYlBu\n", - "\n", - "X = np.linspace(0,1,50)\n", - "fun = lambda n: (np.exp(2*n))*0.5*(1-np.cos(X*2*np.pi))\n", - "\n", - "fig,axes = plt.subplots(1,3,figsize=(13,5))\n", - "\n", - "########### Fake a color bar\n", - "pcf = axes[2].pcolormesh([[0,1],[1,0]],cmap=cmap,vmin=0,vmax=1)\n", - "axes[2].clear()\n", - "\n", - "############################### Better way\n", - "N = 90\n", - "ax = axes[0]\n", - "for ii in range(N-1):\n", - " n0 = 1.0*ii/(N-1)\n", - " n1 = 1.0*(ii+1)/(N-1)\n", - " nc = 1.0*ii/(N-2) # color SHould be in [0,1]\n", - " \n", - " ax.fill_between(X,fun(n0),fun(n1),color=cmap(nc))\n", - "\n", - " ax.set_title('Filled. N={}'.format(N))\n", - " \n", - "############################### Alternative. Have to be careful about spacing\n", - "for ax,N2 in zip(axes[1:],[N,6*N]):\n", - " for ii in range(N2):\n", - " n = 1.0*ii/(N2-1)\n", - " ax.plot(X,fun(n),'-',color=cmap(n))\n", - " ax.set_title('Lines. N={}'.format(N2))\n", - "#fig.colorbar(pcf)\n", - "############################ Colorbar\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "for ax in axes:\n", - " divider = make_axes_locatable(ax)\n", - " cax = divider.append_axes(\"right\", size=\"5%\", pad=0.05)\n", - " cbar = fig.colorbar(pcf,cax=cax)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Styles\n", - "\n", - "You can also use some of the built-in styles." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "inline_rc = dict(mpl.rcParams)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams.update(mpl.rcParamsDefault)\n", - "mpl.rcParams.update(inline_rc)\n", - "X = np.linspace(0,2*np.pi,100)\n", - "Y1 = np.sin(X)\n", - "Y2 = np.sin(X**2)\n", - "for ii,style in enumerate(sorted(plt.style.available)):\n", - " fig,ax = plt.subplots(figsize=(3,2),num=ii)\n", - " plt.style.use(style)\n", - " ax.plot(X,Y1,label='Y1')\n", - " ax.plot(X,Y2,label='Y2')\n", - " ax.set_title(style)\n", - "\n", - "plt.style.use('default')\n", - "mpl.rcParams.update(mpl.rcParamsDefault)\n", - "mpl.rcParams.update(inline_rc)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Export Issues\n", - "\n", - "By default, Jupyter exports images as `png`. In addition, at least with Chrome, only `png` can be viewed\n", - "\n", - "Below is the command to export as PDF as well. However, markdown export tends to break (doesn't show images) when you do both exports. See workaround below\n", - "\n", - "```python\n", - "from IPython.display import set_matplotlib_formats\n", - "set_matplotlib_formats('png','pdf') # Exports both png and pdf. See below for issues\n", - "set_matplotlib_formats('png') # Just pngs. Good for development\n", - "```\n", - "\n", - "### Markdown Export Workaround\n", - "\n", - "As noted above, markdown export images do not work with the PDF option (though PDF export does work). The workaround is as follows:\n", - "\n", - "1. Include the above code block, run the code, export as markdown\n", - "1. Remove the above code (or just have `set_matplotlib_formats('png')`), run the code, export to markdown\n", - "1. Find/Replace `png)` with `pdf)` and copy the corresponding pdf files into that directory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "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.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} -- GitLab