'ValueError: num must be 1 <= num <= 5, not 0 error

I am stuck with this code written in py2 on psychopy. I am not an expert with coding.

I am trying to run the function "analyzeStaircases(stairs, stairInfo['AverageReversals'])" , but I obtain this error:

Traceback (most recent call last):
      File "C:\Users\OneDrive\Desktop\testpy\psychoflicker-master\src\trackingExperiment2StaircaseBACKUP.py", line 611, in <module>
        startExperiment()
      File "C:\Users\OneDrive\Desktop\testpy\psychoflicker-master\src\trackingExperiment2StaircaseBACKUP.py", line 605, in startExperiment
        analyzeStaircases(stairs, stairInfo['AverageReversals'])
      File "C:\Users\OneDrive\Desktop\testpy\psychoflicker-master\src\common\analyzeStaircases.py", line 40, in analyzeStaircases
        pylab.subplot(1,nStairs,stairIndex)
      File "C:\Program Files\PsychoPy2\lib\site-packages\matplotlib\pyplot.py", line 1044, in subplot
        a = fig.add_subplot(*args, **kwargs)
      File "C:\Program Files\PsychoPy2\lib\site-packages\matplotlib\figure.py", line 1021, in add_subplot
        a = subplot_class_factory(projection_class)(self, *args, **kwargs)
      File "C:\Program Files\PsychoPy2\lib\site-packages\matplotlib\axes\_subplots.py", line 64, in __init__
        maxn=rows*cols, num=num))
    ValueError: num must be 1 <= num <= 5, not 0

This is a part of the main script where the function is contained:

            elif np.random.rand() < 0.5:
            catchCondition = copy.deepcopy(thisCondition)
            if thisCondition['Side'] == 'Left':
                catchCondition['Side'] = 'Right'
            else:
                catchCondition['Side'] = 'Left'
            # print "0.5 catch trial, showing ", catchCondition['Side'], "
            # instead of ", thisCondition['Side']
            trackingTrial(
                win, expInfo, speedValue, catchCondition, expInfo['SimulationMode'])
        else:
            thisResp = trackingTrial(
                win, expInfo, speedValue, thisCondition, expInfo['SimulationMode'])
            if thisResp is not None:
                # print speedValue, thisCondition, nTrial
                stairs.addData(not thisResp)
            else:
                raise
        nTrial = nTrial + 1
        stairs.saveAsText(outputfile)
    # Finally save the results of the experiment
    stairs.saveAsText(outputfile)
    # stairs.saveAsExcel(outputfile)
    stairs.saveAsPickle(outputfile)
    experiment_finished(win)
except:
    stairs.saveAsText(outputfile)
    # stairs.saveAsExcel(outputfile)
    stairs.saveAsPickle(outputfile)
    win.close()
    raise

analyzeStaircases(stairs, stairInfo['AverageReversals'])

################################
# The experiment starts here  #
###############################
if __name__ == "__main__":
    startExperiment()

This is the code of the function analyzeStaircases

from psychopy import data
import pylab
from numpy import average,std

def analyzeStaircases(stairs,nReversals):

allIntensities,allResponses=[],[]
nStairs=0
for  s in stairs.staircases:
    allIntensities.append( s.intensities )
    allResponses.append( s.data )
    nStairs=nStairs+1

lines, names = [],[]
for stairIndex, thisStair in enumerate(allIntensities):
    pylab.subplot(1,nStairs,stairIndex)
    rev = stairs.staircases[stairIndex].reversalIntensities
    intens = stairs.staircases[stairIndex].intensities
    pylab.title('Threshold='+str(average(rev[(len(rev)-nReversals):len(rev)])))
    pylab.plot(intens, 'o-',label=stairs.staircases[stairIndex].condition['label'])
    pylab.xlabel('Trial')
    pylab.grid()
    pylab.ylabel('Speed [cm/s]')
    pylab.legend()

pylab.show()

At the beginning of the main code I imported the functions as follow:

import numpy as np
from random import randrange
from common.psycho_init import open_window, setup_monitor
from common.psycho_init import experiment_finished
from common.psycho_init import set_output_file, save_experimental_settings
from common.show_instructions import show_instructions
from common.__init__ import analyzeStaircases
from psychopy import core
from common import Ball

Any suggestion?

EDIT

The error seems to be here

 File "C:\Users\OneDrive\Desktop\testpy\psychoflicker-master\src\common\analyzeStaircases.py", line 40, in analyzeStaircases
        pylab.subplot(1,nStairs,stairIndex)

I checked the subplot.py file and I found this

        self.figure = fig

    if len(args) == 1:
        if isinstance(args[0], SubplotSpec):
            self._subplotspec = args[0]
        else:
            try:
                s = str(int(args[0]))
                rows, cols, num = list(map(int, s))
            except ValueError:
                raise ValueError(
                    'Single argument to subplot must be a 3-digit '
                    'integer')
            self._subplotspec = GridSpec(rows, cols)[num - 1]
            # num - 1 for converting from MATLAB to python indexing
    elif len(args) == 3:
        rows, cols, num = args
        rows = int(rows)
        cols = int(cols)
        if isinstance(num, tuple) and len(num) == 2:
            num = [int(n) for n in num]
            self._subplotspec = GridSpec(rows, cols)[num[0] - 1:num[1]]
        else:
            if num < 1 or num > rows*cols:
                raise ValueError(
                    "num must be 1 <= num <= {maxn}, not {num}".format(
                        maxn=rows*cols, num=num))
            self._subplotspec = GridSpec(rows, cols)[int(num) - 1]
            # num - 1 for converting from MATLAB to python indexing
    else:
        raise ValueError('Illegal argument(s) to subplot: %s' % (args,))

    self.update_params()


Solution 1:[1]

Your code inside a function must be indented in python, as follow from psychopy import data import pylab from numpy import average,std

def analyzeStaircases(stairs,nReversals):

    allIntensities,allResponses=[],[]
    nStairs=0
    for  s in stairs.staircases:
        allIntensities.append( s.intensities )
        allResponses.append( s.data )
        nStairs=nStairs+1
    
    lines, names = [],[]
    for stairIndex, thisStair in enumerate(allIntensities):
        pylab.subplot(1,nStairs,stairIndex)
        rev = stairs.staircases[stairIndex].reversalIntensities
        intens = stairs.staircases[stairIndex].intensities
        pylab.title('Threshold='+str(average(rev[(len(rev)-nReversals):len(rev)])))
        pylab.plot(intens,'o-',label=stairs.staircases[stairIndex].condition['label'])
        pylab.xlabel('Trial')
        pylab.grid()
        pylab.ylabel('Speed [cm/s]')
        pylab.legend()
    
    pylab.show()

Also please send full traceback, with "ValueError" :)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Powi