# Best way to create and display many image stimuli simultaneously in Builder

**URL:** <https://discourse.psychopy.org/t/best-way-to-create-and-display-many-image-stimuli-simultaneously-in-builder/43043>\
**Category:** Builder\
**Created:** [November 22, 2024, 9:46am UTC](https://discourse.psychopy.org/t/best-way-to-create-and-display-many-image-stimuli-simultaneously-in-builder/43043 "2024-11-22T09:46:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mz973](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/mz973/32/43410_2.png) [@mz973](https://discourse.psychopy.org/u/mz973)\
**Post date:** [November 22, 2024, 9:46am UTC](https://discourse.psychopy.org/t/best-way-to-create-and-display-many-image-stimuli-simultaneously-in-builder/43043/1 "2024-11-22T09:46:54Z")

</div>

If this template helps then use it. If not then just delete and start from scratch.

**OS** : Win10  
**PsychoPy version** (e.g. 1.84.x): 2023.2.3  
**Standard Standalone? (y/n)** yes  
\*\*What are you trying to achieve?:  
Displaying 16 images on screen while controlling them from a condition list

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

OK, this is going to be a list of related questions.

1. Initially I thought I could create one ImageStimuli component, and just use deepcopy() to duplicate it in a code component and flexibly set the file names. This didn’t work due to error:

```auto
File "C:\Users\AppData\Local\Programs\PsychoPy\lib\socket.py", line 272, in __getstate__
    raise TypeError(f"cannot pickle {self. __class__. __name__!r} object")
TypeError: cannot pickle 'socket' object

```

Seems that ImageStimuli is not copiable?

1. Then I tried creating all stimuli inside a code component (image = visual.ImageStim()), this resulted in nothing, no error message, no image shown.  
Looking into the script it generated, I found that compared to the one generated by using the Image component, there are chunks of code missing, specifically:

```auto
    image_displayComponents = [image]
    for thisComponent in image_displayComponents:
        thisComponent.tStart = None
        thisComponent.tStop = None
        thisComponent.tStartRefresh = None
        thisComponent.tStopRefresh = None
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED
    # reset timers
    t = 0
    _timeToFirstFrame = win.getFutureFlipTime(clock="now")
    frameN = -1
    
    # --- Run Routine "image_display" ---
    routineForceEnded = not continueRoutine
    while continueRoutine and routineTimer.getTime() < 5.0:
        # get current time
        t = routineTimer.getTime()
        tThisFlip = win.getFutureFlipTime(clock=routineTimer)
        tThisFlipGlobal = win.getFutureFlipTime(clock=None)
        frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
        # is it time to end the Routine? (based on local clock)
        if tThisFlip > 5-frameTolerance:
            continueRoutine = False
        
        # *image* updates
        
        # if image is starting this frame...
        if image.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
            # keep track of start time/frame for later
            image.frameNStart = frameN # exact frame index
            image.tStart = t # local t and not account for scr refresh
            image.tStartRefresh = tThisFlipGlobal # on global time
            win.timeOnFlip(image, 'tStartRefresh') # time at next scr refresh
            # add timestamp to datafile
            thisExp.timestampOnFlip(win, 'image.started')
            # update status
            image.status = STARTED
            image.setAutoDraw(True)
        
        # if image is active this frame...
        if image.status == STARTED:
            # update params
            pass
        
        # if image is stopping this frame...
        if image.status == STARTED:
            # is it time to stop? (based on global clock, using actual start)
            if tThisFlipGlobal > image.tStartRefresh + 1.0-frameTolerance:
                # keep track of stop time/frame for later
                image.tStop = t # not accounting for scr refresh
                image.frameNStop = frameN # exact frame index
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'image.stopped')
                # update status
                image.status = FINISHED
                image.setAutoDraw(False)

```

I’m not sure why Builder doesn’t handle manually created ImageStimuli the same way as its prebuilt component equivalent? Can I even realisticly do that in custom code?

I know I can always click Image component 16 times but thought I would ask since it’s an intriguing question. Thank you if you have read through the question.

Mengya  
.

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [November 22, 2024, 9:57am UTC](https://discourse.psychopy.org/t/best-way-to-create-and-display-many-image-stimuli-simultaneously-in-builder/43043/2 "2024-11-22T09:57:20Z")

</div>

How I do this is create a list of visual objects in the Begin Experiment tab of a code component.

> **[PsychoPy Code Component Snippets](https://docs.google.com/document/d/1kclYKgpbOCT3X8_O5pQOEIQHvD6zqMyxz3IKv3-K73I/edit?tab=t.0#heading=h.z0ghlzganqwm)**
>
> PsychoPy version 2020.2.10Code Component Snippets Compiled by Wakefield Morys-Carter, Oxford Brookes UniversityPlease share widely and follow Psych\_Stats on twitter. Code components should be Auto Py-&gt;JS unless code has been added to the PsychoJS...

```auto
images = []
for Idx in range(16):
     images.append( visual.ImageStim(
    win=win,
    name='imageName'+str(Idx), 
    image='imagePath'+str(Idx)+'.png', 
    ori=0, 
    pos=[0,0], 
    size=[.2,.2],
    color=white, 
    colorSpace='rgb', 
    opacity=1,
    flipHoriz=False, 
    flipVert=False,
    texRes=128, 
    interpolate=True))

```

Then in Begin Routine I can use:

```auto
for Idx in range(16):
     images[Idx].setPos(position[Idx]) # There are other ways of setting the positions but having a list is one possibility
     images[Idx].setAutoDraw(True)

```

and End Routine

```auto
for Idx in range(16):
     images[Idx].setAutoDraw(False)

```

---

<div class="post-metadata">

**Author:** ![mz973](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/mz973/32/43410_2.png) [@mz973](https://discourse.psychopy.org/u/mz973)\
**Post date:** [November 25, 2024, 2:35am UTC](https://discourse.psychopy.org/t/best-way-to-create-and-display-many-image-stimuli-simultaneously-in-builder/43043/3 "2024-11-25T02:35:35Z")

</div>

Hi thank you! This works now. The key seems to be adding setAutoDraw(False) at the end of routine.
