How to randomize placement of multiple images from condition file to set locations in Psychopy Experiment

OS Mac Big Sur 11.2.1:
PsychoPy version 2021.1.4
**Standard Standalone? Y
**What are you trying to achieve?: Randomization of the assignment of multiple (8) images from a condition file into already-specified positions in a 3x3 grid. Basically, what I am trying to do is set up a 3x3 grid for a referential communication experiment (middle square is left intentionally blank so only 8 images), and I would like to have psychopy randomize the image placement rather than hard-coding it in multiple lists worth of condition files.

**What did you try to make it work?:

I’ve tried creating 8 separate image components and assigning them to the various positions in the grid where I want the images to go. Then I added some custom code to get the 8 images from the condition file by accessing the specific columns for the image paths, place them in a list and use the random module to shuffle the list.

Image_List = [distractor1Path,distractor2Path,distractor3Path,distractor4Path,distractor5Path,distractor6Path,target1Path,target2Path, BlackSquarePath]
random.shuffle(Image_List)

If I print this out, I can tell that the code is working because I get something like:
[‘pipe1.png’, ‘pipe2.png’, ‘arrow.png’, ‘skateboard.png’, ‘mixer.png’, ‘can.png’, ‘bone.png’, ‘goggles.png’, ‘blacksquare.png’], for the image list, and then:
[‘mixer.png’, ‘pipe1.png’, ‘arrow.png’, ‘skateboard.png’, ‘goggles.png’, ‘bone.png’, ‘blacksquare.png’, ‘can.png’, ‘pipe2.png’], which is what I want from the randomly shuffled list.

My intent was to have each of the 8 image components correspond to indices from the shuffled list. So for example, the Top Left image in the 3x3 grid would be $Image_List[0], in this case a picture of a mixer, rather than giving it a specific column from the condition file or a specific png file to display. I also tried doing this with the column names from the condition file rather than the image paths to see if that would work, but it also does not because the problem is the same (see below).

What specifically went wrong when you tried that?:
I had this occurring at the beginning of the routine so that it would randomize the images for each trial, but it seems that the assignment of the images to each of the image components occurs earlier in the process than the beginning of the routine, so I was getting an error that Image_List did not exist, as it was created later in the code than the image components (found this out by looking at the python code for what I had made in builder).

However, if I wanted to move the above code snippet to before the part of the psychopy code that set up each of the image components, then it wouldn’t be able to get individual trial data, because it’s at the beginning of the experiment instead of being before each trial.

I’m wondering if this is possible to do in the way I had started out with, or if I will need to do something at the very beginning of the experiment to set the randomized lists for all pictures on all trials at once. Is it even possible to do this all at the beginning of the experiment and then have it stored for each of the trials ahead of time? I was thinking of maybe setting up a dictionary where the key is the trial number from the condition file, and then the value for it is the shuffled list of image paths, but I’m not sure if that can be done ahead of time and then used on each trial.

If anyone has suggestions for how to set it up that need to be done in coder I’m more than open to that - I can use it, I prefer builder to set up the bulk of the experiment because it’s faster, but I’ve used coder to add snippets of specialized code in the past (but not for anything as complicated as this is turning out to be).

If anyone also knows of examples that have done something like this or similar, please let me know - I wasn’t quite sure what to search for this topic and nothing in the suggested similar topics quite got at this, since I have the specific grid positions picked out and hard-coded for the image positions, I just want to randomly assign which of the images go to each of the positions for each trial.

I’ve also uploaded a screenshot of the basic format of my condition file and the builder setup. The basic premise of the experiment works and runs if I use the column names for each of the image positions, but I am hoping to randomize which columns go to which of the positions on each of the trials, so that I can avoid having to make multiple lists to vary all of that.


Since your image components are set to update every repeat and your code component is above them then code in the Begin Routine tab will be processed before the images are set.

In situations where I want a target images plus distractors I usually fix the contents of each image component (referring to a column in the Excel for example) and then shuffle the coordinates in Begin Routine. This means that I can check for a mouse response to the Target image without worrying about its location.

Ahh yes this makes much more sense than what I was trying to do! Thank you for the suggestion