1

I am trying to use trackpy (henceforth tp) for particle tracking. I have a series of images of cell samples. Naturally, there is some noise in the image. The first step in tracking is to choose, from the first image of the series, which clusters are cells and which clusters are not. This is done in large part by tp.locate. This is not perfect. I would like to be able to go through the 'candidates' chosen by tp.locate and indicate if each is a cell or not a cell.

I created the function ID in order to do this. The goal is to go through the list of 'candidates' generated by tp.locate. I wanted to do this by displaying (via matplotlib's imshow function) each 'candidate' while simultaneously prompting a user input to indicate whether or not the 'candidate' is a cell.

The problem is that asking for a user input seems to suppress the output from the imshow function. Each pass through the for loop asks about a different candidate but the imshow window never actually shows the candidate. I do not know how to work around this and I feel that I am VERY CLOSE to my end goal so I would really appreciate input.

I do not need a GUI, but is there some way I could handle this using tkinter? I am not familiar with tkinter, but I have read some things which make me think I may be able to solve this problem with it.

import numpy as np
import matplotlib.pyplot as plt

def framer(f,image,windowsize=(60,100)):
    arr = image[:,:] #This makes a copy of image, so that when the buffers are 
                     #added for the following process, the input image (image) 
                     #is not modified.
    h = windowsize[0]
    w = windowsize[1]
    hbuffer = np.zeros((h/2,arr.shape[1]))
    arr = np.concatenate((hbuffer,arr,hbuffer),axis=0) #Buffer takes care of situations
                                                       #where the crop window extends
                                                       #beyond input image dimensions         
    wbuffer = np.zeros((arr.shape[0],w/2))
    arr = np.concatenate((wbuffer,arr,wbuffer),axis=1)
    narr = np.zeros((f.shape[0],h,w)) #Initialize array of crop windows
    for i in range(f.shape[0]):
        crop_arr = arr[f.get_value(i,'y'):f.get_value(i,'y') + h,f.get_value(i,'x'):f.get_value(i,'x') + w]   #THIS MIGHT BE BACKWARDS
        narr[i] = crop_arr
    return narr

def ID(f,image,windowsize=(60,100)):
    arr = framer(f,image,windowsize=(60,100))
    f_cop = f[:]
    reslist = np.zeros((arr.shape[0]))
    for i in range(arr.shape[0]):
        plt.imshow(arr[i],cmap='gray')
        plt.annotate('particle '+repr(i),xy=(f.get_value(i,'x'),\
        f.get_value(i,'y')),xytext=(f.get_value(i,'x')+20,f.get_value(i,'y')+20),\
        arrowprops=dict(facecolor='red', shrink=0.05),fontsize=12,color='r')

        res = input('Is this a cell? 1 for yes, 0 for no, 5 to exit')
        if res == 1 or res == 0:
            reslist[i] = res
        if res == 5:
            break
        else:
            print('Must give a valid input! (0,1 or 5)')
    f_cop['res'] = reslist
    return f_cop[f_cop.res == 1]
tacaswell
  • 84,579
  • 22
  • 210
  • 199
tsnitz
  • 15
  • 5
  • 2
    I would throw a `plt.draw()` in before the input. – tacaswell May 06 '14 at 19:41
  • 1
    and as much as I like trackpy (as one of the authors) it is not really relevant to your question. It is best to post the _minimal_ amount of code to reproduce your problem. – tacaswell May 06 '14 at 19:53

1 Answers1

1

Try something like:

fig, ax = plt.subplots(1, 1)


for i in range(arr.shape[0]):
    ax.cla()
    im = ax.imshow(arr[i], cmap='gray', interpolation='nearest')
    plt.annotate('particle ' + repr(i), xy=(f.get_value(i, 'x'), f.get_value(i,'y')),
                  xytext=(f.get_value(i,'x')+20, f.get_value(i,'y')+20),
                  arrowprops=dict(facecolor='red', shrink=0.05),
                  fontsize=12,color='r')
    fig.canvas.draw()
    res = None
    while res not in (0, 1, 5):
        res = input('Is this a cell? 1 for yes, 0 for no, 5 to exit')
    if res == 1 or res == 0:
        reslist[i] = res
    elif res == 5:
        break
    else:
        print "should never get here"

You should avoid using pyplot is scripting as much as possible, the state machine can cause you great trouble.

tacaswell
  • 84,579
  • 22
  • 210
  • 199