6

I am trying to update the data in a matplotlib imshow window within a Tkinter gui, an example of my code is as follows:

#minimal example...
import matplotlib, sys
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import pylab as plt
from scipy import ndimage
if sys.version_info[0] < 3:
 import Tkinter as Tk
else:
 import tkinter as Tk
root = Tk.Tk()
root.wm_title("minimal example")
image = plt.imread('test.jpg')
fig = plt.figure(figsize=(5,4))
im = plt.imshow(image) # later use a.set_data(new_data)
ax = plt.gca()
ax.set_xticklabels([]) 
ax.set_yticklabels([]) 
# a tk.DrawingArea
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
def rotate(*args):
 print 'rotate button press...'
 theta = 90
 rotated = ndimage.rotate(image, theta)
 im.set_data(rotated)
 root.update()
def quit(*args):
 print 'quit button press...'
 root.quit() 
 root.destroy() 
button_rotate = Tk.Button(master = root, text = 'Rotate', command = rotate)
button_quit = Tk.Button(master = root, text = 'Quit', command = quit)
button_quit.pack(side=Tk.LEFT)
button_rotate.pack()
Tk.mainloop()

As you can see, I load an image using imshow(), and then try updating the image's data using set_data(), and then want to update the root window of the gui using root.update(). When executed, the print 'rotate button press...' line is executed, but the rest is seemingly not. Do I need to pass the image handle to the rotate function some how, or return the rotated image?

asked Oct 26, 2013 at 22:05
3
  • 1
    do not import pyplot if you are embedding. You end up with dueling gui main loops. Commented Oct 26, 2013 at 23:13
  • @tcaswell That makes sense, but if I'm not using pylot, how can I access imshow()? Commented Oct 27, 2013 at 0:13
  • See stackoverflow.com/questions/14254379/… Commented Oct 27, 2013 at 1:27

1 Answer 1

3

The canvas needs to be redrawn, try this:

def rotate(*args):
 print 'rotate button press...'
 theta = 90
 rotated = ndimage.rotate(image, theta)
 im.set_data(rotated)
 canvas.draw()

Update to keep rotating

Note this is saving image as an attribute of root. Maybe not the best approach but it works for the example.

root = Tk.Tk()
root.wm_title("minimal example")
root.image = plt.imread('test.jpg')
fig = plt.figure(figsize=(5,4))
im = plt.imshow(root.image) # later use a.set_data(new_data)
ax = plt.gca()
ax.set_xticklabels([]) 
ax.set_yticklabels([])
# a tk.DrawingArea
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
def rotate(*args):
 print 'rotate button press...'
 root.image = ndimage.rotate(root.image, 90)
 im.set_data(root.image)
 canvas.draw()
answered Oct 26, 2013 at 22:36

3 Comments

That seems to work, but only once. If I press the rotate button again, it doesn't seem to do anything. (Do I need to somehow save the new state of the image?) And on a potentially unrelated note, it seems to mirror the image, not rotate it 90 as desired.
Yep, this is because you are always rotating the original image 90 degrees. I'll update with another fix, but you'd be better off refactoring to make your own subclass of Tkinter.Frame so you can save your application's attributes...but that's for another question.
You should not import pyplot while embedding.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.