Search code examples
pythonpsychopy

Increasing vertices in psychopy to create progress bar


I am trying to create a progress bar for an fMRI task, so that when a participant answers correctly, the progress bar moves up exponentially based on the trial amount/questions left. I have figured out how to make the bar move up only to a specified value (as shown below) but I cannot seem to get it to move up every correct question by lets say 10%..

I place the progress bar function in the 'each frame' code component of the routine.

progverts = [ [0,-0.8], [0,-0.7], [0.2,-0.7] ,[0.2,-0.8] ]

counter = 0

progTest = visual.ShapeStim(win, units='', lineWidth=1.5, lineColor='red', lineColorSpace='rgb', 
   fillColor='yellow', fillColorSpace='rgb', vertices=progverts, 
   closeShape=True, pos=(0, 0), size=1, ori=0.0, opacity=1.0,
   contrast=1.0, depth=0, interpolate=True, name=None, autoLog=None, autoDraw = False)

def progressbar ():
   global counter 
   global progverts 

   progTest.setAutoDraw(True)
   win.flip()
   core.wait(.5)

   if trials.thisN == 0: 
       if ParticipantKeys.corr  == 1:
           progTest.vertices = [ [0,-0.8], [0,-0.65], [0.2,-0.65] ,[0.2,-0.8] ]

Essentially, I am trying to figure out a way to make progverts[1] and progverts[2] increase their y-axis every correct answer..


Solution

  • Here's a solution. Read the comments in the code below to learn why I've changed a few things here and there. I've answered your question as if this was a pure code problem first. However, it seems that you may be working through a Builder code component so there's a Builder version below.

    Coder version

    # Some parameters.
    RISE_SPEED = 0.02  # how much to increase height in each frame. (here 2% increase every frame)
    RISE_END = 1.0  # end animation at this unit height
    
    # Set up the window and bar. 
    from psychopy import visual
    win = visual.Window()
    progTest = visual.Rect(win, width=0.2, height=0.1, pos=(0, -0.75), 
                           lineColor='red', fillColor='yellow')  # no need to set all the default parameters. Just change the ones you need
    
    # While the height is less than RISE_END.
    while progTest.height < RISE_END:
        # Increase the height (y-length in both directions) and then move up on Y so that the base stays put.
        progTest.height *= 1 + RISE_SPEED
        progTest.pos[1] += progTest.height*RISE_SPEED/2  # the y-position only
    
        # Show it. 
        progTest.draw()
        win.flip()
    

    Notice that since you're just using a rectangle bar, visual.Rect is handy since it has a height parameter. Behind the scenes, visual.Rect is just a visual.ShapeStim, but the Rect way is easier to create and manipulate rectangles which is a frequent enough use case to warrant it's existence.

    Builder version

    Simply have this in the "run each frame" section of a code component and make sure to haveprogTest in the same routine, created using Builder.

    RISE_SPEED = 0.02  # how much to increase height in each frame. (here 2% increase every frame)
    RISE_END = 1.0  # end animation at this unit height
    progTest.height *= 1 + RISE_SPEED
    progTest.pos[1] += progTest.height*RISE_SPEED/2  # the y-position only