5

What I'm doing is to show 2 images interchangeably to one figure in an infinite loop until the user clicks on the window to close it.

#import things
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import cv2
import time

#turn on interactive mode for pyplot
plt.ion()

quit_frame = False

#load the first image
img = cv2.imread("C:\Users\al\Desktop\Image1.jpg")
#make the second image from the first one
imggray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

def onclick(event):
    global quit_frame
    quit_frame = not quit_frame

fig = plt.figure()
ax = plt.gca()
fig.canvas.mpl_connect('button_press_event', onclick)

i = 0

while quit_frame is False:
    if i % 2 == 0: #if i is even, show the first image
        ax.imshow(img)
    else: #otherwise, show the second
        ax.imshow(imggray)

    #show the time for drawing
    start = time.time()
    plt.draw()
    print time.time() - start

    i = i + 1
    fig.canvas.get_tk_widget().update()
    if quit_frame is True:
        plt.close(fig)

The problem here is that the time printed is quite small at the begining loops but gradually increasing:

0.107000112534
0.074000120163
0.0789999961853
0.0989999771118
0.0880000591278
...
0.415999889374
0.444999933243
0.442000150681
0.468999862671
0.467000007629
0.496999979019
(and continue to increase)

My expectation is the drawing time must be the same for all loop times. What I've done wrong here?

1 Answer 1

11

The problem is that each time you call ax.imshow you add an additional artist to the plot (i.e., you add an image, instead of just replacing it). Thus, in each iteration plt.draw() has an additional image to draw.

To solve this, just instantiate the artist once (before looping):

img_artist = ax.imshow(imggray)

And then in the loop, just call

img_artist.set_data(gray)

to replace the image content (or img_artist.set_data(imggray) of course)

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

2 Comments

Many thanks for your helpful solution. But to get the image artist by using the imshow before the loop is quite irritating. Just curious is there other way to get the artist rather using imshow?
What is irritating about it? Think of img_artist as a container that handles all the drawing related properties and since you only want to change the data that you display, you only need one of these objects.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.