psychopy.org | Reference | Downloads | Github

Method to copy a visual object?

At initialization I wish to create a visual.ImageStim with a certain pos as such

stim = visual.ImageStim(WIN, # capitalized variables are global const
            image=os.path.join(STIMULI_PATH, filename + '.png'), 
            pos = LEFT_POS
        )

I also wish to place this same image at other locations. I would create an array to hold these stimuli with the different locations and then loop through them to draw them later. However, the following of course does not work as the position of each item in the stimuli array will simply have the last assigned pos

stimuli = []
stimuli.append(stim)
stim.pos = RIGHT_POS
stimuli.append(stim)
stim.pos = LEFT_POS
stimuli.append(stim)
# etc etc

I could simply recreate the visual.imageStim multiple times with different pos parameters, but I assume that loading in the same image is inefficient (is it? Perhaps there’s some magic under the hood?). Is there something possible that would achieve the following?

stim = stim.copy() # identical copy, but different object
stim.pos = RIGHT_POS # now changing `pos` does not change the original stim.pos

Not sure if you can copy a visual stim object like that, but if you want to show the same image at multiple locations on the screen at once you could do:

stim = visual.ImageStim(WIN, # capitalized variables are global const
            image=os.path.join(STIMULI_PATH, filename + '.png'), 
            pos = LEFT_POS
        )

# draw tthe image at both LEFT_POS and RIGHT_POS
for pos in [LEFT_POS, RIGHT_POS]:
    stim.pos = pos
    stim.draw()

# display the updated screen gfx
WIN.flip()

I thought I mentioned this in the original question, but it seems like I did not. My bad!

I considered this solution, which probably be the best option. However in my case not all stimuli will be presented at all locations. I could create another variable to define the locations etc and access the locations at each trial but I’m afraid that in my case this will very quickly becomes very messy.

That’s why I’d prefer to define all the trials at initialization, shuffle and divide trials etc. Then I could just keep the actual trial very neat.

trial = TRIALS[trialNum]
for stim in trial:
  stim.draw()
WIN.flip()

As such I would still like to copy an object without having to redefine it.

What I do is append visual.ImageStim definitions to an array and then set autodraw to true for the ones I want in a particular trial.

If you look at my interactive slider demo you’ll see that I have an array containing both shapes and text, and in my Affect Grid demo I create a grid programmatically.