| Reference | Downloads | Github

Issues generating a precisely timed expanding circle

I’ve been trying to write a simple script that generates an expanding circle that:

  1. Expands from 2 to 20 degrees of visual angle over 250 ms.

  2. Holds at 20 degrees for another 250 ms.

  3. Repeats n number of times with 500 ms inter-stimulus interval (blank, grey screen).

I think I have the code working. However, 1) I think there must be a simpler/better way of doing this and 2) when I run the code, although no frame drops are reported, there appears to be some lag/variation in expansion between iterations.

If anyone could comment on either of these points I would appreciate it.

Code so far:

from psychopy import visual, core, event

# Define the background

# Number of epochs (repetitions)

# Duration of expansion

# Hold duration

# ISI duration

# Time-to-frame conversion assuming a 60Hz FR and RR

# Define the stimulus

for e in range(EPOCH):
    for f in range(FRAMES):
        if circle.radius<10:
            circle.radius+=1 # or should it be: circle.radius=(circle.radius+(9/FRAMES))?
    for f in range(HOLD_FRAMES):
    for f in range(ISI_FRAMES):

# Get keys to quit.
if len(event.getKeys())>0:

HI @dylanablack, I would suggest you may be better off using Builder, as it is easily put together. You will need one routines in a loop, where loop controls number of presentations. In the routine. use a static component starting at zero time, with a duration of 500ms, which will be your ISI. Then use a Polygon component, where the shape is a regular polygon with 99 sides - this will give you your circle - remember to set units to degrees. Give your polygon a start of .5 seconds, and a duration of .5 seconds, set the size to circleSize and get it to update every screen refresh. To define and update yourcircleSize variable, we use a code component in Builder. For setting sizes, we will think in terms of frames, or screen refreshes, where one frame is 1/60hz refresh rate = 16.67ms per frame.

In your code component, add the following to the relevant tabs:

# Begin Routine
expansionFrames = 15  # duration of your expansion in frames, or 250ms / 16.67
expansionDegrees = 18 # starting at 2 degrees, 2 + 18 = 20 degrees
expansionRate = expansionDegrees / expansionFrames # expand 1.2 degrees per frame
circleSize = 2  # starting size in degrees

# Each frame
if polygon.size[0] < 20 - 1:  # if not already 20 degrees, expand.
    circleSize += expansionRate

The circle will expand 1.2 degree every frame, and it will take 15 frames to reach 18 degrees of expansion, + starting size = 20 degrees