4

I'm trying to embed a matplotlib graph in my tkinter GUI. After many attempts of trying examples posted on the matplotlib site, none of them seem to work.

For example:

#!/usr/bin/env python

import matplotlib
matplotlib.use('TkAgg')

from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
# implement the default mpl key bindings
from matplotlib.backend_bases import key_press_handler


from matplotlib.figure import Figure

import sys
if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk

root = Tk.Tk()
root.wm_title("Embedding in TK")


f = Figure(figsize=(5, 4), dpi=100)
a = f.add_subplot(111)
t = arange(0.0, 3.0, 0.01)
s = sin(2*pi*t)

a.plot(t, s)


# a tk.DrawingArea
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)


def on_key_event(event):
    print('you pressed %s' % event.key)
    key_press_handler(event, canvas, toolbar)

canvas.mpl_connect('key_press_event', on_key_event)


def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate

button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)

Tk.mainloop()
# If you put root.destroy() here, it will cause an error if
# the window is closed with the window manager. 

The example above gives me this error:

Traceback (most recent call last):
  File "<tmp 1>", line 34, in <module>
    canvas.show()
  File "C:\pyzo2015a\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 350, in draw
    tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
  File "C:\pyzo2015a\lib\site-packages\matplotlib\backends\tkagg.py", line 24, in blit
    tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
_tkinter.TclError

Another example:

#!/usr/bin/env python
# -*- noplot -*-

import matplotlib as mpl
import numpy as np
import sys
if sys.version_info[0] < 3:
    import Tkinter as tk
else:
    import tkinter as tk
import matplotlib.backends.tkagg as tkagg
from matplotlib.backends.backend_agg import FigureCanvasAgg


def draw_figure(canvas, figure, loc=(0, 0)):
    """ Draw a matplotlib figure onto a Tk canvas

    loc: location of top-left corner of figure on canvas in pixels.

    Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
    """
    figure_canvas_agg = FigureCanvasAgg(figure)
    figure_canvas_agg.draw()
    figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds
    figure_w, figure_h = int(figure_w), int(figure_h)
    photo = tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)

    # Position: convert from top-left anchor to center anchor
    canvas.create_image(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo)

    # Unfortunatly, there's no accessor for the pointer to the native renderer
    tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)

    # Return a handle which contains a reference to the photo object
    # which must be kept live or else the picture disappears
    return photo

# Create a canvas
w, h = 300, 200
window = tk.Tk()
window.title("A figure in a canvas")
canvas = tk.Canvas(window, width=w, height=h)
canvas.pack()

# Generate some example data
X = np.linspace(0, 2.0*3.14, 50)
Y = np.sin(X)

# Create the figure we desire to add to an existing canvas
fig = mpl.figure.Figure(figsize=(2, 1))
ax = fig.add_axes([0, 0, 1, 1])
ax.plot(X, Y)

# Keep this handle alive, or else figure will disappear
fig_x, fig_y = 100, 100
fig_photo = draw_figure(canvas, fig, loc=(fig_x, fig_y))
fig_w, fig_h = fig_photo.width(), fig_photo.height()

# Add more elements to the canvas, potentially on top of the figure
canvas.create_line(200, 50, fig_x + fig_w / 2, fig_y + fig_h / 2)
canvas.create_text(200, 50, text="Zero-crossing", anchor="s")

# Let Tk take over
tk.mainloop()

This one gives me this error:

 Traceback (most recent call last):
      File "<tmp 2>", line 56, in <module>
        fig_photo = draw_figure(canvas, fig, loc=(fig_x, fig_y))
      File "<tmp 2>", line 32, in draw_figure
        tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
      File "C:\pyzo2015a\lib\site-packages\matplotlib\backends\tkagg.py", line 24, in blit
        tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
    _tkinter.TclError

I don't understand why these examples are not working. Can someone please help me?

6
  • 1
    Are you using anaconda? Commented May 28, 2016 at 16:45
  • I had a similar problem. Although in my case I was using PyQt for the GUI, instead of Tkinter. Nevertheless, I believe that the solution to my problem can help you as well. Check out here: stackoverflow.com/questions/36665850/… Commented May 28, 2016 at 22:34
  • @shivsn, no i'm using Pyzo. I try the example code with Spyder and it works.... so, if i want to embed graph in tk with Pyzo what i could do? Commented Jun 4, 2016 at 15:53
  • @shivsn, thanks a lot.. it seems to work. It work with the examples taken from the matplotlib site. Now i have to test if it works with my code. I let you know! Commented Jun 5, 2016 at 17:05
  • @ConcettoCantone did it work for your code? Commented Jun 6, 2016 at 9:27

1 Answer 1

1

I had similar problem so this worked for me, If you are using windows I suggest uninstall pillow and matplotlib and reinstall from here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.