# Threading with Matplotlib and ipywidgets

**URL:** <https://discourse.jupyter.org/t/threading-with-matplotlib-and-ipywidgets/14674>\
**Category:** JupyterLab\
**Tags:** jupyterlab, help-wanted\
**Created:** [June 20, 2022, 8:29pm UTC](https://discourse.jupyter.org/t/threading-with-matplotlib-and-ipywidgets/14674 "2022-06-20T20:29:39Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![bollwyvl](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/bollwyvl/32/904_2.png) [@bollwyvl](https://discourse.jupyter.org/u/bollwyvl)\
**Post date:** [June 21, 2022, 4:26pm UTC](https://discourse.jupyter.org/t/threading-with-matplotlib-and-ipywidgets/14674/2 "2022-06-21T16:26:53Z")

</div>

Some consideration:

- rather than threads, consider using the event loop
  - if you absolutely need threads, consider _still_ using `asyncio`, and a [deque](https://docs.python.org/3.2/library/collections.html#collections.deque)

- maybe have a look at using `ipympl`
  - doing full display updates are pretty expensive

Here’s a basic pattern: it delegates the asyncio stuff to an interval-based loop. Ideally, the `do_work` would _also_ be `async`, but matplotlib _isn’t_.

```auto
import ipywidgets, asyncio, time
output = ipywidgets.Textarea()
running = ipywidgets.ToggleButton(description="start", icon="play")
interval = ipywidgets.FloatSlider(description="loop interval", value=1, min=0.001, max=10) # zero can hang if you don't await
ui = ipywidgets.VBox([ipywidgets.HBox([running, interval]), output])
tasks = dict()

def do_work(t):
    output.value = f"{t}: {time.time()}"

async def do_loop():
    t = 0
    while running.value:
        do_work(t)
        t += 1
        await asyncio.sleep(interval.value)

def on_running_changed(*change):
    task = tasks.pop("do_loop", None)
    output.value = f"maybe stopping {task}..."
    if task:
        output.value = f"stopping {task}..."
        task.cancel()
    if running.value:
        output.value = "starting..."
        tasks["do_loop"] = asyncio.get_event_loop().create_task(do_loop())
running.observe(on_running_changed, "value")

ui

```

---

_[View the full topic](https://discourse.jupyter.org/t/threading-with-matplotlib-and-ipywidgets/14674)._
