{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Slice in volumetric data, via Plotly ##"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A volume included in a parallelepiped is described by the values of a scalar field, $f(x,y,z)$, with $x\\in[a,b]$, $y\\in [c,d]$, $z\\in[e,f]$.\n",
"A slice in this volume is visualized by coloring the surface of the slice, according to the values of the function f, restricted to that surface.\n",
"\n",
"In order to plot a planar or a nonlinear slice of equation z=s(x,y) one proceeds as follows:\n",
"\n",
"- define a meshgrid in x,y;\n",
"- evaluate z=s(x,y)\n",
"- define an instance of the Plotly Surface class, that represents the surface z=s(x,y)\n",
"- this surface is colored according to the values, f(x,y,z), at its points. More precisely, the normalized values of the function f are mapped to a colormap/colorscale."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With obvious modications we get slices of equation $x=s(y,z), y=s(z,x)$."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import plotly.graph_objects as go\n",
"from IPython"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Define a function that returns a slice as a Plotly Surface:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_the_slice(x,y,z, surfacecolor):\n",
" return go.Surface(x=x,\n",
" y=y,\n",
" z=z,\n",
" surfacecolor=surfacecolor,\n",
" coloraxis='coloraxis')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_lims_colors(surfacecolor):# color limits for a slice\n",
" return np.min(surfacecolor), np.max(surfacecolor)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us plot the slices z=0 and y=-0.5 in the volume defined by:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"scalar_f = lambda x,y,z: x*np.exp(-x**2-y**2-z**2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.linspace(-2,2, 50)\n",
"y = np.linspace(-2,2, 50)\n",
"x, y = np.meshgrid(x,y)\n",
"z = np.zeros(x.shape)\n",
"surfcolor_z = scalar_f(x,y,z)\n",
"sminz, smaxz = get_lims_colors(surfcolor_z)\n",
"\n",
"slice_z = get_the_slice(x, y, z, surfcolor_z)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = np.linspace(-2,2, 50)\n",
"z = np.linspace(-2,2, 50)\n",
"x, z = np.meshgrid(x,y)\n",
"y = -0.5 * np.ones(x.shape)\n",
"surfcolor_y = scalar_f(x,y,z)\n",
"sminy, smaxy = get_lims_colors(surfcolor_y)\n",
"vmin = min([sminz, sminy])\n",
"vmax = max([smaxz, smaxy])\n",
"slice_y = get_the_slice(x, y, z, surfcolor_y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In order to be able to compare the two slices, we choose a unique interval of values to be mapped to the colorscale:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def colorax(vmin, vmax):\n",
" return dict(cmin=vmin,\n",
" cmax=vmax)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig1 = go.Figure(data=[slice_z, slice_y])\n",
"fig1.update_layout(\n",
" title_text='Slices in volumetric data', \n",
" title_x=0.5,\n",
" width=700,\n",
" height=700,\n",
" scene_zaxis_range=[-2,2], \n",
" coloraxis=dict(colorscale='BrBG',\n",
" colorbar_thickness=25,\n",
" colorbar_len=0.75,\n",
" **colorax(vmin, vmax))) \n",
" \n",
"#fig1.show() "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import IFrame \n",
"IFrame('https://chart-studio.plotly.com/~empet/13862', width=700, height=700)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Oblique slice in volumetric data ###"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As an example we plot comparatively two slices: a slice through $z=0$ and an oblique planar slice, that is defined by rotating the plane z=0 by $\\alpha=\\pi/4$, about Oy."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Rotating the plane $z=c$ about Oy (from Oz towards Ox) with $\\alpha$ radians we get the plane of equation\n",
"$z=c/\\cos(\\alpha)-x\\tan(\\alpha)$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"alpha = np.pi/4\n",
"x = np.linspace(-2, 2, 50)\n",
"y = np.linspace(-2, 2, 50)\n",
"x, y = np.meshgrid(x,y)\n",
"z = -x * np.tan(alpha)\n",
"\n",
"surfcolor_obl = scalar_f(x,y,z)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"smino, smaxo = get_lims_colors(surfcolor_obl)\n",
"vmin = min([sminz, smino])\n",
"vmax = max([smaxz, smaxo])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"slice_obl = get_the_slice(x,y,z, surfcolor_obl)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig2 = go.Figure(data=[slice_z, slice_obl], layout=fig1.layout)\n",
"fig2.update_layout( coloraxis=colorax(vmin, vmax))\n",
"\n",
"#fig2.show() "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"IFrame('https://chart-studio.plotly.com/~empet/13864', width=700, height=700)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.core.display import HTML\n",
"def css_styling():\n",
" styles = open(\"./custom.css\", \"r\").read()\n",
" return HTML(styles)\n",
"css_styling()"
]
}
],
"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.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}