-
-
Notifications
You must be signed in to change notification settings - Fork 531
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added new example for gallery (#1576)
* added new example for gallery * clean notebook Co-authored-by: Marc Skov Madsen <[email protected]>
- Loading branch information
1 parent
a390d2c
commit 1993515
Showing
1 changed file
with
238 additions
and
0 deletions.
There are no files selected for viewing
238 changes: 238 additions & 0 deletions
238
examples/gallery/dynamic/dynamic_timeseries_image_analysis.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |