{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Visualization in Python\n", "\n", "- Python provides a wide array of options\n", "- Low-level and high-level plotting APIs\n", "- Static images vs. HTML output vs. interactive plots\n", "- Domain-general and domain-specific packages\n", "\n", "***Note: Some of the visualisations will not work unless your browswer supports WebGL (i.e. not the firefox installed in the CVL). If you need to switch browsers, copy/paste the \"localhost+token\" link from the terminal you launched Jupyter notebook from***\n", "\n", "**PS: Many pieces of this notebook have been scavenged from other visualization notebooks and galleries. But the main things are from Tal Yarkoni's [visualization-in-python notebook](https://github.com/neurohackweek/visualization-in-python).**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# General Overview\n", "\n", "In this notebook, we will cover the following python packages. Some of them are exclusively for visualization while others like `Pandas` have many other purposes:\n", "\n", "- [Matplotlib](https://matplotlib.org/)\n", "- [Seaborn](http://seaborn.pydata.org/)\n", "- [Pandas](http://pandas.pydata.org/)\n", "- [Bokeh](https://bokeh.pydata.org)\n", "- [Plotly](https://plot.ly/python/)\n", "- [HoloViews](http://holoviews.org/)\n", "\n", "The visualization of the first three is all based on matplotlib and use static images. While the last three create HTML outputs and allow much more interactive plots. We will talk about each one as we go along.\n", "\n", "## Python-graph-gallery\n", "Check out the very helpful and cool new homepage https://python-graph-gallery.com/ to see how you can create different kinds of graphs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Preparation\n", "\n", "As with most things in Python, we first load the relevant packages. Here we load three important packages:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first line in the cell above is specific to Jupyter notebooks. It tells the interpreter to capture figures and embed them in the browser. Otherwise, they would end up almost in digital ether." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Datasets\n", "\n", "For example purposes, we will make use of a phenotypic dataset from the [ABIDE II](http://fcon_1000.projects.nitrc.org/indi/abide/abide_II.html) consortium. This multi-site dataset contains data from individuals diagnosed with Autism Spectrum Disorder (ASD) and healthy controls. We will first load the data from a single site.\n", "\n", "Let's read this from the Web using Pandas. We explicitly specify that missing values are noted in the dataset as `'n/a'`." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "df = pd.read_table('data/participants.tsv', na_values=['n/a'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the following cell we remove all columns that have missing values." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | site_id | \n", "participant_id | \n", "dx_group | \n", "age_at_scan | \n", "sex | \n", "handedness_category | \n", "handedness_scores | \n", "viq | \n", "piq | \n", "viq_test_type | \n", "piq_test_type | \n", "nonasd_psydx_icd9code | \n", "nonasd_psydx_label | \n", "eye_status_at_scan | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | \n", "ABIDEII-KKI_1 | \n", "29273 | \n", "1 | \n", "8.476712 | \n", "1 | \n", "1.0 | \n", "82.0 | \n", "142.0 | \n", "104.0 | \n", "WISC-IV | \n", "WISC-IV | \n", "314.01 | \n", "ADHD combined | \n", "1.0 | \n", "
1 | \n", "ABIDEII-KKI_1 | \n", "29274 | \n", "1 | \n", "9.246575 | \n", "1 | \n", "1.0 | \n", "83.0 | \n", "104.0 | \n", "79.0 | \n", "WISC-IV | \n", "WISC-IV | \n", "296.3 | \n", "MDD (past) | \n", "1.0 | \n", "
2 | \n", "ABIDEII-KKI_1 | \n", "29275 | \n", "1 | \n", "8.646575 | \n", "1 | \n", "1.0 | \n", "100.0 | \n", "130.0 | \n", "121.0 | \n", "WISC-IV | \n", "WISC-IV | \n", "313.81 | \n", "ODD | \n", "1.0 | \n", "
3 | \n", "ABIDEII-KKI_1 | \n", "29276 | \n", "1 | \n", "9.216438 | \n", "2 | \n", "1.0 | \n", "100.0 | \n", "128.0 | \n", "115.0 | \n", "WISC-IV | \n", "WISC-IV | \n", "314.01; 300.29 | \n", "ADHD combined; simple phobia | \n", "1.0 | \n", "
4 | \n", "ABIDEII-KKI_1 | \n", "29277 | \n", "1 | \n", "12.789041 | \n", "1 | \n", "1.0 | \n", "90.0 | \n", "132.0 | \n", "123.0 | \n", "WISC-IV | \n", "WISC-IV | \n", "314.01 | \n", "ADHD hyperactive/impulsive | \n", "1.0 | \n", "
\n", " | SepalLength | \n", "SepalWidth | \n", "PetalLength | \n", "PetalWidth | \n", "Species | \n", "
---|---|---|---|---|---|
0 | \n", "5.1 | \n", "3.5 | \n", "1.4 | \n", "0.2 | \n", "setosa | \n", "
8 | \n", "4.4 | \n", "2.9 | \n", "1.4 | \n", "0.2 | \n", "setosa | \n", "
16 | \n", "5.4 | \n", "3.9 | \n", "1.3 | \n", "0.4 | \n", "setosa | \n", "
24 | \n", "4.8 | \n", "3.4 | \n", "1.9 | \n", "0.2 | \n", "setosa | \n", "
32 | \n", "5.2 | \n", "4.1 | \n", "1.5 | \n", "0.1 | \n", "setosa | \n", "
40 | \n", "5.0 | \n", "3.5 | \n", "1.3 | \n", "0.3 | \n", "setosa | \n", "
48 | \n", "5.3 | \n", "3.7 | \n", "1.5 | \n", "0.2 | \n", "setosa | \n", "
56 | \n", "6.3 | \n", "3.3 | \n", "4.7 | \n", "1.6 | \n", "versicolor | \n", "
64 | \n", "5.6 | \n", "2.9 | \n", "3.6 | \n", "1.3 | \n", "versicolor | \n", "
72 | \n", "6.3 | \n", "2.5 | \n", "4.9 | \n", "1.5 | \n", "versicolor | \n", "
80 | \n", "5.5 | \n", "2.4 | \n", "3.8 | \n", "1.1 | \n", "versicolor | \n", "
88 | \n", "5.6 | \n", "3.0 | \n", "4.1 | \n", "1.3 | \n", "versicolor | \n", "
96 | \n", "5.7 | \n", "2.9 | \n", "4.2 | \n", "1.3 | \n", "versicolor | \n", "
104 | \n", "6.5 | \n", "3.0 | \n", "5.8 | \n", "2.2 | \n", "virginica | \n", "
112 | \n", "6.8 | \n", "3.0 | \n", "5.5 | \n", "2.1 | \n", "virginica | \n", "
120 | \n", "6.9 | \n", "3.2 | \n", "5.7 | \n", "2.3 | \n", "virginica | \n", "
128 | \n", "6.4 | \n", "2.8 | \n", "5.6 | \n", "2.1 | \n", "virginica | \n", "
136 | \n", "6.3 | \n", "3.4 | \n", "5.6 | \n", "2.4 | \n", "virginica | \n", "
144 | \n", "6.7 | \n", "3.3 | \n", "5.7 | \n", "2.5 | \n", "virginica | \n", "
\n", " | SepalLength | \n", "SepalWidth | \n", "PetalLength | \n", "PetalWidth | \n", "Species | \n", "
---|---|---|---|---|---|
0 | \n", "5.1 | \n", "3.5 | \n", "1.4 | \n", "0.2 | \n", "setosa | \n", "
1 | \n", "4.9 | \n", "3.0 | \n", "1.4 | \n", "0.2 | \n", "setosa | \n", "
2 | \n", "4.7 | \n", "3.2 | \n", "1.3 | \n", "0.2 | \n", "setosa | \n", "
3 | \n", "4.6 | \n", "3.1 | \n", "1.5 | \n", "0.2 | \n", "setosa | \n", "
4 | \n", "5.0 | \n", "3.6 | \n", "1.4 | \n", "0.2 | \n", "setosa | \n", "
\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"
\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"
\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"
\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"
\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"
\\n\"+\n",
" \"=55296&&m<=56319&&(f+=t[++d]),l.call(e,v,f,u),!_);++d);else c.call(t,function(t){return l.call(e,v,t,u),_})}},function(t,e,n){var i=t(326),r=t(363),o=t(365),s=t(370),a=t(371),l=t(384).iterator;e.exports=function(t){return\"function\"==typeof a(t)[l]?t[l]():i(t)?new o(t):r(t)?new s(t):new o(t)}},function(t,e,n){var i,r=t(321),o=t(339),s=t(357),a=t(359),l=t(320),c=t(319),h=t(384),u=Object.defineProperty,_=Object.defineProperties;e.exports=i=function(t,e){if(!(this instanceof i))throw new TypeError(\"Constructor requires 'new'\");_(this,{__list__:l(\"w\",a(t)),__context__:l(\"w\",e),__nextIndex__:l(\"w\",0)}),e&&(s(e.on),e.on(\"_add\",this._onAdd),e.on(\"_delete\",this._onDelete),e.on(\"_clear\",this._onClear))},delete i.prototype.constructor,_(i.prototype,o({_next:l(function(){var t;if(this.__list__)return this.__redo__&&void 0!==(t=this.__redo__.shift())?t:this.__nextIndex__