From 00d179f7eb1a19fb0e239e1e93c406883e65221d Mon Sep 17 00:00:00 2001
From: Sean Fitzgibbon <seanf@fmrib.ox.ac.uk>
Date: Wed, 28 Apr 2021 22:37:00 +0100
Subject: [PATCH] Added first pass at plotly examples notebook

---
 applications/data_visualisation/plotly.ipynb | 609 +++++++++++++++++++
 1 file changed, 609 insertions(+)
 create mode 100644 applications/data_visualisation/plotly.ipynb

diff --git a/applications/data_visualisation/plotly.ipynb b/applications/data_visualisation/plotly.ipynb
new file mode 100644
index 0000000..b4e7a27
--- /dev/null
+++ b/applications/data_visualisation/plotly.ipynb
@@ -0,0 +1,609 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# `plotly.py`\n",
+    "\n",
+    "[`plotly.py`](https://plotly.com/python/) a python interface to the `plotly` javascript library which is an open-source graphing library which specialises in high-quality web-based interactive graphs. `plotly.py` allows you to create these interactive web-based plots without having to code in javascript.\n",
+    "\n",
+    "`plotly.py` has excellent documentation: https://plotly.com/python/\n",
+    "\n",
+    "This notebook is not intended to instruct you how to use `plotly.py`.  Instead it pulls together interesting examples from the `plotly.py` documentation into a single notebook to give you a taster of what can be done with `plotly.py`.\n",
+    "\n",
+    "## Install `plotly.py`\n",
+    "\n",
+    "`plotly` is not installed in the `fslpython` environment so you will need to install it to run this notebook. In a terminal run the following command (you will need admin privileges):\n",
+    "\n",
+    "```\n",
+    "sudo $FSLDIR/fslpython/bin/conda install -c conda-forge -n fslpython plotly\n",
+    "```\n",
+    "\n",
+    "## Line & Scatter Plots\n",
+    "\n",
+    "https://plotly.com/python/line-and-scatter/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objects as go\n",
+    "\n",
+    "# Create random data with numpy\n",
+    "import numpy as np\n",
+    "np.random.seed(1)\n",
+    "\n",
+    "N = 100\n",
+    "random_x = np.linspace(0, 1, N)\n",
+    "random_y0 = np.random.randn(N) + 5\n",
+    "random_y1 = np.random.randn(N)\n",
+    "random_y2 = np.random.randn(N) - 5\n",
+    "\n",
+    "fig = go.Figure()\n",
+    "\n",
+    "# Add traces\n",
+    "fig.add_trace(go.Scatter(x=random_x, y=random_y0,\n",
+    "                    mode='markers',\n",
+    "                    name='markers'))\n",
+    "fig.add_trace(go.Scatter(x=random_x, y=random_y1,\n",
+    "                    mode='lines+markers',\n",
+    "                    name='lines+markers'))\n",
+    "fig.add_trace(go.Scatter(x=random_x, y=random_y2,\n",
+    "                    mode='lines',\n",
+    "                    name='lines'))\n",
+    "\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Bar Charts\n",
+    "https://plotly.com/python/bar-charts/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objects as go\n",
+    "\n",
+    "months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n",
+    "          'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\n",
+    "\n",
+    "fig = go.Figure()\n",
+    "fig.add_trace(go.Bar(\n",
+    "    x=months,\n",
+    "    y=[20, 14, 25, 16, 18, 22, 19, 15, 12, 16, 14, 17],\n",
+    "    name='Primary Product',\n",
+    "    marker_color='indianred'\n",
+    "))\n",
+    "fig.add_trace(go.Bar(\n",
+    "    x=months,\n",
+    "    y=[19, 14, 22, 14, 16, 19, 15, 14, 10, 12, 12, 16],\n",
+    "    name='Secondary Product',\n",
+    "    marker_color='lightsalmon'\n",
+    "))\n",
+    "\n",
+    "# Here we modify the tickangle of the xaxis, resulting in rotated labels.\n",
+    "fig.update_layout(barmode='group', xaxis_tickangle=-45)\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Box Plots\n",
+    "https://plotly.com/python/box-plots/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.express as px\n",
+    "\n",
+    "df = px.data.tips()\n",
+    "\n",
+    "fig = px.box(df, x=\"day\", y=\"total_bill\", color=\"smoker\")\n",
+    "fig.update_traces(quartilemethod=\"exclusive\") # or \"inclusive\", or \"linear\" by default\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Distribution Plots\n",
+    "https://plotly.com/python/distplot/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.figure_factory as ff\n",
+    "import numpy as np\n",
+    "\n",
+    "# Add histogram data\n",
+    "x1 = np.random.randn(200) - 2\n",
+    "x2 = np.random.randn(200)\n",
+    "x3 = np.random.randn(200) + 2\n",
+    "x4 = np.random.randn(200) + 4\n",
+    "\n",
+    "# Group data together\n",
+    "hist_data = [x1, x2, x3, x4]\n",
+    "\n",
+    "group_labels = ['Group 1', 'Group 2', 'Group 3', 'Group 4']\n",
+    "\n",
+    "# Create distplot with custom bin_size\n",
+    "fig = ff.create_distplot(hist_data, group_labels, bin_size=.2)\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Violin Plots\n",
+    "https://plotly.com/python/violin/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objects as go\n",
+    "\n",
+    "import pandas as pd\n",
+    "\n",
+    "df = pd.read_csv(\"https://raw.githubusercontent.com/plotly/datasets/master/violin_data.csv\")\n",
+    "\n",
+    "fig = go.Figure()\n",
+    "\n",
+    "days = ['Thur', 'Fri', 'Sat', 'Sun']\n",
+    "\n",
+    "for day in days:\n",
+    "    fig.add_trace(go.Violin(x=df['day'][df['day'] == day],\n",
+    "                            y=df['total_bill'][df['day'] == day],\n",
+    "                            name=day,\n",
+    "                            box_visible=True,\n",
+    "                            meanline_visible=True))\n",
+    "\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Dendrogram with Heatmap\n",
+    "https://plotly.com/python/dendrogram/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objects as go\n",
+    "import plotly.figure_factory as ff\n",
+    "\n",
+    "import numpy as np\n",
+    "from scipy.spatial.distance import pdist, squareform\n",
+    "\n",
+    "\n",
+    "# get data\n",
+    "data = np.genfromtxt(\"http://files.figshare.com/2133304/ExpRawData_E_TABM_84_A_AFFY_44.tab\",\n",
+    "                     names=True,usecols=tuple(range(1,30)),dtype=float, delimiter=\"\\t\")\n",
+    "data_array = data.view((float, len(data.dtype.names)))\n",
+    "data_array = data_array.transpose()\n",
+    "labels = data.dtype.names\n",
+    "\n",
+    "# Initialize figure by creating upper dendrogram\n",
+    "fig = ff.create_dendrogram(data_array, orientation='bottom', labels=labels)\n",
+    "for i in range(len(fig['data'])):\n",
+    "    fig['data'][i]['yaxis'] = 'y2'\n",
+    "\n",
+    "# Create Side Dendrogram\n",
+    "dendro_side = ff.create_dendrogram(data_array, orientation='right')\n",
+    "for i in range(len(dendro_side['data'])):\n",
+    "    dendro_side['data'][i]['xaxis'] = 'x2'\n",
+    "\n",
+    "# Add Side Dendrogram Data to Figure\n",
+    "for data in dendro_side['data']:\n",
+    "    fig.add_trace(data)\n",
+    "\n",
+    "# Create Heatmap\n",
+    "dendro_leaves = dendro_side['layout']['yaxis']['ticktext']\n",
+    "dendro_leaves = list(map(int, dendro_leaves))\n",
+    "data_dist = pdist(data_array)\n",
+    "heat_data = squareform(data_dist)\n",
+    "heat_data = heat_data[dendro_leaves,:]\n",
+    "heat_data = heat_data[:,dendro_leaves]\n",
+    "\n",
+    "heatmap = [\n",
+    "    go.Heatmap(\n",
+    "        x = dendro_leaves,\n",
+    "        y = dendro_leaves,\n",
+    "        z = heat_data,\n",
+    "        colorscale = 'Blues'\n",
+    "    )\n",
+    "]\n",
+    "\n",
+    "heatmap[0]['x'] = fig['layout']['xaxis']['tickvals']\n",
+    "heatmap[0]['y'] = dendro_side['layout']['yaxis']['tickvals']\n",
+    "\n",
+    "# Add Heatmap Data to Figure\n",
+    "for data in heatmap:\n",
+    "    fig.add_trace(data)\n",
+    "\n",
+    "# Edit Layout\n",
+    "fig.update_layout({'width':800, 'height':800,\n",
+    "                         'showlegend':False, 'hovermode': 'closest',\n",
+    "                         })\n",
+    "# Edit xaxis\n",
+    "fig.update_layout(xaxis={'domain': [.15, 1],\n",
+    "                                  'mirror': False,\n",
+    "                                  'showgrid': False,\n",
+    "                                  'showline': False,\n",
+    "                                  'zeroline': False,\n",
+    "                                  'ticks':\"\"})\n",
+    "# Edit xaxis2\n",
+    "fig.update_layout(xaxis2={'domain': [0, .15],\n",
+    "                                   'mirror': False,\n",
+    "                                   'showgrid': False,\n",
+    "                                   'showline': False,\n",
+    "                                   'zeroline': False,\n",
+    "                                   'showticklabels': False,\n",
+    "                                   'ticks':\"\"})\n",
+    "\n",
+    "# Edit yaxis\n",
+    "fig.update_layout(yaxis={'domain': [0, .85],\n",
+    "                                  'mirror': False,\n",
+    "                                  'showgrid': False,\n",
+    "                                  'showline': False,\n",
+    "                                  'zeroline': False,\n",
+    "                                  'showticklabels': False,\n",
+    "                                  'ticks': \"\"\n",
+    "                        })\n",
+    "# Edit yaxis2\n",
+    "fig.update_layout(yaxis2={'domain':[.825, .975],\n",
+    "                                   'mirror': False,\n",
+    "                                   'showgrid': False,\n",
+    "                                   'showline': False,\n",
+    "                                   'zeroline': False,\n",
+    "                                   'showticklabels': False,\n",
+    "                                   'ticks':\"\"})\n",
+    "\n",
+    "# Plot!\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Network Graph\n",
+    "https://plotly.com/python/network-graphs/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objects as go\n",
+    "\n",
+    "import networkx as nx\n",
+    "\n",
+    "G = nx.random_geometric_graph(200, 0.125)\n",
+    "\n",
+    "edge_x = []\n",
+    "edge_y = []\n",
+    "for edge in G.edges():\n",
+    "    x0, y0 = G.nodes[edge[0]]['pos']\n",
+    "    x1, y1 = G.nodes[edge[1]]['pos']\n",
+    "    edge_x.append(x0)\n",
+    "    edge_x.append(x1)\n",
+    "    edge_x.append(None)\n",
+    "    edge_y.append(y0)\n",
+    "    edge_y.append(y1)\n",
+    "    edge_y.append(None)\n",
+    "\n",
+    "edge_trace = go.Scatter(\n",
+    "    x=edge_x, y=edge_y,\n",
+    "    line=dict(width=0.5, color='#888'),\n",
+    "    hoverinfo='none',\n",
+    "    mode='lines')\n",
+    "\n",
+    "node_x = []\n",
+    "node_y = []\n",
+    "for node in G.nodes():\n",
+    "    x, y = G.nodes[node]['pos']\n",
+    "    node_x.append(x)\n",
+    "    node_y.append(y)\n",
+    "\n",
+    "node_trace = go.Scatter(\n",
+    "    x=node_x, y=node_y,\n",
+    "    mode='markers',\n",
+    "    hoverinfo='text',\n",
+    "    marker=dict(\n",
+    "        showscale=True,\n",
+    "        # colorscale options\n",
+    "        #'Greys' | 'YlGnBu' | 'Greens' | 'YlOrRd' | 'Bluered' | 'RdBu' |\n",
+    "        #'Reds' | 'Blues' | 'Picnic' | 'Rainbow' | 'Portland' | 'Jet' |\n",
+    "        #'Hot' | 'Blackbody' | 'Earth' | 'Electric' | 'Viridis' |\n",
+    "        colorscale='YlGnBu',\n",
+    "        reversescale=True,\n",
+    "        color=[],\n",
+    "        size=10,\n",
+    "        colorbar=dict(\n",
+    "            thickness=15,\n",
+    "            title='Node Connections',\n",
+    "            xanchor='left',\n",
+    "            titleside='right'\n",
+    "        ),\n",
+    "        line_width=2))\n",
+    "\n",
+    "node_adjacencies = []\n",
+    "node_text = []\n",
+    "for node, adjacencies in enumerate(G.adjacency()):\n",
+    "    node_adjacencies.append(len(adjacencies[1]))\n",
+    "    node_text.append('# of connections: '+str(len(adjacencies[1])))\n",
+    "\n",
+    "node_trace.marker.color = node_adjacencies\n",
+    "node_trace.text = node_text\n",
+    "\n",
+    "fig = go.Figure(data=[edge_trace, node_trace],\n",
+    "             layout=go.Layout(\n",
+    "                titlefont_size=16,\n",
+    "                showlegend=False,\n",
+    "                hovermode='closest',\n",
+    "                margin=dict(b=20,l=5,r=5,t=40),\n",
+    "                xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),\n",
+    "                yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))\n",
+    "                )\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Custom Controls: Sliders\n",
+    "\n",
+    "https://plotly.com/python/sliders/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objects as go\n",
+    "import numpy as np\n",
+    "\n",
+    "# Create figure\n",
+    "fig = go.Figure()\n",
+    "\n",
+    "# Add traces, one for each slider step\n",
+    "for step in np.arange(0, 5, 0.1):\n",
+    "    fig.add_trace(\n",
+    "        go.Scatter(\n",
+    "            visible=False,\n",
+    "            line=dict(color=\"#00CED1\", width=6),\n",
+    "            name=\"𝜈 = \" + str(step),\n",
+    "            x=np.arange(0, 10, 0.01),\n",
+    "            y=np.sin(step * np.arange(0, 10, 0.01))))\n",
+    "\n",
+    "# Make 10th trace visible\n",
+    "fig.data[10].visible = True\n",
+    "\n",
+    "# Create and add slider\n",
+    "steps = []\n",
+    "for i in range(len(fig.data)):\n",
+    "    step = dict(\n",
+    "        method=\"update\",\n",
+    "        args=[{\"visible\": [False] * len(fig.data)},\n",
+    "              {\"title\": \"Slider switched to step: \" + str(i)}],  # layout attribute\n",
+    "    )\n",
+    "    step[\"args\"][0][\"visible\"][i] = True  # Toggle i'th trace to \"visible\"\n",
+    "    steps.append(step)\n",
+    "\n",
+    "sliders = [dict(\n",
+    "    active=10,\n",
+    "    currentvalue={\"prefix\": \"Frequency: \"},\n",
+    "    pad={\"t\": 50},\n",
+    "    steps=steps\n",
+    ")]\n",
+    "\n",
+    "fig.update_layout(\n",
+    "    sliders=sliders\n",
+    ")\n",
+    "\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Custom Controls: Dropdown Menus\n",
+    "\n",
+    "https://plotly.com/python/dropdowns/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objects as go\n",
+    "\n",
+    "import pandas as pd\n",
+    "\n",
+    "# load dataset\n",
+    "df = pd.read_csv(\"https://raw.githubusercontent.com/plotly/datasets/master/volcano.csv\")\n",
+    "\n",
+    "# Create figure\n",
+    "fig = go.Figure()\n",
+    "\n",
+    "# Add surface trace\n",
+    "fig.add_trace(go.Heatmap(z=df.values.tolist(), colorscale=\"Viridis\"))\n",
+    "\n",
+    "# Update plot sizing\n",
+    "fig.update_layout(\n",
+    "    width=800,\n",
+    "    height=900,\n",
+    "    autosize=False,\n",
+    "    margin=dict(t=100, b=0, l=0, r=0),\n",
+    ")\n",
+    "\n",
+    "# Update 3D scene options\n",
+    "fig.update_scenes(\n",
+    "    aspectratio=dict(x=1, y=1, z=0.7),\n",
+    "    aspectmode=\"manual\"\n",
+    ")\n",
+    "\n",
+    "# Add dropdowns\n",
+    "button_layer_1_height = 1.08\n",
+    "fig.update_layout(\n",
+    "    updatemenus=[\n",
+    "        dict(\n",
+    "            buttons=list([\n",
+    "                dict(\n",
+    "                    args=[\"colorscale\", \"Viridis\"],\n",
+    "                    label=\"Viridis\",\n",
+    "                    method=\"restyle\"\n",
+    "                ),\n",
+    "                dict(\n",
+    "                    args=[\"colorscale\", \"Cividis\"],\n",
+    "                    label=\"Cividis\",\n",
+    "                    method=\"restyle\"\n",
+    "                ),\n",
+    "                dict(\n",
+    "                    args=[\"colorscale\", \"Blues\"],\n",
+    "                    label=\"Blues\",\n",
+    "                    method=\"restyle\"\n",
+    "                ),\n",
+    "                dict(\n",
+    "                    args=[\"colorscale\", \"Greens\"],\n",
+    "                    label=\"Greens\",\n",
+    "                    method=\"restyle\"\n",
+    "                ),\n",
+    "            ]),\n",
+    "            direction=\"down\",\n",
+    "            pad={\"r\": 10, \"t\": 10},\n",
+    "            showactive=True,\n",
+    "            x=0.1,\n",
+    "            xanchor=\"left\",\n",
+    "            y=button_layer_1_height,\n",
+    "            yanchor=\"top\"\n",
+    "        ),\n",
+    "        dict(\n",
+    "            buttons=list([\n",
+    "                dict(\n",
+    "                    args=[\"reversescale\", False],\n",
+    "                    label=\"False\",\n",
+    "                    method=\"restyle\"\n",
+    "                ),\n",
+    "                dict(\n",
+    "                    args=[\"reversescale\", True],\n",
+    "                    label=\"True\",\n",
+    "                    method=\"restyle\"\n",
+    "                )\n",
+    "            ]),\n",
+    "            direction=\"down\",\n",
+    "            pad={\"r\": 10, \"t\": 10},\n",
+    "            showactive=True,\n",
+    "            x=0.37,\n",
+    "            xanchor=\"left\",\n",
+    "            y=button_layer_1_height,\n",
+    "            yanchor=\"top\"\n",
+    "        ),\n",
+    "        dict(\n",
+    "            buttons=list([\n",
+    "                dict(\n",
+    "                    args=[{\"contours.showlines\": False, \"type\": \"contour\"}],\n",
+    "                    label=\"Hide lines\",\n",
+    "                    method=\"restyle\"\n",
+    "                ),\n",
+    "                dict(\n",
+    "                    args=[{\"contours.showlines\": True, \"type\": \"contour\"}],\n",
+    "                    label=\"Show lines\",\n",
+    "                    method=\"restyle\"\n",
+    "                ),\n",
+    "            ]),\n",
+    "            direction=\"down\",\n",
+    "            pad={\"r\": 10, \"t\": 10},\n",
+    "            showactive=True,\n",
+    "            x=0.58,\n",
+    "            xanchor=\"left\",\n",
+    "            y=button_layer_1_height,\n",
+    "            yanchor=\"top\"\n",
+    "        ),\n",
+    "    ]\n",
+    ")\n",
+    "\n",
+    "fig.update_layout(\n",
+    "    annotations=[\n",
+    "        dict(text=\"colorscale\", x=0, xref=\"paper\", y=1.06, yref=\"paper\",\n",
+    "                             align=\"left\", showarrow=False),\n",
+    "        dict(text=\"Reverse<br>Colorscale\", x=0.25, xref=\"paper\", y=1.07,\n",
+    "                             yref=\"paper\", showarrow=False),\n",
+    "        dict(text=\"Lines\", x=0.54, xref=\"paper\", y=1.06, yref=\"paper\",\n",
+    "                             showarrow=False)\n",
+    "    ])\n",
+    "\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
-- 
GitLab