psychopy.org | Reference | Downloads | Github

Writing a Loop for all Gray Levels in RGB255

Hi,

I need to create a uniform-colored circle that cycles through each of the 256 gray levels when a keyboard button is hit. Here is code the so far:

#create a window
mywin = visual.Window([800,600], monitor="testMonitor", color = 'black', units="deg")

#create the stimulus
stim = visual.GratingStim(win=mywin, mask="circle", size=5, pos=[0,0], sf=0)
stim.colorSpace = 'rgb255'
stim.color = (0, 0, 0)

#draw the stimuli and update the window
for frameN in range(256):
    stim.setColor(1.0, '+')
    stim.draw()
    mywin.update()

event.clearEvents(eventType='keyboard')

My trouble is writing the for loop and telling PsychoPy to change to the next gray level at the stroke of the button; I was hoping “stim.setColor(1.0, ‘+’)” would add 1 gray level to each of the (0, 0, 0) values, but it does not. The “event.clearEvents” code for changing the level of the gray is hopefully on the right track.

I am a beginner in coding and psychopy, and will really appreciate your help.

Thank you,
Nick

You are probably better off using a Circle than a GratingStim, unless there is a particular reason for using the latter. Also, note that the second argument to setColor is colorSpace rather than operation, so using stim.setColor(1.0, '+') won’t apply the operation.

Here is some example code:

import psychopy.visual

win = psychopy.visual.Window(
    size=[800, 600],
    monitor="testMonitor",
    color="black",
    units="deg"
)

stim = psychopy.visual.Circle(
    win=win,
    radius=5,
    edges=128,
    fillColorSpace="rgb255",
    fillColor=[0, 0, 0],
    lineColor=None
)

for frameN in range(255):

    # note that the operation is the third argument so needs to be named
    stim.setFillColor(1.0, operation="+")

    stim.draw()

    # note the use of 'flip' rather than 'update'
    win.flip()

win.close()
1 Like

Hi @djmannion, thank you very much! This code works great in looping through the grays!

Is there a way to append the code such that, instead of looping through all levels automatically, I’d need to hit a key to move onto the next level?

I have tried the following in an attempt to accomplish this:

from psychopy import visual, event # import some libraries from PsychoPy

#create a window
mywin = visual.Window(
[800,600], 
monitor="testMonitor", 
color = 'black', 
units="deg")

#create the stimulus
stim = visual.Circle(
win=mywin,
radius=5,
edges=128,
fillColorSpace="rgb255",
fillColor=[0,0,0],
lineColor=None
)

for frameN in range(255):
    stim.setFillColor(1.0, operation="+")
    stim.draw()
    mywin.flip()

#response 
k = ['wait']
while k[0] not in ["escape","space"]:
    k = event.waitKeys()
if k[0] in ['escape']:
    win.close()
    core.quit()

mywin.close()

But all this did was to require a keystroke to exit the program once the loop was complete, as opposed to hitting a keystroke to proceed to the next level of the loop…

Nick

If you add one level of indent to the lines starting with #response and ending with core.quit(), they will get executed for each iteration through the loop - which should do what you’re after.

1 Like

@djmannion PERFECT! Worked like a charm! Thank you for your help!!