Skip to content

Commit

Permalink
added new example for gallery (#1576)
Browse files Browse the repository at this point in the history
* added new example for gallery

* clean notebook

Co-authored-by: Marc Skov Madsen <[email protected]>
  • Loading branch information
2 people authored and philippjfr committed Sep 17, 2020
1 parent a390d2c commit 1993515
Showing 1 changed file with 238 additions and 0 deletions.
238 changes: 238 additions & 0 deletions examples/gallery/dynamic/dynamic_timeseries_image_analysis.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[<img src=\"http://holoviews.org/_static/logo.png\" style=\"height:50px;display:inline\"></img>](https://holoviews.holoviz.org)[<img src=\"https://panel.holoviz.org/_static/logo_stacked.png\" style=\"height:50px;display:inline\"></img>](https://panel.holoviz.org)\n",
"\n",
"# Timeseries Image Analysis with HoloViews and Panel \n",
"\n",
"The purpose of this notebook is to illustrate how you can **make an interactive and responsive tool for timeseries analysis of images** by combining a Panel `IntSlider`, some `@pn.depends` annotated plotting functions and a few HoloViews `DynamicMap`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import holoviews as hv\n",
"import hvplot.pandas\n",
"import panel as pn\n",
"\n",
"hv.extension('bokeh')\n",
"pn.config.sizing_mode=\"stretch_width\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def make_ts_data(n_timesteps):\n",
" data = pd.DataFrame(\n",
" {\n",
" \"a\": np.random.normal(size=(n_timesteps,)),\n",
" \"b\": np.random.normal(size=(n_timesteps,)),\n",
" \"c\": np.random.normal(size=(n_timesteps,)),\n",
" },\n",
" index=pd.Index(np.arange(n_timesteps), name=\"time\", )\n",
" )\n",
" return data\n",
"\n",
"ts_data = make_ts_data(1000)\n",
"ts_data.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plots"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"HEIGHT=300"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plot_a = ts_data.hvplot(y=\"a\", responsive=True, height=HEIGHT)\n",
"plot_b = ts_data.hvplot(y=\"b\", responsive=True, height=HEIGHT)\n",
"plot_c = ts_data.hvplot(y=\"c\", responsive=True, height=HEIGHT)\n",
"\n",
"plot_a + plot_b + plot_c"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_image(frame):\n",
" return hv.Image(np.random.normal(size=(100, 100))).opts(height=HEIGHT, responsive=True)\n",
"\n",
"get_image(100)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_vline(frame):\n",
" return hv.VLine(frame).opts(color=\"red\")\n",
"\n",
"get_vline(0.5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## App\n",
"\n",
"### Bar"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"app_bar = pn.Row(\n",
" pn.pane.Markdown(\"## TimeSeries Image Analysis - POC\", style={\"color\": \"white\"}, width=500, sizing_mode=\"fixed\", margin=(10,5,10,15)), \n",
" pn.Spacer(),\n",
" pn.pane.PNG(\"http://holoviews.org/_static/logo.png\", height=50, sizing_mode=\"fixed\", align=\"center\"),\n",
" pn.pane.PNG(\"https://panel.holoviz.org/_static/logo_horizontal.png\", height=50, sizing_mode=\"fixed\", align=\"center\"),\n",
" background=\"black\",\n",
")\n",
"app_bar"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Dynamic Plots"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"frame_slider = pn.widgets.IntSlider(name=\"Time\", value=25, start=0, end=999)\n",
"\n",
"@pn.depends(frame=frame_slider)\n",
"def image(frame):\n",
" return get_image(frame)\n",
"\n",
"@pn.depends(frame=frame_slider)\n",
"def vline(frame):\n",
" return get_vline(frame)\n",
"\n",
"vline_dmap = hv.DynamicMap(vline)\n",
"img_dmap = hv.DynamicMap(image)\n",
"\n",
"plots = ((plot_a + plot_b + plot_c) * vline_dmap).cols(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Layout"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"app = pn.Column(\n",
" app_bar,\n",
" pn.Spacer(height=10),\n",
" frame_slider,\n",
" pn.Row(\n",
" plots,\n",
" pn.Column(\n",
" pn.Spacer(height=20),\n",
" img_dmap,\n",
" ),\n",
" ),\n",
")\n",
"app.servable()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You are now ready to serve the app to your users via `panel serve dynamic_timeseries_image_analysis.ipynb`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Notes\n",
"\n",
"The `plots = ((plot_a + plot_b + plot_c) * vline_dmap).cols(1)` line is essential for making the app fast and responsive. Initially the `plot_a + plot_b + plot_c` where regenerated together with the `vline` everytime the `frame_slider.value` was changed. That made the app slower because it had to recalculate and retransfer much more data."
]
}
],
"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.8.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

0 comments on commit 1993515

Please sign in to comment.