Skip to content

Commit 61f46fe

Browse files
committed
🔥 time-series annotation example
1 parent 1e80f4e commit 61f46fe

File tree

2 files changed

+130
-8
lines changed

2 files changed

+130
-8
lines changed

examples/README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ the [basic example notebook](basic_example.ipynb)
1111

1212
### 0.1 Figurewidget example
1313

14-
The [figurewidget example notebook](figurewidget_example.ipynb) utilizes the `FigureWidgetResampler` wrapper to
15-
create a `go.FigureWidget` with dynamic aggregation functionality. A major advantage of this approach is that this does not create a web application, thus not needing to be able to create / forward a network port.
14+
The [figurewidget example notebook](figurewidget_example.ipynb) utilizes the `FigureWidgetResampler` wrapper to create a `go.FigureWidget` with dynamic aggregation functionality. A major advantage of this approach is that this does not create a web application, thus not needing to be able to create / forward a network port.
15+
16+
Additionally, this notebook highlights how to use the `FigureWidget` its on-click callback to utilize plotly for large **time series annotation**.
1617

1718
## 1. Dash apps
1819

examples/figurewidget_example.ipynb

+127-6
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
{
6767
"data": {
6868
"application/vnd.jupyter.widget-view+json": {
69-
"model_id": "c478aeb87d6645319e54ba0c3ef2bb27",
69+
"model_id": "f0b23a98e7a24f64b5d2a8d24ae1e96b",
7070
"version_major": 2,
7171
"version_minor": 0
7272
},
@@ -121,13 +121,134 @@
121121
"cell_type": "markdown",
122122
"metadata": {},
123123
"source": [
124-
"### Adjusting the figure data using the `hf_data` property"
124+
"### time-series **annotation** using the on-click callback"
125125
]
126126
},
127127
{
128128
"cell_type": "code",
129129
"execution_count": 7,
130130
"metadata": {},
131+
"outputs": [],
132+
"source": [
133+
"from ipywidgets import Dropdown\n",
134+
"from IPython.display import display"
135+
]
136+
},
137+
{
138+
"cell_type": "code",
139+
"execution_count": 12,
140+
"metadata": {},
141+
"outputs": [
142+
{
143+
"data": {
144+
"application/vnd.jupyter.widget-view+json": {
145+
"model_id": "f3390f396a9d46a088290fb5991f3724",
146+
"version_major": 2,
147+
"version_minor": 0
148+
},
149+
"text/plain": [
150+
"Dropdown(options=('peak', 'through', 'rise', 'fall'), value='peak')"
151+
]
152+
},
153+
"metadata": {},
154+
"output_type": "display_data"
155+
},
156+
{
157+
"data": {
158+
"application/vnd.jupyter.widget-view+json": {
159+
"model_id": "e80c27b76cd54fa3bdfe87bb80035941",
160+
"version_major": 2,
161+
"version_minor": 0
162+
},
163+
"text/plain": [
164+
"FigureWidgetResampler({\n",
165+
" 'data': [{'name': '<b style=\"color:sandybrown\">[R]</b> noisy sine <i style=\"color:…"
166+
]
167+
},
168+
"metadata": {},
169+
"output_type": "display_data"
170+
}
171+
],
172+
"source": [
173+
"# Proxy for a label class\n",
174+
"label_dict = {\n",
175+
" \"peak\": {\n",
176+
" \"type\": \"marker\",\n",
177+
" \"trace_index\": 1,\n",
178+
" \"plt_kwargs\": {\n",
179+
" \"mode\": \"markers\", \"marker_symbol\": \"star\", \"marker_size\": 12, \"marker_color\": \"red\"\n",
180+
" }\n",
181+
" },\n",
182+
" \"through\": {\n",
183+
" \"type\": \"marker\",\n",
184+
" \"trace_index\": 2,\n",
185+
" \"plt_kwargs\": {\n",
186+
" \"mode\": \"markers\", \"marker_symbol\": \"cross\", \"marker_size\": 12, \"line_color\": \"orange\"\n",
187+
" }\n",
188+
" },\n",
189+
" \"rise\": {\n",
190+
" \"type\": \"x-range\",\n",
191+
" \"plt_kwargs\": {\n",
192+
" \"line_width\": 0, \"fillcolor\": \"green\", \"opacity\": 0.3\n",
193+
" }\n",
194+
" },\n",
195+
" \"fall\": {\n",
196+
" \"type\": \"x-range\",\n",
197+
" \"plt_kwargs\": {\n",
198+
" \"line_width\": 0, \"fillcolor\": \"purple\", \"opacity\": 0.3\n",
199+
" }\n",
200+
" }\n",
201+
"}\n",
202+
"\n",
203+
"# Create a label selector\n",
204+
"label_selector = Dropdown()\n",
205+
"label_selector.options = list(label_dict.keys())\n",
206+
"\n",
207+
"# Construct the figure\n",
208+
"fw_fig = FigureWidgetResampler()\n",
209+
"fw_fig.add_trace(go.Scattergl(name=\"noisy sine\", opacity=0.8), hf_x=x, hf_y=y)\n",
210+
"for k, v in label_dict.items():\n",
211+
" if v.get(\"type\", \"\").lower() == 'marker':\n",
212+
" fw_fig.add_trace(go.Scattergl(name=k, **v.get(\"plt_kwargs\", {})))\n",
213+
"\n",
214+
"\n",
215+
"# Update logic\n",
216+
"prev_x = []\n",
217+
"point_list = []\n",
218+
"\n",
219+
"def update_point(trace, points, selector):\n",
220+
" global prev_x, point_list\n",
221+
" config = label_dict[label_selector.value]\n",
222+
"\n",
223+
" if config.get(\"type\", \"\") == 'x-range':\n",
224+
" prev_x.append(points.xs[0])\n",
225+
" if len(prev_x) == 2:\n",
226+
" fw_fig.add_vrect(prev_x[0], prev_x[1], **config.get(\"plt_kwargs\", {}))\n",
227+
" prev_x = []\n",
228+
"\n",
229+
" with fw_fig.batch_update():\n",
230+
" if config.get(\"type\", \"\") == 'marker':\n",
231+
" trace_index = config.get(\"trace_index\")\n",
232+
" fw_fig.data[trace_index].x = list(fw_fig.data[trace_index].x) + points.xs\n",
233+
" fw_fig.data[trace_index].y = list(fw_fig.data[trace_index].y) + points.ys\n",
234+
"\n",
235+
"fw_fig.data[0].on_click(update_point)\n",
236+
"\n",
237+
"display(label_selector)\n",
238+
"fw_fig"
239+
]
240+
},
241+
{
242+
"cell_type": "markdown",
243+
"metadata": {},
244+
"source": [
245+
"### Adjusting the figure data using the `hf_data` property"
246+
]
247+
},
248+
{
249+
"cell_type": "code",
250+
"execution_count": 9,
251+
"metadata": {},
131252
"outputs": [
132253
{
133254
"name": "stdout",
@@ -140,7 +261,7 @@
140261
{
141262
"data": {
142263
"application/vnd.jupyter.widget-view+json": {
143-
"model_id": "ed08193852c147f9b0824e4562b6e28a",
264+
"model_id": "02cc8bd1dcdd44ab946cbfbe78821833",
144265
"version_major": 2,
145266
"version_minor": 0
146267
},
@@ -163,7 +284,7 @@
163284
},
164285
{
165286
"cell_type": "code",
166-
"execution_count": 8,
287+
"execution_count": 10,
167288
"metadata": {},
168289
"outputs": [],
169290
"source": [
@@ -182,13 +303,13 @@
182303
},
183304
{
184305
"cell_type": "code",
185-
"execution_count": 9,
306+
"execution_count": 11,
186307
"metadata": {},
187308
"outputs": [
188309
{
189310
"data": {
190311
"application/vnd.jupyter.widget-view+json": {
191-
"model_id": "6752cdd8dc52457da48f77aa165b44e4",
312+
"model_id": "549137c024764fadafb5343059def47f",
192313
"version_major": 2,
193314
"version_minor": 0
194315
},

0 commit comments

Comments
 (0)