PsychoPy is a free, open-source application for running psychology and neuroscience experiments. It’s written in Python and provides precise control over stimulus presentation timing, essential for behavioral research and human/animal experiments.
Why PsychoPy?
- Precise Timing: Millisecond-accurate stimulus presentation
- Flexible: Python scripting for complex designs
- Hardware Support: Interfaces with response boxes, eye trackers, EEG, fMRI
- Cross-Platform: Runs on Windows, macOS, and Linux
- GUI & Code: Use Builder interface or write Python scripts
Key Features
Stimulus Presentation
from psychopy import visual, core, event
# Create window
win = visual.Window(size=(800, 600), fullscr=False)
# Create stimuli
fixation = visual.TextStim(win, text='+')
image = visual.ImageStim(win, image='stimulus.png')
# Present sequence
fixation.draw()
win.flip()
core.wait(0.5)
image.draw()
win.flip()
core.wait(2.0)
Response Collection
from psychopy import event
# Wait for keyboard response
keys = event.waitKeys(keyList=['left', 'right', 'escape'])
# Get reaction time
rt_clock = core.Clock()
keys = event.waitKeys(keyList=['space'], timeStamped=rt_clock)
Experiment Flow
# Trial structure
for trial in range(n_trials):
# Present stimulus
stim.draw()
win.flip()
trial_clock.reset()
# Collect response
keys = event.waitKeys(
keyList=['left', 'right'],
timeStamped=trial_clock
)
# Save data
data.append({
'trial': trial,
'response': keys[0][0],
'rt': keys[0][1]
})
Hardware Integration
# Parallel port for triggers
from psychopy import parallel
port = parallel.ParallelPort(address=0x0378)
port.setData(1) # Send trigger
# Serial port for devices
from psychopy import serial
arduino = serial.Serial('COM3', baudrate=9600)
Builder Interface
PsychoPy Builder provides a graphical interface:
- Drag-and-drop components
- Visual timeline of experimental flow
- Generate Python code automatically
- Good for standard experimental designs
Coder Interface
For complex experiments, write Python directly:
- Full control over experiment logic
- Custom stimulus generation
- Advanced timing control
- Integration with data analysis
Common Experimental Paradigms
Visual Search
# Display array of items
# Record search time and accuracy
N-Back Task
# Present sequence of stimuli
# Detect matches N items back
Oddball Paradigm
# Standard and deviant stimuli
# For ERP studies
Reaction Time Tasks
# Measure speed of response to stimuli
# Simple or choice RT
Getting Started
Install PsychoPy:
# Standalone application (recommended for beginners)
# Download from psychopy.org
# Or install via pip
pip install psychopy
Simple experiment:
from psychopy import visual, core, event
# Setup
win = visual.Window()
msg = visual.TextStim(win, text='Press space to start')
# Welcome screen
msg.draw()
win.flip()
event.waitKeys(keyList=['space'])
# Run trial
stim = visual.TextStim(win, text='Stimulus')
stim.draw()
win.flip()
core.wait(1.0)
# Cleanup
win.close()
core.quit()
Best Practices
Timing
- Use
win.flip()for frame-accurate timing - Call
win.flip()regularly to avoid dropped frames - Test timing with photodiode
- Use
StaticPeriodfor non-drawing operations
Data Saving
- Save data incrementally (after each trial)
- Use structured formats (CSV, JSON)
- Include timestamps and metadata
- Back up data files
Stimulus Preparation
- Pre-load stimuli before experiment
- Use appropriate image formats
- Consider display refresh rate
- Test on actual experimental setup
Tips
- Always pilot experiments thoroughly
- Use
loggingmodule for debugging - Test on the actual experimental computer
- Validate timing with external measurement
- Keep experiment scripts under version control
- Document experimental parameters clearly
- Use try/except to handle errors gracefully
- Include informed consent and debriefing screens