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.


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.