Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TclError when using pandastable with matplotlib figure #177

Open
thawn opened this issue Jun 24, 2020 · 3 comments
Open

TclError when using pandastable with matplotlib figure #177

thawn opened this issue Jun 24, 2020 · 3 comments

Comments

@thawn
Copy link

thawn commented Jun 24, 2020

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
@dmnfarrell
Copy link
Owner

dmnfarrell commented Jun 25, 2020

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()

@thawn
Copy link
Author

thawn commented Jun 25, 2020

@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.

@dmnfarrell
Copy link
Owner

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants