Liveplotter can't be run multiple times

If I create a plot using start_liveplotter, then close it, I get the following exception:

In [80]: Exception in thread Thread-10:
Traceback (most recent call last):
  File "/usr/lib/python3.5/", line 914, in _bootstrap_inner
  File "/usr/lib/python3.5/", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/home/alex/.local/lib/python3.5/site-packages/odrive/", line 74, in plot_data
  File "/home/alex/.local/lib/python3.5/site-packages/matplotlib/", line 2251, in start_event_loop
  File "/home/alex/.local/lib/python3.5/site-packages/matplotlib/backends/", line 491, in flush_events
  File "/usr/lib/python3.5/tkinter/", line 1028, in update'update')
_tkinter.TclError: can't invoke "update" command: application has been destroyed

odrivetool still works, however if I try to start another plot, the whole thing crashes with the following error:

In [80]: start_liveplotter(lambda: [odrv0.axis0.encoder.vel_estimate])
Out[80]: <fibre.utils.Event at 0x7f7964edf470>

In [81]: Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7f7968fa54a8>>
Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/", line 3359, in __del__'image', 'delete',
RuntimeError: main thread is not in main loop
Tcl_AsyncDelete: async handler deleted by the wrong thread
Aborted (core dumped)

This is on Ubuntu 16.04.

1 Like

Yeah, the plotting stuff doesn’t like to live on anything but the main thread. However the main thread also is where live commands are parsed. So right now I just kill odrivetool and restart it again every time I want to use the liveplotter. This isn’t a big deal since odrivetool doesn’t really have any state, it’s all on the ODrive.

That said, of course the user experience isn’t great. I think a good solution would be to run the liveplotter in a different process using the python multiprocessing module. If you are interested in looking into that that would be very welcomed.