| Reference | Downloads | Github

Colour Wheel implementation


I’m trying to implement a colour wheel (Color wheel - Wikipedia) using individual coloured lines and the hsv colour space.

I have pretty much got it working except there appears to be a funny visual effect occurring within the wheel itself, and the edge of the circle does not appear to be consistent. Also, the center point seems to be inconsistent for each colour (but this could just be my eyes). Maybe there’s a rounding error for my calculation of the “end” point for each degree of the circle? I’ve tried several things and I cannot locate the source of the error in my code.

If was wondering if anyone would please have a look at my code (attached) and inform me where I might be going wrong?

Jim Grange. (1.8 KB)

I’ve attached a screen-grab of the visual effect I am getting if you don’t want to have to run my code to see the error.


I’ve solved the issue. I was drawing a single line for each degree in the circle. In the solution, I define the space at a finer resolution (using numpy’s function np.arange(0, 360, 0.3)) and then looped over each item in this vector and drew a line for that angle (and associated colour on the hsv scale). The final image looks great.

Having created the array I would recommend drawing a single texture (pass your array to the GratingStim as a texture and add a circle mask). Would be much more efficient computationally than drawing lines in a for-loop. The hard part was creating the HSV texture. Well done on achieving that already. :slight_smile:

1 Like

I couldn’t help myself from doing this to see how it would work. Look away if you want to work it out yourself. :wink:

from psychopy import visual, misc, event
import numpy as np

win = visual.Window()

# If texture res if low you can still get a smooth ring by
# turning interpolation on and having a high anuglar res on the stimulus
textureRes = 64

hsv = np.ones([textureRes,textureRes,3], dtype=float)
hsv[:,:,0] = np.linspace(0,360,textureRes, endpoint=False)
hsv[:,:,1] = 1
hsv[:,:,2] = 1
rgb = misc.hsv2rgb(hsv)

#mask gives the fraction of the that is visible
mask = np.zeros([100,1])
mask[-10:] = 1  # 10% of the radius is 1 (visible)
# annoyingly with interpolate=True the mask outer edge can 
# get blended with innermost pixel

stim = visual.RadialStim(win, tex=rgb, 
                        mask = mask,
                        angularRes=256, angularCycles=1, 


Fantastic! I don’t think I would have come to a solution this way (not until I am much more familiar with Python / Psychopy), so this is excellent! Thanks so much Jon.

This thread was very useful for coding up an interactive color wheel which returns the color picked by a participant so I thought I would share what I ended up with in case it’s useful to future readers.