psychopy.org | Reference | Downloads | Github

Defining specific colours for RadialStim and GratingStim

Hi there,

I would actually like to define the colour of the abovementioned visual. functions. But currently, the ‘color’ setting for these functions can only be applied to one of the rings/gratings and the color of the other, the direct opposite. Is there a way that I can specifically control the colour of the second ring/grating?

(ie. If I were to set the color as red, the default opponent color is blue. I would like to make it say, red and green instead.)

Edit: I’ve found the solution for a non-radial stimulus at Creating a grating with a only one color. However, the psychopy.filters.makeGrating function hasn’t got a ‘tex’ setting where I could change it away from the default sin texture. Secondly, I’m still not quite sure how to do the same to a circular radial stimulus?

The gratType parameter has a few options to generate non-sin textures.

You can get an idea of how it works with a radial stimulus by replacing GratingStim with RadialStim in the linked demo code.

blue_radial_grating

For example, try using ori=90 in makeGrating.

Thanks @djmannion . That worked for a squarish grating, which is one thing that I needed. However for the radial stimulus, is filter.makeGrating able to come out with something like this instead?

Yes, just set ori=90 when making the texture that is drawn by a RadialStim.

Or you can get that just with a RadialStim by setting angularCycles=0 and radialCycles=8 (for example) with tex="sqrXsqr".

Oh yes, thanks, I managed to get it to work now!

One last question, from the linked demo code:

replace the blue channel with the grating

blue_grating[…, -1] = grating

I was trying to wrap my head around the massive number of lists within ‘blue_grating’ here and can’t quite figure out how this actually makes the grating blue. If I want to make this red, green or even maroon, what variable here do I have to manipulate to get it to change to the respective colours?

The blue_grating variable is a 256x256x3 array, where the last dimension indexes the red, green, and blue colour channels. The line blue_grating[…, -1] = grating is setting the blue channel (the -1 indexes the last channel) to vary its intensity according to the grating.

To make it be different colours, the RGB space might not be easiest. Instead, you can define your stimulus in HSV space (with the grating in the V channel) and then convert it into RGB. That way, you only need to change the H channel to vary the hue (though other aspects change with hue also).

For example:

import numpy as np

import psychopy.visual
import psychopy.event
import psychopy.colors

win = psychopy.visual.Window()

grating_res = 256

grating = psychopy.visual.filters.makeGrating(res=grating_res, cycles=5.0)

hsv_tex = np.ones((grating_res, grating_res, 3))
# set the value channel to the grating
hsv_tex[..., 2] = (grating + 1) / 2.0

stim = psychopy.visual.RadialStim(
    win=win,
    units="pix",
    size=(grating_res, grating_res)
)

# loop over hues
for angle in range(0, 360, 10):

    hsv_tex[..., 0] = angle

    stim.tex = psychopy.colors.hsv2rgb(hsv_tex)

    stim.draw()

    win.flip()

    psychopy.event.waitKeys()

win.close()

I see, thanks for all these. It seems though, that the colour is dependent on having a black background. Does it have to be that way? (Ie. I can’t have a non-black colour pair like yellow and brown?)

No, it doesn’t have to be that way. You can make the value channel not go all the way to 0 to get yellow-brown. I’d suggest experimenting with the different ways of manipulating hsv_tex - you can make it look pretty much however you want.

import numpy as np

import psychopy.visual
import psychopy.event
import psychopy.colors

win = psychopy.visual.Window()

grating_res = 256

grating = psychopy.visual.filters.makeGrating(res=grating_res, cycles=5.0)

hsv_tex = np.ones((grating_res, grating_res, 3))
hsv_tex[..., 0] = 50.0
hsv_tex[..., 2] = (grating + 1) / 2.0 * 0.5 + 0.5

stim = psychopy.visual.RadialStim(
    win=win,
    units="pix",
    size=(grating_res, grating_res)
)

stim.tex = psychopy.colors.hsv2rgb(hsv_tex)

stim.draw()

win.flip()

psychopy.event.waitKeys()

win.close()