pandastable
pandastable copied to clipboard
TclError when using pandastable with matplotlib figure
I would like to use pandastable together with my own matplotlib figure. However, I get the following error: _tkinter.TclError: image "pyimage10" doesn't exist
here is a minimal code example that reproduces the error:
import tkinter
import pandas as pd
from pandastable import Table
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
fig = plt.figure()
root = tkinter.Tk()
pane = tkinter.Canvas(root)
pdframe = pd.DataFrame()
table = Table(pane, dataframe=pdframe, showtoolbar=False, showstatusbar=True)
table.show()
pane.pack()
root.mainloop()
without the line fig = plt.figure()
the code works as expected
I was able to work around the problem by replacing root = tkinter.Tk()
with root = tkinter.Toplevel()
. See also this stackexchange question. However, this workaround causes other problems like the application not closing properly.
This seems to indicate, that matplotlib creates a Tk root object in the background to which the PhotoImage
objects in images.py
get assigned. This makes the images inaccessible by pandastable in the other Tk root object.
This answer on StackExchange suggests that adding master=something
to the PhotoImage
objects in images.py
might help. However, I am not sure which would be a good master object and how to pass it into images.py
.
here is the full stack trace:
File "python3.7/site-packages/pandastable/core.py", line 306, in show
self.statusbar = statusBar(self.parentframe, self)
File "python3.7/site-packages/pandastable/core.py", line 3709, in __init__
addButton(fr, 'Contract Cols', self.parentapp.contractColumns, img, 'contract columns', side=LEFT, padding=1)
File "python3.7/site-packages/pandastable/dialogs.py", line 245, in addButton
image=img, compound=compound, padding=padding)
File "python3.7/tkinter/ttk.py", line 614, in __init__
Widget.__init__(self, master, "ttk::button", kw)
File "python3.7/tkinter/ttk.py", line 559, in __init__
tkinter.Widget.__init__(self, master, widgetname, kw=kw)
File "python3.7/tkinter/__init__.py", line 2299, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage10" doesn't exist
I don't know how to solve that. but when you plot from pandastable it creates a PlotViewer object called pf that you can access and plot to. Maybe that's of use.
root = tkinter.Tk()
pane = tkinter.Canvas(root)
pdframe = pd.DataFrame()
table = Table(pane, dataframe=pdframe, showtoolbar=False, showstatusbar=True)
table.show()
table.plotSelected()
pf = table.pf
fig = pf.fig
ax = pf.ax
ax.plot(range(10),range(10))
pane.pack()
root.mainloop()
@dmnfarrell Thanks a lot for the quick answer and the tip with table.pf object.
I think that the error I am getting may be related to the fact that the PhotoImage
ojects are created without specifying a master tkinter object. This may cause them to be assigned to the wrong tkinter object (the one created by pyplot in my case), which in turn makes them unavailable for pandastable. Do you have an idea how to pass a tkinter object that belongs to pandastable to images.py
? As far as I know, that tkinter object would not need to be the one where the images appear in the end, it just needs to be in the same tkinter object tree so that it can hold the images and keep them accessible to pandastable.
Sorry I don't know how to do that. You'd have to ask someone who knows more about matplotlib. Maybe you could do it without using the pyplot interface. https://matplotlib.org/faq/usage_faq.html#matplotlib-pyplot-and-pylab-how-are-they-related