Skip to content

Instantly share code, notes, and snippets.

@thoughtsociety
Last active April 10, 2019 21:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thoughtsociety/70d00d2890259d4f24d52a4ebece9d13 to your computer and use it in GitHub Desktop.
Save thoughtsociety/70d00d2890259d4f24d52a4ebece9d13 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![My Logo](https://thoughtsociety.org/wp-content/uploads/2019/03/ts_notebook_header.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Segment 4 - 3D"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Several of the examples used in this notebook were borrowed from Plot.ly tutorials and references\n",
"\n",
">***Many thanks to the work done by the Plot.ly team to open source all of these examples.***"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot.ly Gym for 3D\n",
"\n",
"Undoubtedly, 3D holds some fascination for many of us and it can be said that there are myriad ways to render 3D from data other than just Plotly. Much of the challenge in visualizing something in 3D is in the nature, shape and context of your data.\n",
"\n",
"Not everything lends itself well to a 3D rendition. There are ways to show tabular data with 3D viewpoints and manipulations that make it worth doing even if the data iself does not represent something in 3D. \n",
"\n",
"Making use of attributes for size and color in order to differentiate similar data is very powerful when rendered in three space. This is a pretty extensive Gym in that Plotly have covered a lot of use-cases with their API and it will be a great addition to our toolbox once we learn how to do it."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### This gym covers:\n",
"\n",
"* 3D Scatter Plots\n",
"* 3D Bubble Charts\n",
"* 3D Line Plots\n",
"* 3D Filled Line Plots\n",
"* 3D Surface Plots\n",
"* 3D Mesh Plots\n",
"* 3D Wireframe Plots\n",
"* Parametric Plots\n",
"* Trisurf Plots\n",
"* Iso Surface\n",
"* 3d Network Graphs\n",
"* 3D Clustering with Alpha Shapes\n",
"* Projection of 3D Surface\n",
"* 3D Cone Plots\n",
"* 3D Streamtube Plots\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plotly 3D Concepts\n",
"\n",
"In plotly, three plot types are used to accomplish 3d. \n",
"\n",
"1. Scatter3d\n",
"2. Surface\n",
"3. Mesh3d\n",
"\n",
"However, there can be lots of flexibility attained as a result of the attributes given.\n",
"\n",
"**Iso Surfaces like Trisurf** are done with figure_factory (ff).\n",
"x,y and z as well as a colormap are applied to achieve a nice looking iso surfaced object that you can rotate with the mouse. \n",
"\n",
"**Basic parametric plots** can be achieved with go.Surface(x,y,z)\n",
"Making use of np.meshgrid() can generate elegant looking objects as we will see in the demos.\n",
"\n",
"**Scatter3d** is used just at Scatter(2d) where you can setup multiple traces and combine them in a single 3d plot. It uses data, layout and the iplot() call as before. These can have colorscaling added as in the 2d use-case.\n",
"\n",
"**3D Network Graphs** are very useful and interesting when you have hover-text associated with the nodes.\n",
"The demo uses urllib3 and json_loads to fetch a dataset from github that includes the node topology and hover-text information. This visualization is about \"Network of coappearances of characters in Victor Hugo's novel 'Les Miserables'\"\n",
"\n",
"**Projection of 3D Surface Onto Planes**\n",
"\n",
"A more sophisticated method that allows one to color a 3d surface with their own custom color function improving on the limitation of having to use a z-normalized range of colormapping.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Check plotly version\n",
"import plotly\n",
"plotly.__version__"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import plotly.plotly as py\n",
"import plotly.graph_objs as go\n",
"import plotly.figure_factory as ff\n",
"import numpy as np\n",
"from skimage import measure\n",
"import pandas as pd\n",
"import seaborn as sns\n",
"from datetime import datetime"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# For ignoring warnings\n",
"import warnings\n",
"warnings.filterwarnings('ignore')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from plotly.offline import init_notebook_mode, iplot\n",
"plotly.offline.init_notebook_mode(connected=True) # initiate notebook for offline plot"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Scatter Plots\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x, y, z = np.random.multivariate_normal(np.array([0,0,0]), np.eye(3), 200).transpose()\n",
"trace1 = go.Scatter3d(\n",
" x=x,\n",
" y=y,\n",
" z=z,\n",
" mode='markers',\n",
" marker=dict(\n",
" size=12,\n",
" line=dict(\n",
" color='rgba(217, 217, 217, 0.14)',\n",
" width=0.5\n",
" ),\n",
" opacity=0.8\n",
" )\n",
")\n",
"\n",
"x2, y2, z2 = np.random.multivariate_normal(np.array([0,0,0]), np.eye(3), 200).transpose()\n",
"trace2 = go.Scatter3d(\n",
" x=x2,\n",
" y=y2,\n",
" z=z2,\n",
" mode='markers',\n",
" marker=dict(\n",
" color='rgb(127, 127, 127)',\n",
" size=12,\n",
" symbol='circle',\n",
" line=dict(\n",
" color='rgb(204, 204, 204)',\n",
" width=1\n",
" ),\n",
" opacity=0.9\n",
" )\n",
")\n",
"data = [trace1, trace2]\n",
"layout = go.Layout(\n",
" margin=dict(\n",
" l=0,\n",
" r=0,\n",
" b=0,\n",
" t=0\n",
" )\n",
")\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 3D Scatter Plot with Colorscaling\n",
"\n",
"x, y, z = np.random.multivariate_normal(np.array([0,0,0]), np.eye(3), 400).transpose()\n",
"\n",
"trace1 = go.Scatter3d(\n",
" x=x,\n",
" y=y,\n",
" z=z,\n",
" mode='markers',\n",
" marker=dict(\n",
" size=12,\n",
" color=z, # set color to an array/list of desired values\n",
" colorscale='Viridis', # choose a colorscale\n",
" opacity=0.8\n",
" )\n",
")\n",
"\n",
"data = [trace1]\n",
"layout = go.Layout(\n",
" margin=dict(\n",
" l=0,\n",
" r=0,\n",
" b=0,\n",
" t=0\n",
" )\n",
")\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Bubble Charts\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Simple Bubble Chart\n",
"\n",
"df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')\n",
"\n",
"trace1 = go.Scatter3d(\n",
" x=df['year'][750:1500],\n",
" y=df['continent'][750:1500],\n",
" z=df['pop'][750:1500],\n",
" text=df['country'][750:1500],\n",
" mode='markers',\n",
" marker=dict(\n",
" sizemode='diameter',\n",
" sizeref=750,\n",
" size=df['gdpPercap'][750:1500],\n",
" color = df['lifeExp'][750:1500],\n",
" colorscale = 'Viridis',\n",
" colorbar = dict(title = 'Life<br>Expectancy'),\n",
" line=dict(color='rgb(140, 140, 170)')\n",
" )\n",
")\n",
"\n",
"data=[trace1]\n",
"\n",
"layout=go.Layout(height=800, width=800, title='Examining Population and Life Expectancy Over Time')\n",
"\n",
"fig=go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Line Plots\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 3D Line Plot of Brownian Motion\n",
"\n",
"df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/iris.csv')\n",
"df.head()\n",
"\n",
"def brownian_motion(T = 1, N = 100, mu = 0.1, sigma = 0.01, S0 = 20):\n",
" dt = float(T)/N\n",
" t = np.linspace(0, T, N)\n",
" W = np.random.standard_normal(size = N)\n",
" W = np.cumsum(W)*np.sqrt(dt) # standard brownian motion\n",
" X = (mu-0.5*sigma**2)*t + sigma*W\n",
" S = S0*np.exp(X) # geometric brownian motion\n",
" return S\n",
"\n",
"dates = pd.date_range('2012-01-01', '2013-02-22')\n",
"T = (dates.max()-dates.min()).days / 365\n",
"N = dates.size\n",
"start_price = 100\n",
"y = pd.Series(\n",
" brownian_motion(T, N, sigma=0.1, S0=start_price), index=dates)\n",
"z = pd.Series(\n",
" brownian_motion(T, N, sigma=0.1, S0=start_price), index=dates)\n",
"\n",
"trace = go.Scatter3d(\n",
" x=list(dates), y=y, z=z,\n",
" marker=dict(\n",
" size=4,\n",
" color=z,\n",
" colorscale='Viridis',\n",
" ),\n",
" line=dict(\n",
" color='#1f77b4',\n",
" width=1\n",
" )\n",
")\n",
"\n",
"data = [trace]\n",
"\n",
"layout = dict(\n",
" width=800,\n",
" height=700,\n",
" autosize=False,\n",
" title='Iris dataset',\n",
" scene=dict(\n",
" xaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" yaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" zaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" camera=dict(\n",
" up=dict(\n",
" x=0,\n",
" y=0,\n",
" z=1\n",
" ),\n",
" eye=dict(\n",
" x=-1.7428,\n",
" y=1.0707,\n",
" z=0.7100,\n",
" )\n",
" ),\n",
" aspectratio = dict( x=1, y=1, z=0.7 ),\n",
" aspectmode = 'manual'\n",
" ),\n",
")\n",
"\n",
"fig = dict(data=data, layout=layout)\n",
"\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Filled Line Plots\n",
"\n",
"Taking part of the gapminder dataset limited to 5 countries, China, India, U.S., Bangladesj and South Africa.\n",
"Group by country and then population, \n",
"\n",
"* run a scatter3d\n",
"* Focus on surfaces\n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Basic Filled Line Plot\n",
"\n",
"# The datasets' url. Thanks Jennifer Bryan!\n",
"url_csv = 'http://www.stat.ubc.ca/~jenny/notOcto/STAT545A/examples/gapminder/data/gapminderDataFiveYear.txt'\n",
"\n",
"df = pd.read_csv(url_csv, sep='\\t')\n",
"# df.head()\n",
"\n",
"countries = ['China', 'India', 'United States', 'Bangladesh', 'South Africa']\n",
"fill_colors = ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854']\n",
"gf = df.groupby('country')\n",
"\n",
"data = []\n",
"\n",
"for country, fill_color in zip(countries[::-1], fill_colors):\n",
" group = gf.get_group(country)\n",
" years = group['year'].tolist()\n",
" length = len(years)\n",
" country_coords = [country] * length\n",
" pop = group['pop'].tolist()\n",
" zeros = [0] * length\n",
" \n",
" data.append(dict(\n",
" type='scatter3d',\n",
" mode='lines',\n",
" x=years + years[::-1] + [years[0]], # year loop: in incr. order then in decr. order then years[0]\n",
" y=country_coords * 2 + [country_coords[0]],\n",
" z=pop + zeros + [pop[0]],\n",
" name='',\n",
" surfaceaxis=1, # add a surface axis ('1' refers to axes[1] i.e. the y-axis)\n",
" surfacecolor=fill_color,\n",
" line=dict(\n",
" color='black',\n",
" width=4\n",
" ),\n",
" ))\n",
"\n",
"layout = dict(\n",
" title='Population from 1957 to 2007 [Gapminder]',\n",
" showlegend=False,\n",
" scene=dict(\n",
" xaxis=dict(title=''),\n",
" yaxis=dict(title=''),\n",
" zaxis=dict(title=''),\n",
" camera=dict(\n",
" eye=dict(x=-1.7, y=-1.7, z=0.5)\n",
" )\n",
" )\n",
")\n",
"\n",
"fig = dict(data=data, layout=layout)\n",
"\n",
"# IPython notebook\n",
"# py.iplot(fig, filename='filled-3d-lines')\n",
"\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Surface Plots in Python\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Topographical 3D Surface Plo\n",
"\n",
"# Read data from a csv\n",
"z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')\n",
"\n",
"data = [\n",
" go.Surface(\n",
" z=z_data.as_matrix()\n",
" )\n",
"]\n",
"layout = go.Layout(\n",
" title='Mt Bruno Elevation',\n",
" autosize=False,\n",
" width=500,\n",
" height=500,\n",
" margin=dict(\n",
" l=65,\n",
" r=50,\n",
" b=65,\n",
" t=90\n",
" )\n",
")\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Surface Plot With Contours¶\n",
"\n",
"z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')\n",
"\n",
"data = [\n",
" go.Surface(\n",
" z=z_data.as_matrix(),\n",
" contours=go.surface.Contours(\n",
" z=go.surface.contours.Z(\n",
" show=True,\n",
" usecolormap=True,\n",
" highlightcolor=\"#42f462\",\n",
" project=dict(z=True)\n",
" )\n",
" )\n",
" )\n",
"]\n",
"layout = go.Layout(\n",
" title='Mt Bruno Elevation',\n",
" autosize=False,\n",
" scene=dict(camera=dict(eye=dict(x=1.87, y=0.88, z=-0.64))),\n",
" width=500,\n",
" height=500,\n",
" margin=dict(\n",
" l=65,\n",
" r=50,\n",
" b=65,\n",
" t=90\n",
" )\n",
")\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Multiple 3D Surface Plots¶\n",
"\n",
"z1 = [\n",
" [8.83,8.89,8.81,8.87,8.9,8.87],\n",
" [8.89,8.94,8.85,8.94,8.96,8.92],\n",
" [8.84,8.9,8.82,8.92,8.93,8.91],\n",
" [8.79,8.85,8.79,8.9,8.94,8.92],\n",
" [8.79,8.88,8.81,8.9,8.95,8.92],\n",
" [8.8,8.82,8.78,8.91,8.94,8.92],\n",
" [8.75,8.78,8.77,8.91,8.95,8.92],\n",
" [8.8,8.8,8.77,8.91,8.95,8.94],\n",
" [8.74,8.81,8.76,8.93,8.98,8.99],\n",
" [8.89,8.99,8.92,9.1,9.13,9.11],\n",
" [8.97,8.97,8.91,9.09,9.11,9.11],\n",
" [9.04,9.08,9.05,9.25,9.28,9.27],\n",
" [9,9.01,9,9.2,9.23,9.2],\n",
" [8.99,8.99,8.98,9.18,9.2,9.19],\n",
" [8.93,8.97,8.97,9.18,9.2,9.18]\n",
"]\n",
"\n",
"z2 = [[zij+1 for zij in zi] for zi in z1]\n",
"z3 = [[zij-1 for zij in zi] for zi in z1]\n",
"\n",
"data = [\n",
" go.Surface(z=z1),\n",
" go.Surface(z=z2, showscale=False, opacity=0.9),\n",
" go.Surface(z=z3, showscale=False, opacity=0.9)\n",
"\n",
"]\n",
"\n",
"iplot(data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Mesh Plots\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Simple 3D Mesh\n",
"\n",
"pts=np.loadtxt('mesh_dataset.txt')\n",
"x,y,z=zip(*pts)\n",
"\n",
"trace = go.Mesh3d(x=x,y=y,z=z,color='#FFB6C1',opacity=0.50)\n",
"trace1 = go.Mesh3d(x=x,y=y,z=z,color='#00cc00',opacity=0.25)\n",
"traces = [trace,trace1]\n",
"iplot(traces)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 3D Mesh example with Alphahull\n",
"\n",
"pts=np.loadtxt('mesh_dataset.txt')\n",
"x,y,z=zip(*pts)\n",
"\n",
"trace = go.Mesh3d(x=x,y=y,z=z,\n",
" alphahull=5,\n",
" opacity=0.4,\n",
" color='#00FFFF')\n",
"iplot([trace])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Mesh Tetrahedron\n",
"\n",
"data = [\n",
" go.Mesh3d(\n",
" x = [0, 1, 2, 0],\n",
" y = [0, 0, 1, 2],\n",
" z = [0, 2, 0, 1],\n",
" colorbar = go.ColorBar(\n",
" title='z'\n",
" ),\n",
" colorscale = [[0, 'rgb(255, 0, 0)'], \n",
" [0.5, 'rgb(0, 255, 0)'], \n",
" [1, 'rgb(0, 0, 255)']],\n",
" intensity = [0, 0.33, 0.66, 1],\n",
" i = [0, 0, 0, 1],\n",
" j = [1, 2, 3, 2],\n",
" k = [2, 3, 1, 3],\n",
" name = 'y',\n",
" showscale = True\n",
" )\n",
"]\n",
"layout = go.Layout(\n",
" xaxis=go.XAxis(\n",
" title='x'\n",
" ),\n",
" yaxis=go.YAxis(\n",
" title='y'\n",
" )\n",
")\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Mesh Cube¶\n",
"\n",
"data = [\n",
" go.Mesh3d(\n",
" x = [0, 0, 1, 1, 0, 0, 1, 1],\n",
" y = [0, 1, 1, 0, 0, 1, 1, 0],\n",
" z = [0, 0, 0, 0, 1, 1, 1, 1],\n",
" colorbar = go.ColorBar(\n",
" title='z'\n",
" ),\n",
" colorscale = [[0, 'rgb(255, 0, 255)'],\n",
" [0.5, 'rgb(0, 255, 0)'], \n",
" [1, 'rgb(0, 0, 255)']],\n",
" intensity = [0, 0.142857142857143, 0.285714285714286, \n",
" 0.428571428571429, 0.571428571428571, \n",
" 0.714285714285714, 0.857142857142857, 1],\n",
" i = [7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2],\n",
" j = [3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3],\n",
" k = [0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6],\n",
" name='y',\n",
" showscale=True\n",
" )\n",
"]\n",
"layout = go.Layout(\n",
" xaxis=go.XAxis(\n",
" title='x'\n",
" ),\n",
" yaxis=go.YAxis(\n",
" title='y'\n",
" )\n",
")\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Wireframe Plots\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Basic Wireframe\n",
"\n",
"# Creating the data\n",
"x = np.linspace(-5, 5, 50)\n",
"y = np.linspace(-5, 5, 50)\n",
"xGrid, yGrid = np.meshgrid(y, x)\n",
"R = np.sqrt(xGrid ** 2 + yGrid ** 2)\n",
"z = np.sin(R)\n",
"\n",
"# Creating the plot\n",
"lines = []\n",
"line_marker = dict(color='#0066FF', width=2)\n",
"for i, j, k in zip(xGrid, yGrid, z):\n",
" lines.append(go.Scatter3d(x=i, y=j, z=k, mode='lines', line=line_marker))\n",
"\n",
"layout = go.Layout(\n",
" title='Wireframe Plot',\n",
" scene=dict(\n",
" xaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" yaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" zaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" )\n",
" ),\n",
" showlegend=False,\n",
")\n",
"fig = go.Figure(data=lines, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Parametric Plots\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Basic Parametric Plot\n",
"\n",
"s = np.linspace(0, 2 * np.pi, 240)\n",
"t = np.linspace(0, np.pi, 240)\n",
"tGrid, sGrid = np.meshgrid(s, t)\n",
"\n",
"r = 2 + np.sin(7 * sGrid + 5 * tGrid) # r = 2 + sin(7s+5t)\n",
"x = r * np.cos(sGrid) * np.sin(tGrid) # x = r*cos(s)*sin(t)\n",
"y = r * np.sin(sGrid) * np.sin(tGrid) # y = r*sin(s)*sin(t)\n",
"z = r * np.cos(tGrid) # z = r*cos(t)\n",
"\n",
"surface = go.Surface(x=x, y=y, z=z)\n",
"data = [surface]\n",
"\n",
"layout = go.Layout(\n",
" title='Parametric Plot',\n",
" scene=dict(\n",
" xaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" yaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" zaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" )\n",
" )\n",
")\n",
"\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Parameteric Plot with Colorscale¶\n",
"\n",
"dphi, dtheta = np.pi / 250.0, np.pi / 250.0\n",
"[phi, theta] = np.mgrid[0:np.pi + dphi * 1.5:dphi, 0:2 * np.pi +\n",
" dtheta * 1.5:dtheta]\n",
"m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4;\n",
"\n",
"# Applying the parametric equation..\n",
"r = (np.sin(m0 * phi) ** m1 + np.cos(m2 * phi) ** m3 +\n",
" np.sin(m4 * theta) ** m5 + np.cos(m6 * theta) ** m7)\n",
"x = r * np.sin(phi) * np.cos(theta)\n",
"y = r * np.cos(phi)\n",
"z = r * np.sin(phi) * np.sin(theta)\n",
"\n",
"\n",
"surface = go.Surface(x=x, y=y, z=z, colorscale='Viridis')\n",
"data = [surface]\n",
"layout = go.Layout(\n",
" title='Another Parametric Plot',\n",
" scene=dict(\n",
" xaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" yaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" ),\n",
" zaxis=dict(\n",
" gridcolor='rgb(255, 255, 255)',\n",
" zerolinecolor='rgb(255, 255, 255)',\n",
" showbackground=True,\n",
" backgroundcolor='rgb(230, 230,230)'\n",
" )\n",
" )\n",
")\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Trisurf Plots\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Torus\n",
"\n",
"from scipy.spatial import Delaunay\n",
"\n",
"u = np.linspace(0, 2*np.pi, 20)\n",
"v = np.linspace(0, 2*np.pi, 20)\n",
"u,v = np.meshgrid(u,v)\n",
"u = u.flatten()\n",
"v = v.flatten()\n",
"\n",
"x = (3 + (np.cos(v)))*np.cos(u)\n",
"y = (3 + (np.cos(v)))*np.sin(u)\n",
"z = np.sin(v)\n",
"\n",
"points2D = np.vstack([u,v]).T\n",
"tri = Delaunay(points2D)\n",
"simplices = tri.simplices\n",
"\n",
"fig1 = ff.create_trisurf(x=x, y=y, z=z,\n",
" simplices=simplices,\n",
" title=\"Torus\", aspectratio=dict(x=1, y=1, z=0.75))\n",
"iplot(fig1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Mobius Band\n",
"\n",
"u = np.linspace(0, 2*np.pi, 24)\n",
"v = np.linspace(-1, 1, 8)\n",
"u,v = np.meshgrid(u,v)\n",
"u = u.flatten()\n",
"v = v.flatten()\n",
"\n",
"tp = 1 + 0.5*v*np.cos(u/2.)\n",
"x = tp*np.cos(u)\n",
"y = tp*np.sin(u)\n",
"z = 0.5*v*np.sin(u/2.)\n",
"\n",
"points2D = np.vstack([u,v]).T\n",
"tri = Delaunay(points2D)\n",
"simplices = tri.simplices\n",
"\n",
"fig1 = ff.create_trisurf(x=x, y=y, z=z,\n",
" colormap=\"Portland\",\n",
" simplices=simplices,\n",
" title=\"Mobius Band\")\n",
"iplot(fig1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Boy's Surface¶\n",
"\n",
"from scipy.spatial import Delaunay\n",
"\n",
"u=np.linspace(-np.pi/2, np.pi/2, 60)\n",
"v=np.linspace(0, np.pi, 60)\n",
"u,v=np.meshgrid(u,v)\n",
"u=u.flatten()\n",
"v=v.flatten()\n",
"\n",
"x = (np.sqrt(2)*(np.cos(v)*np.cos(v))*np.cos(2*u) + np.cos(u)*np.sin(2*v))/(2 - np.sqrt(2)*np.sin(3*u)*np.sin(2*v))\n",
"y = (np.sqrt(2)*(np.cos(v)*np.cos(v))*np.sin(2*u) - np.sin(u)*np.sin(2*v))/(2 - np.sqrt(2)*np.sin(3*u)*np.sin(2*v))\n",
"z = (3*(np.cos(v)*np.cos(v)))/(2 - np.sqrt(2)*np.sin(3*u)*np.sin(2*v))\n",
"\n",
"points2D = np.vstack([u, v]).T\n",
"tri = Delaunay(points2D)\n",
"simplices = tri.simplices\n",
"\n",
"fig1 = ff.create_trisurf(x=x, y=y, z=z,\n",
" colormap=['rgb(50, 0, 75)', 'rgb(200, 0, 200)', '#c8dcc8'],\n",
" show_colorbar=True,\n",
" simplices=simplices,\n",
" title=\"Boy's Surface\")\n",
"iplot(fig1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Change Colorscale Variable\n",
"\n",
"from scipy.spatial import Delaunay\n",
"\n",
"u = np.linspace(0, 2*np.pi, 20)\n",
"v = np.linspace(0, 2*np.pi, 20)\n",
"u,v = np.meshgrid(u,v)\n",
"u = u.flatten()\n",
"v = v.flatten()\n",
"\n",
"x = (3 + (np.cos(v)))*np.cos(u)\n",
"y = (3 + (np.cos(v)))*np.sin(u)\n",
"z = np.sin(v)\n",
"\n",
"points2D = np.vstack([u,v]).T\n",
"tri = Delaunay(points2D)\n",
"simplices = tri.simplices\n",
"\n",
"# define a function that calculates the distance\n",
"# from the origin to use as the color variable\n",
"def dist_origin(x, y, z):\n",
" return np.sqrt((1.0 * x)**2 + (1.0 * y)**2 + (1.0 * z)**2)\n",
"\n",
"fig1 = ff.create_trisurf(x=x, y=y, z=z, color_func=dist_origin,\n",
" colormap = [(0.4, 0.15, 0), (1, 0.65, 0.12)],\n",
" show_colorbar=True,\n",
" simplices=simplices, title=\"Torus - Origin Distance Coloring\",\n",
" aspectratio=dict(x=1, y=1, z=0.3))\n",
"iplot(fig1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Diverging Colormap\n",
"\n",
"from scipy.spatial import Delaunay\n",
"\n",
"u = np.linspace(-np.pi, np.pi, 30)\n",
"v = np.linspace(-np.pi, np.pi, 30)\n",
"u, v = np.meshgrid(u,v)\n",
"u = u.flatten()\n",
"v = v.flatten()\n",
"\n",
"x = u\n",
"y = u*np.cos(v)\n",
"z = u*np.sin(v)\n",
"\n",
"points2D = np.vstack([u,v]).T\n",
"tri = Delaunay(points2D)\n",
"simplices = tri.simplices\n",
"\n",
"# define a function for the color assignment\n",
"def dist_from_x_axis(x, y, z):\n",
" return x\n",
"\n",
"fig1 = ff.create_trisurf(x=x, y=y, z=z,\n",
" colormap=['rgb(153, 0, 153)', 'rgb(102, 255, 255)', ],\n",
" show_colorbar=True,\n",
" simplices=simplices, title=\"Light Cone\",\n",
" showbackground=False, gridcolor='rgb(255, 20, 160)',\n",
" plot_edges=False, aspectratio=dict(x=1, y=1, z=0.75))\n",
"iplot(fig1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Iso Surface in Python\n",
"\n",
"In this first basic example of U.S. states choropleth maps, here is what is happening:\n",
"\n",
"* Read in the 2011 us exports csv file\n",
"* Create a list of colors for the colorscale\n",
"* Create the hover text by bringing in state,beef,dairy, etc. with values as a text string\n",
"* Build the data object using go.Choropleth and setting attributes accordingly\n",
"* Build the layout object by calling go.Layout with attributes and an Albers projection\n",
"`Albers is a conic, equal area map projection that uses two standard parallels`\n",
" \n",
"* instantiate the figure by go.figure with data and layout\n",
"* iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"import numpy as np\n",
"\n",
"\n",
"X,Y,Z = np.mgrid[-2:2:40j, -2:2:40j, -2:2:40j]\n",
"surf_eq = X**4 + Y**4 + Z**4 - (X**2+Y**2+Z**2)**2 + 3*(X**2+Y**2+Z**2) - 3 \n",
"\n",
"vertices, simplices = measure.marching_cubes_classic(surf_eq, 0)\n",
"x,y,z = zip(*vertices) \n",
"\n",
"\n",
"\n",
"\n",
"colormap=['rgb(255,105,180)','rgb(255,255,51)','rgb(0,191,255)']\n",
"fig = ff.create_trisurf(x=x,\n",
" y=y, \n",
" z=z, \n",
" plot_edges=False,\n",
" colormap=colormap,\n",
" simplices=simplices,\n",
" title=\"Isosurface\")\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Network Mapping\n",
"\n",
"**3D Network Graphs** are very useful and interesting when you have hover-text associated with the nodes.\n",
"The demo uses urllib3 and json_loads to fetch a dataset from github that includes the node topology and hover-text information. This visualization is about \"Network of coappearances of characters in Victor Hugo's novel 'Les Miserables'\"\n",
"\n",
"This example has several stages which we can follow -\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 1. Make a request to fetch a json file with our data\n",
"# perform a json.loads to get the data into a list\n",
"\n",
"import igraph as ig\n",
"import json\n",
"import urllib3\n",
"\n",
"\n",
"http = urllib3.PoolManager()\n",
"url = \"https://raw.githubusercontent.com/plotly/datasets/master/miserables.json\"\n",
"\n",
"response = http.request('GET',url)\n",
"data = json.loads(response.data.decode('utf-8'))\n",
"\n",
"# # req = urllib3.get(\"https://raw.githubusercontent.com/plotly/datasets/master/miserables.json\")\n",
"# opener = urllib3.build_opener()\n",
"# f = opener.open(req)\n",
"# data = json.loads(f.read())\n",
"\n",
"# print (data.keys)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 2. figure out length of data['nodes']\n",
"\n",
"N = len(data['nodes'])\n",
"N"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 3. Figure out length of data['links'] \n",
"# 4. build Edges for as many links there are and iterate from json data for source & target\n",
"\n",
"L=len(data['links'])\n",
"Edges=[(data['links'][k]['source'], data['links'][k]['target']) for k in range(L)]\n",
"\n",
"# instantiate G.ig.Graph() from igraph.Graph\n",
"\n",
"G=ig.Graph(Edges, directed=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 5. Extract the node attributes, 'group', and 'name': \n",
"data['nodes'][0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 6. append to labels and groups - name and group info\n",
"\n",
"labels=[]\n",
"group=[]\n",
"for node in data['nodes']:\n",
" labels.append(node['name'])\n",
" group.append(node['group'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 7. Get the node positions, set by the Kamada-Kawai layout for 3D graphs:\n",
"layt=G.layout('kk', dim=3) "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# layt is a list of three elements lists (the coordinates of nodes):\n",
"layt[5]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 8. Set data for the Plotly plot of the graph:\n",
"\n",
"Xn=[layt[k][0] for k in range(N)]# x-coordinates of nodes\n",
"Yn=[layt[k][1] for k in range(N)]# y-coordinates\n",
"Zn=[layt[k][2] for k in range(N)]# z-coordinates\n",
"Xe=[]\n",
"Ye=[]\n",
"Ze=[]\n",
"for e in Edges:\n",
" Xe+=[layt[e[0]][0],layt[e[1]][0], None]# x-coordinates of edge ends\n",
" Ye+=[layt[e[0]][1],layt[e[1]][1], None] \n",
" Ze+=[layt[e[0]][2],layt[e[1]][2], None] "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 9. Setup the traces\n",
"trace1=go.Scatter3d(x=Xe,\n",
" y=Ye,\n",
" z=Ze,\n",
" mode='lines',\n",
" line=dict(color='rgb(125,125,125)', width=1),\n",
" hoverinfo='none'\n",
" )\n",
"\n",
"trace2=go.Scatter3d(x=Xn,\n",
" y=Yn,\n",
" z=Zn,\n",
" mode='markers',\n",
" name='actors',\n",
" marker=dict(symbol='circle',\n",
" size=6,\n",
" color=group,\n",
" colorscale='Viridis',\n",
" line=dict(color='rgb(50,50,50)', width=0.5)\n",
" ),\n",
" text=labels,\n",
" hoverinfo='text'\n",
" )\n",
"\n",
"axis=dict(showbackground=False,\n",
" showline=False,\n",
" zeroline=False,\n",
" showgrid=False,\n",
" showticklabels=False,\n",
" title=''\n",
" )\n",
"\n",
"layout = go.Layout(\n",
" title=\"Network of coappearances of characters in Victor Hugo's novel<br> Les Miserables (3D visualization)\",\n",
" width=1000,\n",
" height=1000,\n",
" showlegend=False,\n",
" scene=dict(\n",
" xaxis=dict(axis),\n",
" yaxis=dict(axis),\n",
" zaxis=dict(axis),\n",
" ),\n",
" margin=dict(\n",
" t=100\n",
" ),\n",
" hovermode='closest',\n",
" annotations=[\n",
" dict(\n",
" showarrow=False,\n",
" text=\"Data source: <a href='http://bost.ocks.org/mike/miserables/miserables.json'>[1] miserables.json</a>\",\n",
" xref='paper',\n",
" yref='paper',\n",
" x=0,\n",
" y=0.1,\n",
" xanchor='left',\n",
" yanchor='bottom',\n",
" font=dict(\n",
" size=14\n",
" )\n",
" )\n",
" ], )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 10. Plot it\n",
"\n",
"data=[trace1, trace2]\n",
"fig=go.Figure(data=data, layout=layout)\n",
"\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Clustering with Alpha Shapes\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/alpha_shape.csv')\n",
"df.head()\n",
"\n",
"scatter = dict(\n",
" mode = \"markers\",\n",
" name = \"y\",\n",
" type = \"scatter3d\", \n",
" x = df['x'], y = df['y'], z = df['z'],\n",
" marker = dict( size=2, color=\"rgb(23, 190, 207)\" )\n",
")\n",
"clusters = dict(\n",
" alphahull = 7,\n",
" name = \"y\",\n",
" opacity = 0.1,\n",
" type = \"mesh3d\", \n",
" x = df['x'], y = df['y'], z = df['z']\n",
")\n",
"layout = dict(\n",
" title = '3d point clustering',\n",
" scene = dict(\n",
" xaxis = dict( zeroline=False ),\n",
" yaxis = dict( zeroline=False ),\n",
" zaxis = dict( zeroline=False ),\n",
" )\n",
")\n",
"fig = dict( data=[scatter, clusters], layout=layout )\n",
"# Use py.iplot() for IPython notebook\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Projection of 3D Surface in Python\n",
"\n",
"This is one of the more advanced methods in the plotly API. \n",
"\n",
"When you see the results, you will understand a little about what is going on here. \n",
"\n",
"From the plotly tutorial:\n",
"\n",
">This example will demonstrate how to create heatmaps of projections of a 3d surface onto planes perpendicular to the z, x, respectively y-direction. Usually surfaces in the 3d space are colored with a colormap associated to the normalized range of the z coordinates of points on that surface. Recently, Plotly devised a method to color a surface according to a custom color function.\n",
"\n",
">This method allows to project a surface onto planes perpendicular to the z, x or y-direction in the 3d space and interpret the projection as a planar surface colored according to the z, x or y value at each point of the coresponding plane.\n",
"\n",
"The demo code is somewhat involved but it can be understood."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Define the surface and its discretization\n",
"\n",
"xx=np.linspace(-3.5, 3.5, 100)\n",
"yy=np.linspace(-3.5, 3.5, 100)\n",
"x,y=np.meshgrid(xx, yy)\n",
"z=np.exp(-(x-1)**2-y**2)-10*(x**3+y**4-x/5)*np.exp(-(x**2+y**2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Original colorscale\n",
"# colorscale=[[0.0, 'rgb(20,29,67)'],\n",
"# [0.1, 'rgb(28,76,96)'],\n",
"# [0.2, 'rgb(16,125,121)'],\n",
"# [0.3, 'rgb(92,166,133)'],\n",
"# [0.4, 'rgb(182,202,175)'],\n",
"# [0.5, 'rgb(253,245,243)'],\n",
"# [0.6, 'rgb(230,183,162)'],\n",
"# [0.7, 'rgb(211,118,105)'],\n",
"# [0.8, 'rgb(174,63,95)'],\n",
"# [0.9, 'rgb(116,25,93)'],\n",
"# [1.0, 'rgb(51,13,53)']]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Color according to normalized z-values\n",
"\n",
"colorscale=[[0.0, 'rgb(204, 0, 204)'],\n",
" [0.1, 'rgb(204, 0, 204)'],\n",
" [0.2, 'rgb(16,125,121)'],\n",
" [0.3, 'rgb(92,166,133)'],\n",
" [0.4, 'rgb(182,202,175)'],\n",
" [0.5, 'rgb(51, 153, 255)'],\n",
" [0.6, 'rgb(51, 204, 255)'],\n",
" [0.7, 'rgb(211,118,105)'],\n",
" [0.8, 'rgb(174,63,95)'],\n",
" [0.9, 'rgb(116,25,93)'],\n",
" [1.0, 'rgb(51,13,53)']]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Hover text\n",
"\n",
"textz = [['x: '+'{:0.5f}'.format(x[i][j])+'<br>y: '+'{:0.5f}'.format(y[i][j])+\n",
" '<br>z: '+'{:0.5f}'.format(z[i][j]) for j in range(z.shape[1])] for i in range(z.shape[0])]\n",
"\n",
"trace1= go.Surface(\n",
" x=tuple(x),\n",
" y=tuple(y),\n",
" z=tuple(z),\n",
" colorscale=colorscale,\n",
" text=textz,\n",
" hoverinfo='text',\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Create the plot layout\n",
"\n",
"axis = dict(\n",
"showbackground=True, \n",
"backgroundcolor=\"rgb(230, 230,230)\", \n",
"showgrid=False, \n",
"zeroline=False, \n",
"showline=False)\n",
"\n",
"ztickvals=list(range(-6,4))\n",
"layout = go.Layout(title=\"Projections of a surface onto coordinate planes\" , \n",
" autosize=False,\n",
" width=700,\n",
" height=600,\n",
" scene=dict(xaxis=dict(axis, range=[-3.5, 3.5]),\n",
" yaxis=dict(axis, range=[-3.5, 3.5]),\n",
" zaxis=dict(axis , tickvals=ztickvals),\n",
" aspectratio=dict(x=1,\n",
" y=1,\n",
" z=0.95)\n",
" )\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Discretization of each Plane\n",
"\n",
"z_offset=(np.min(z)-2)*np.ones(z.shape)\n",
"x_offset=np.min(xx)*np.ones(z.shape)\n",
"y_offset=np.min(yy)*np.ones(z.shape)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Color functions for each plan\n",
"# Coordinate tuples on hover\n",
"# First two for coordinates\n",
"# Third for color\n",
"# Create three traces - 1 for x, y and z\n",
"\n",
"proj_z=lambda x, y, z: z#projection in the z-direction\n",
"colorsurfz=proj_z(x,y,z)\n",
"proj_x=lambda x, y, z: x\n",
"colorsurfx=proj_z(x,y,z)\n",
"proj_y=lambda x, y, z: y\n",
"colorsurfy=proj_z(x,y,z)\n",
"\n",
"textx=[['y: '+'{:0.5f}'.format(y[i][j])+'<br>z: '+'{:0.5f}'.format(z[i][j])+\n",
" '<br>x: '+'{:0.5f}'.format(x[i][j]) for j in range(z.shape[1])] for i in range(z.shape[0])]\n",
"texty=[['x: '+'{:0.5f}'.format(x[i][j])+'<br>z: '+'{:0.5f}'.format(z[i][j]) +\n",
" '<br>y: '+'{:0.5f}'.format(y[i][j]) for j in range(z.shape[1])] for i in range(z.shape[0])] \n",
"\n",
"tracex = go.Surface(z=list(z),\n",
" x=list(x_offset),\n",
" y=list(y),\n",
" colorscale=colorscale,\n",
" showlegend=False,\n",
" showscale=False,\n",
" surfacecolor=colorsurfx,\n",
" text=textx,\n",
" hoverinfo='text'\n",
" )\n",
"tracey = go.Surface(z=list(z),\n",
" x=list(x),\n",
" y=list(y_offset),\n",
" colorscale=colorscale,\n",
" showlegend=False,\n",
" showscale=False,\n",
" surfacecolor=colorsurfy,\n",
" text=texty,\n",
" hoverinfo='text'\n",
" )\n",
"tracez = go.Surface(z=list(z_offset),\n",
" x=list(x),\n",
" y=list(y),\n",
" colorscale=colorscale,\n",
" showlegend=False,\n",
" showscale=False,\n",
" surfacecolor=colorsurfx,\n",
" text=textz,\n",
" hoverinfo='text'\n",
" )\n",
"\n",
"data=[trace1, tracex, tracey, tracez]\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Cone Plots\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Basic 3D Cone\n",
"\n",
"data = [{\n",
" 'type': 'cone',\n",
" 'x': [1], 'y': [1], 'z': [1],\n",
" 'u': [1], 'v': [1], 'w': [0]\n",
"}]\n",
"\n",
"layout = {\n",
" 'scene': {\n",
" 'camera': {\n",
" 'eye': {'x': -0.76, 'y': 1.8, 'z': 0.92}\n",
" }\n",
" }\n",
"}\n",
"\n",
"fig = {\"data\": data, \"layout\": layout}\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Multiple 3D Cones\n",
"\n",
"data = [{\n",
" \"type\": \"cone\",\n",
" \"x\": [1, 2, 3],\n",
" \"y\": [1, 2, 3],\n",
" \"z\": [1, 2, 3],\n",
" \"u\": [1, 0, 0],\n",
" \"v\": [0, 3, 0],\n",
" \"w\": [0, 0, 2],\n",
" \"sizemode\": \"absolute\",\n",
" \"sizeref\": 2,\n",
" \"anchor\": \"tip\",\n",
" \"colorbar\": {\n",
" \"x\": 0,\n",
" \"xanchor\": \"right\",\n",
" \"side\": \"left\"\n",
" }\n",
"}]\n",
"\n",
"layout = {\n",
" \"scene\": {\n",
" \"domain\": {\"x\": [0, 1]},\n",
" \"camera\": {\n",
" \"eye\": {\"x\": -1.57, \"y\": 1.36, \"z\": 0.58}\n",
" }\n",
" }\n",
"}\n",
"\n",
"fig = {\"data\": data, \"layout\": layout}\n",
"py.iplot(fig, filename=\"cone-mulitple\", validate=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3D Streamtube Plots \n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Basic Streamtube Plot\n",
"\n",
"df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/streamtube-basic.csv')\n",
"\n",
"data = [go.Streamtube(\n",
" x = df['x'],\n",
" y = df['y'],\n",
" z = df['z'],\n",
" u = df['u'],\n",
" v = df['v'],\n",
" w = df['w'],\n",
" sizeref = 0.5,\n",
" colorscale = 'Blues', \n",
" cmin = 0,\n",
" cmax = 3\n",
" )\n",
"]\n",
"\n",
"layout = go.Layout(\n",
" scene = dict(\n",
" camera = dict(\n",
" eye = dict(\n",
" x = -0.7243612458865182,\n",
" y = 1.9269804254717962,\n",
" z = 0.6704828299861716\n",
" )\n",
" )\n",
" )\n",
")\n",
"\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Starting Position and Segments\n",
"\n",
"df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/streamtube-wind.csv').drop(['Unnamed: 0'],axis=1)\n",
"\n",
"data = [go.Streamtube(\n",
" x = df['x'],\n",
" y = df['y'],\n",
" z = df['z'],\n",
" u = df['u'],\n",
" v = df['v'],\n",
" w = df['w'],\n",
" starts = dict(\n",
" x = [80] * 16,\n",
" y = [20,30,40,50] * 4,\n",
" z = [0,0,0,0,5,5,5,5,10,10,10,10,15,15,15,15]\n",
" ),\n",
" sizeref = 0.3,\n",
" colorscale = 'Portland',\n",
" showscale = False,\n",
" maxdisplayed = 3000\n",
")]\n",
"\n",
"layout = go.Layout(\n",
" scene = dict(\n",
" aspectratio = dict(\n",
" x = 2,\n",
" y = 1,\n",
" z = 0.3\n",
" )\n",
" ),\n",
" margin = dict(\n",
" t = 20,\n",
" b = 20,\n",
" l = 20,\n",
" r = 20\n",
" )\n",
")\n",
"\n",
"fig = go.Figure(data=data, layout=layout)\n",
"iplot(fig)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plotly Gym: Segment-4: 3D\n",
"\n",
"Takeaways:\n",
"\n",
"3D Scatter Plots\n",
"* 3D Bubble Charts\n",
"* 3D Line Plots\n",
"* 3D Filled Line Plots\n",
"* 3D Surface Plots\n",
"* 3D Mesh Plots\n",
"* 3D Wireframe Plots\n",
"* Parametric Plots\n",
"* Trisurf Plots\n",
"* Iso Surface\n",
"* 3d Network Graphs\n",
"* 3D Clustering with Alpha Shapes\n",
"* Projection of 3D Surface\n",
"* 3D Cone Plots\n",
"* 3D Streamtube Plots"
]
},
{
"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.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment