问题描述
我正在PsychoPy(版本1.84.2)中编写一项任务,参与者必须对某些光栅之间的对比度差异(例如-1和1之间的值)进行评分。我使用visual.RatingScale设计了一个评分量表。现在我想请参与者在量表上再添加两个标记,以表示他们的置信区间。甚至更好:参与者可以使用鼠标的滚轮来调整间隔的宽度。
是否有可能这样做?
代码:
from __future__ import absolute_import,division
from psychopy import locale_setup,gui,visual,core,data,event,logging,sound
from psychopy.constants import (NOT_STARTED,STARTED,PLAYING,PAUSED,STOPPED,FINISHED,PRESSED,RELEASED,FOREVER)
import numpy as np # whole numpy lib is available,prepend 'np.'
from numpy import (sin,cos,tan,log,log10,pi,average,sqrt,std,deg2rad,rad2deg,linspace,asarray)
from numpy.random import random,randint,normal,shuffle
import os # handy system and path functions
import sys # to get file system encoding
# Ensure that relative paths start from the same directory as this script
_thisDir = os.path.dirname(os.path.abspath(__file__)).decode(sys.getfilesystemencoding())
os.chdir(_thisDir)
# Store info about the experiment session
expName = u'rating' # from the Builder filename that created this script
expInfo = {'participant':'','session':'001'}
dlg = gui.DlgFromDict(dictionary=expInfo,title=expName)
if dlg.OK == False:
core.quit() # user pressed cancel
expInfo['date'] = data.getDateStr() # add a simple timestamp
expInfo['expName'] = expName
# Data file name stem = absolute path + name; later add .psyexp,.csv,.log,etc
filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'],expName,expInfo['date'])
# An ExperimentHandler isn't essential but helps with data saving
thisExp = data.ExperimentHandler(name=expName,version='',extraInfo=expInfo,runtimeInfo=None,originPath=None,savePickle=True,saveWideText=True,dataFileName=filename)
# save a log file for detail verbose info
logFile = logging.LogFile(filename+'.log',level=logging.EXP)
logging.console.setLevel(logging.WARNING) # this outputs to the screen,not a file
endExpNow = False # flag for 'escape' or other condition => quit the exp
# Start Code - component code to be run before the window creation
# Setup the Window
win = visual.Window(
size=(1280,800),fullscr=True,screen=0,allowGUI=True,allowStencil=False,monitor='testMonitor',color=[0,0],colorSpace='rgb',blendMode='avg',useFBO=True)
# store frame rate of monitor if we can measure it
expInfo['frameRate'] = win.getActualFrameRate()
if expInfo['frameRate'] != None:
frameDur = 1.0 / round(expInfo['frameRate'])
else:
frameDur = 1.0 / 60.0 # could not measure,so guess
# Initialize components for Routine "trial"
trialClock = core.Clock()
rating = visual.RatingScale(win=win,name='rating',marker=u'triangle',size=1.0,pos=[0.0,0.0],low=-1,high=1,labels=["-1","1"],precision=100,showValue=True,scale=None)
# Create some handy timers
globalClock = core.Clock() # to track the time since experiment started
routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine
# ------Prepare to start Routine "trial"-------
t = 0
trialClock.reset() # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
rating.reset()
# keep track of which components have finished
trialComponents = [rating]
for thisComponent in trialComponents:
if hasattr(thisComponent,'status'):
thisComponent.status = NOT_STARTED
# -------Start Routine "trial"-------
while continueRoutine:
# get current time
t = trialClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *rating* updates
if t >= 0.0 and rating.status == NOT_STARTED:
# keep track of start time/frame for later
rating.tStart = t
rating.frameNStart = frameN # exact frame index
rating.setAutoDraw(True)
continueRoutine &= rating.noResponse # a response ends the trial
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in trialComponents:
if hasattr(thisComponent,"status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
core.quit()
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "trial"-------
for thisComponent in trialComponents:
if hasattr(thisComponent,"setAutoDraw"):
thisComponent.setAutoDraw(False)
# the Routine "trial" was not non-slip safe,so reset the non-slip timer
routineTimer.reset()
# these shouldn't be strictly necessary (should auto-save)
thisExp.saveAsWideText(filename+'.csv')
thisExp.saveAsPickle(filename)
logging.flush()
# make sure everything is closed down
thisExp.abort() # or data files will save again on exit
win.close()
core.quit()
解决方法
我不确定它是否在1.84版本中可用(或者为什么您需要使用PsychoPy的旧版本),但是现在的一般建议是避免使用RatingScale
类,而是使用更简单但可扩展的Slider
类。
无论如何,我建议您避免通过添加额外的标记等来修改该对象。而是创建并绘制一个单独的矩形ShapeStim
对象:
https://www.psychopy.org/api/visual/shapestim.html
根据需要将该矩形的垂直位置设置为一个常数,可以在滑块的上方,下方或后面。在每帧上,将其中心设置为与滑块或等级标尺的标记值相对应。监视鼠标滚轮,并使用其控制矩形的长度,以指示不确定性宽度。