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