Search code examples
pythonlistpsychopy

Changing text and image stimuli according to lists


What I'm trying to do is present participants with a word of the animal and an image of an animal. Sometimes the word and image will match, sometimes they won't and participants have to respond to the name of the animal. What I am struggling with is presenting the text and the images.

So...

I have a list of animals:

animal_words =[ 'gorilla', 'Ostrich', 'Snake', 'Panda']

I then have an image of an animal, which are the same as the colours above

animal_image=[ 'gorilla', 'Ostrich', 'Snake', 'Panda']

I have two conditions: same and different. I have sorted the above lists into same and different. The same condition will be presented to participants 10 times and the different condition will be presented 5.I've put them together into a trial list.

same=[]
different[]
conditions=[]

for animal in animals:
for image in animal_images:
    if animal == image:
        same.extend([[animal,image]]* 10)
    else:  
        different.extend ([[animal,image]] * 5)

shuffle (same)
shuffle (different)

#combine conditions into trial list
conditions=[same,different]

An example of the same condition is:

[Gorilla (text) , Gorilla (image)]

I then create my window and stimuli:

from psychopy import visual, event, core, gui

win=visual.Window([1024,768], fullscr=False,allowGUI=True, units='pix',\
color= (-1,-1,-1))

tstim=visual.TextStim(win, text='', pos=(0,0), color= ((0,0,0)))
imstim=visual.ImageStim(win, image='', pos=(0,0)

What I need to do is assign the animal text to tstim and the animal_image to imstim and set a loop so that they change according to the lists that I've made. I haven't been able to successfully do this, as the lists are stuck together. I also don't know how to set up the loop The below code is my best guess for how the loop should look:

for a in conditions:
     tstim.setText(animal_name)
     imstim.setImage(animal_image)
     tstim.draw()
     imstim.draw()
     win.flip()
     core.wait()

However, I don't think that loop is right but I can't think of anything else. Any help would be appreciated


Solution

  • You're on the right track. It's a good a idea to have a nested list, where each sublist contains the pair for the trial. I would suggest creating a nested list with image and text stimuli, and then running through that list of stimuli. I demonstrate this below (untested).

    import random
    from psychopy import visual, event, core, gui
    
    animal_words = ['Gorilla', 'Ostrich', 'Snake', 'Panda']
    animal_images = ['Gorilla', 'Ostrich', 'Snake', 'Panda']
    
    win = visual.Window(
        [1024, 768], fullscr=False, allowGUI=True, units='pix',
        color=(-1, -1, -1))
    
    # Create list of trials
    trials = []
    for animal in animal_words:
        for image in animal_images:
            # Get the filepath to the animal image.
            image_file = "{}.png".format(image)
            # Instantiate the stimulus objects.
            stim_pair = [
                visual.TextStim(win, text=animal, pos=(0, 0), color=(0, 0, 0)),
                visual.ImageStim(win, image=image_file, pos=(0, 0))
            ]
            # Add stimulus objects to growing list of trials.
            if animal == image:
                trials.extend([stim_pair] * 10)
            else:
                trials.extend([stim_pair] * 5)
    
    random.shuffle(trials)
    
    # Run trials
    for text, image in trials:
        text.draw()
        image.draw()
        win.flip()
        core.wait()
    

    If all the trials are the same (just in a different order), then you can save the text and image filepath in a spreadsheet, read the spreadsheet into a list, create the stim objects, and shuffle that list. This would be instead of creating the list on each run.