remove references to live plotting tasks from the Runner and
instead maintain a mapping from plot name to task. This avoids
polluting the runner, but also allows users to maintain references
to plotting tasks, so that they can cancel them at will.
Closes #38.
... | ... |
@@ -53,7 +53,14 @@ def notebook_extension(): |
53 | 53 |
|
54 | 54 |
# Plotting |
55 | 55 |
|
56 |
-def live_plot(runner, *, plotter=None, update_interval=2): |
|
56 |
+active_plotting_tasks = dict() |
|
57 |
+ |
|
58 |
+# Incremented by 'live_plot' on every successful plot creation; |
|
59 |
+# used to name plots that are not given an explicit name. |
|
60 |
+_last_plot_id = 0 |
|
61 |
+ |
|
62 |
+ |
|
63 |
+def live_plot(runner, *, plotter=None, update_interval=2, name=None): |
|
57 | 64 |
try: |
58 | 65 |
import holoviews as hv |
59 | 66 |
except ModuleNotFoundError: |
... | ... |
@@ -70,19 +77,26 @@ def live_plot(runner, *, plotter=None, update_interval=2): |
70 | 77 |
dm = hv.DynamicMap(plot_generator(), |
71 | 78 |
streams=[hv.streams.Stream.define('Next')()]) |
72 | 79 |
|
80 |
+ # Generate task name if not provided |
|
81 |
+ global _last_plot_id |
|
82 |
+ if not name: |
|
83 |
+ name = f'plot_{_last_plot_id}' |
|
84 |
+ _last_plot_id += 1 |
|
85 |
+ |
|
73 | 86 |
# Could have used dm.periodic in the following, but this would either spin |
74 | 87 |
# off a thread (and learner is not threadsafe) or block the kernel. |
75 | 88 |
|
76 | 89 |
async def updater(): |
77 |
- while not runner.task.done(): |
|
78 |
- dm.event() |
|
79 |
- await asyncio.sleep(update_interval) |
|
80 |
- dm.event() # fire off one last update before we die |
|
90 |
+ try: |
|
91 |
+ while not runner.task.done(): |
|
92 |
+ dm.event() |
|
93 |
+ await asyncio.sleep(update_interval) |
|
94 |
+ dm.event() # fire off one last update before we die |
|
95 |
+ finally: |
|
96 |
+ active_plotting_tasks.pop(name, None) |
|
81 | 97 |
|
82 | 98 |
task = asyncio.get_event_loop().create_task(updater()) |
83 | 99 |
|
84 |
- if not hasattr(runner, 'live_plotters'): |
|
85 |
- runner.live_plotters = [] |
|
100 |
+ active_plotting_tasks[name] = task |
|
86 | 101 |
|
87 |
- runner.live_plotters.append(task) |
|
88 | 102 |
return dm |