Beispiel #1
0
def summarize(path):
    fig = plt.figure()

    # Frame rate
    ax = fig.add_subplot(331)
    vidtime = np.genfromtxt(os.path.join(path, 'Analysis/videotime.csv'))
    ax.hist(1.0 / np.diff(vidtime), 100, normed=True)
    ax.set_title('frame rate')
    ax.set_xlabel('fps')

    # Trajectories
    ax = fig.add_subplot(332)
    rawtraj = trajectories.genfromtxt(path)
    rawtraj = trajectories.trajectories(rawtraj.data, rawtraj.slices[1:])
    rawtraj = trajectories.scale(rawtraj)
    croph = [
        200 * trajectories.width_pixel_to_cm,
        1000 * trajectories.width_pixel_to_cm
    ]
    traj = trajectories.crop(rawtraj, croph)
    for t in traj.tolist():
        ax.plot(t[:, 0], t[:, 1], 'k', alpha=0.2)
    ax.set_title('trajectories')
    ax.set_xlabel('x (cm)')
    ax.set_ylabel('y (cm)')
    trajax = ax

    # Draw trial selection
    selecthandles = []
    trajfilter = []
    conditionfilter = []

    def updateselection():
        if len(trajfilter) > 0:
            ind = trajfilter
            if len(conditionfilter) > 0:
                ind = list(set(ind).intersection(conditionfilter))
        else:
            ind = conditionfilter

        selector.ind[:] = ind
        sselector.ind[:] = ind
        selector.updateselection()
        sselector.updateselection()
        while len(selecthandles) > 0:
            handle = selecthandles.pop()
            if np.iterable(handle):
                for l in handle:
                    l.remove()
                    del l
            del handle

        for s in traj.slices[ind]:
            h1 = trajax.plot(traj.data[s, 0], traj.data[s, 1], 'r', alpha=0.5)
            h2 = activityax.plot(trialsteps_x[ind, :], trialsteps[ind, :],
                                 'r.')
            h3 = slipax.plot(trialslips_x[ind, :], trialslips[ind, :], 'rx')
            selecthandles.append(h1)
            selecthandles.append(h2)
            selecthandles.append(h3)

    def onselect(ind):
        trajfilter[:] = ind
        updateselection()

    # Trajectory features
    ax = fig.add_subplot(333)
    selector = trajectoryfeatures(traj, vidtime, ax, onselect)

    # Reward rate
    ax = fig.add_subplot(334)
    lr = np.atleast_1d(
        np.genfromtxt(os.path.join(path, 'left_rewards.csv'), dtype=str))
    rr = np.atleast_1d(
        np.genfromtxt(os.path.join(path, 'right_rewards.csv'), dtype=str))
    rewards = np.sort(np.concatenate((lr, rr)))
    rewardtimes = [dateutil.parser.parse(t) for t in rewards]
    rewardinterval = np.array(
        [d.total_seconds() for d in np.diff(rewardtimes)])
    ax.plot(rewardinterval)
    ax.set_title('reward rate')
    ax.set_xlabel('trials')
    ax.set_ylabel('inter-reward interval (s)')

    # Summary statistics (Top)
    ax = fig.add_subplot(335)
    avgsdvheight = np.array([(np.mean(t[:, 1]), np.std(t[:, 1]))
                             for t in traj.tolist()])
    ax.boxplot(avgsdvheight)
    ax.set_ylabel('height (cm)')

    # Slowdown
    ax = fig.add_subplot(336)
    speed = trajectories.speed(traj, vidtime)
    midbounds = np.array([425, 850]) * trajectories.width_pixel_to_cm
    midpoints = [
        traj.data[s, 0] > midbounds[0]
        if traj.data[s.stop, 0] > traj.data[s.start, 0] else
        traj.data[s, 0] < midbounds[1] for s in traj.slices
    ]
    #    midpoints = [(t[:,0] > midbounds[0]) & (t[:,0] < midbounds[1])
    #    for t in traj.tolist()]
    midspeed = np.array(
        [np.abs(np.mean(t[v, 0])) for t, v in zip(speed.tolist(), midpoints)])
    edgespeed = np.array(
        [np.abs(np.mean(t[~v, 0])) for t, v in zip(speed.tolist(), midpoints)])
    print edgespeed
    pts = ax.scatter(edgespeed,
                     midspeed,
                     s=10,
                     marker='D',
                     facecolors='b',
                     edgecolors='none')
    pltutils.regressionline(edgespeed, midspeed, ax, color='k')
    sselector = CollectionSelector(ax,
                                   pts,
                                   color_other='r',
                                   onselection=onselect)
    ax.set_title('slowdown')
    ax.set_xlabel('entry speed (cm / s)')
    ax.set_ylabel('exit speed (cm / s)')

    # Summary statistics (Bottom)
    #    ax = fig.add_subplot(338)
    #    speed = trajectories.speed(traj,vidtime)
    #    avgsdvspeed = np.array([(np.abs(np.mean(t[:,0])),np.std(t[:,0])) for t in speed.tolist()])
    #    ax.boxplot(avgsdvspeed)
    #    ax.set_ylabel('speed (cm / s)')

    # Step activity
    ax = fig.add_subplot(337)
    stepactivity = np.genfromtxt(
        os.path.join(path, 'Analysis/step_activity.csv'))
    trialsteps = np.array(
        [np.sum(stepactivity[s, :], axis=0) for s in traj.slices])
    stepnumbers = np.arange(8) + 1
    trialsteps_x = np.tile(stepnumbers, (trialsteps.shape[0], 1))
    ax.plot(trialsteps_x, trialsteps, 'k.')
    ax.set_title('stepping')
    ax.set_xlabel('step')
    ax.set_xlim(0, len(stepnumbers) + 1)
    ax.set_xticks(stepnumbers)
    activityax = ax

    # Slips
    ax = fig.add_subplot(338)
    slipactivity = np.genfromtxt(
        os.path.join(path, 'Analysis/slip_activity.csv'))
    trialslips = np.array(
        [np.sum(slipactivity[s, :], axis=0) for s in traj.slices])
    gapnumbers = np.arange(7) + 1
    trialslips_x = np.tile(gapnumbers, (trialslips.shape[0], 1))
    ax.plot(trialslips_x, trialslips, 'kx')
    ax.set_title('slips')
    ax.set_xlabel('gap')
    ax.set_xlim(0, len(gapnumbers) + 1)
    ax.set_xticks(gapnumbers)
    slipax = ax

    # Trial conditions (WARNING! CONSIDER STEP STATE WRAPAROUND!!)
    ax = fig.add_subplot(339)
    width = 0.39
    trialindices = trials.gettrialindices(path)
    steptrialpath = os.path.join(path, 'step{0}_trials.csv')
    stepstates = np.array([
        trials.gettrialstate(str.format(steptrialpath, i), trialindices)
        for i in xrange(1, 7)
    ]).T
    steptrialstate = np.array([stepstates[s.start, :] for s in traj.slices])
    fractionstabletrials = np.sum(steptrialstate, axis=0) / float(
        steptrialstate.shape[0])
    fractionstabletrials = np.insert(fractionstabletrials,
                                     [0, stepstates.shape[1]], 1)
    unstablebars = ax.bar(stepnumbers,
                          np.ones(stepnumbers.shape),
                          width,
                          color='r')
    stablebars = ax.bar(stepnumbers, fractionstabletrials, width, color='g')
    ax.set_title('manipulations')
    ax.set_xlabel('step')
    ax.set_xlim(0 + width / 2., len(stepnumbers) + 1 + width / 2.)
    ax.set_xticks(stepnumbers + width / 2.)
    ax.set_xticklabels(stepnumbers)
    conditionax = ax

    # Select trial conditions
    def selectstepindices(evt, bars, trialstate):
        try:
            step = next(i - 1 for i, bar in enumerate(bars)
                        if bar.contains(evt)[0])
        except StopIteration:
            return []

        if step >= 0 and step < trialstate.shape[1]:
            ind = np.nonzero(trialstate[:, step])[0]
        else:
            ind = range(trialstate.shape[0])
        return ind

    notsteptrialstate = np.bitwise_not(steptrialstate)

    def onbuttonpress(evt):
        if evt.inaxes == conditionax:
            ind = selectstepindices(evt, stablebars, steptrialstate)
            if len(ind) == 0:
                ind = selectstepindices(evt, unstablebars, notsteptrialstate)
            conditionfilter[:] = ind
            updateselection()

    ax.figure.canvas.mpl_connect('button_press_event', onbuttonpress)

    plt.tight_layout(pad=0.5)
    return rawtraj, traj, vidtime, stepactivity, selector, sselector
def summarize(path):
    fig = plt.figure()

    # Frame rate
    ax = fig.add_subplot(331)
    vidtime = np.genfromtxt(os.path.join(path, 'Analysis/videotime.csv'))
    ax.hist(1.0 / np.diff(vidtime),100,normed=True)
    ax.set_title('frame rate')
    ax.set_xlabel('fps')
    
    # Trajectories
    ax = fig.add_subplot(332)
    rawtraj = trajectories.genfromtxt(path)
    rawtraj = trajectories.trajectories(rawtraj.data,rawtraj.slices[1:])
    rawtraj = trajectories.scale(rawtraj)
    croph = [200*trajectories.width_pixel_to_cm,1000*trajectories.width_pixel_to_cm]
    traj = trajectories.crop(rawtraj,croph)
    for t in traj.tolist():
        ax.plot(t[:,0],t[:,1],'k',alpha=0.2)
    ax.set_title('trajectories')
    ax.set_xlabel('x (cm)')
    ax.set_ylabel('y (cm)')
    trajax = ax
    
    # Draw trial selection
    selecthandles = []
    trajfilter = []
    conditionfilter = []
    def updateselection():
        if len(trajfilter) > 0:
            ind = trajfilter
            if len(conditionfilter) > 0:
                ind = list(set(ind).intersection(conditionfilter))
        else:
            ind = conditionfilter
        
        selector.ind[:] = ind
        sselector.ind[:] = ind
        selector.updateselection()
        sselector.updateselection()
        while len(selecthandles) > 0:
            handle = selecthandles.pop()
            if np.iterable(handle):
                for l in handle:
                    l.remove()
                    del l
            del handle
        
        for s in traj.slices[ind]:
            h1 = trajax.plot(traj.data[s,0],traj.data[s,1],'r',alpha=0.5)
            h2 = activityax.plot(trialsteps_x[ind,:],trialsteps[ind,:],'r.')
            h3 = slipax.plot(trialslips_x[ind,:],trialslips[ind,:],'rx')
            selecthandles.append(h1)
            selecthandles.append(h2)
            selecthandles.append(h3)
            
    def onselect(ind):
        trajfilter[:] = ind
        updateselection()
    
    # Trajectory features
    ax = fig.add_subplot(333)
    selector = trajectoryfeatures(traj,vidtime,ax,onselect)
    
    # Reward rate
    ax = fig.add_subplot(334)
    lr = np.atleast_1d(np.genfromtxt(os.path.join(path, 'left_rewards.csv'), dtype=str))
    rr = np.atleast_1d(np.genfromtxt(os.path.join(path, 'right_rewards.csv'), dtype=str))    
    rewards = np.sort(np.concatenate((lr,rr)))
    rewardtimes = [dateutil.parser.parse(t) for t in rewards]
    rewardinterval = np.array([d.total_seconds() for d in np.diff(rewardtimes)])
    ax.plot(rewardinterval)
    ax.set_title('reward rate')
    ax.set_xlabel('trials')
    ax.set_ylabel('inter-reward interval (s)')
    
    # Summary statistics (Top)
    ax = fig.add_subplot(335)
    avgsdvheight = np.array([(np.mean(t[:,1]),np.std(t[:,1])) for t in traj.tolist()])
    ax.boxplot(avgsdvheight)
    ax.set_ylabel('height (cm)')
    
    # Slowdown
    ax = fig.add_subplot(336)
    speed = trajectories.speed(traj,vidtime)
    midbounds = np.array([425,850]) * trajectories.width_pixel_to_cm
    midpoints = [traj.data[s,0] > midbounds[0]
    if traj.data[s.stop,0] > traj.data[s.start,0]
    else traj.data[s,0] < midbounds[1]
    for s in traj.slices]
#    midpoints = [(t[:,0] > midbounds[0]) & (t[:,0] < midbounds[1])
#    for t in traj.tolist()]
    midspeed = np.array([np.abs(np.mean(t[v,0]))
    for t,v in zip(speed.tolist(),midpoints)])
    edgespeed = np.array([np.abs(np.mean(t[~v,0]))
    for t,v in zip(speed.tolist(),midpoints)])
    print edgespeed    
    pts = ax.scatter(edgespeed,midspeed,s=10,marker='D',
                      facecolors='b',edgecolors='none')
    pltutils.regressionline(edgespeed,midspeed,ax,color='k')
    sselector = CollectionSelector(ax,pts,color_other='r',onselection=onselect)
    ax.set_title('slowdown')
    ax.set_xlabel('entry speed (cm / s)')
    ax.set_ylabel('exit speed (cm / s)')
    
    # Summary statistics (Bottom)
#    ax = fig.add_subplot(338)
#    speed = trajectories.speed(traj,vidtime)
#    avgsdvspeed = np.array([(np.abs(np.mean(t[:,0])),np.std(t[:,0])) for t in speed.tolist()])
#    ax.boxplot(avgsdvspeed)
#    ax.set_ylabel('speed (cm / s)')
    
    # Step activity
    ax = fig.add_subplot(337)
    stepactivity = np.genfromtxt(os.path.join(path, 'Analysis/step_activity.csv'))
    trialsteps = np.array([np.sum(stepactivity[s,:],axis=0) for s in traj.slices])
    stepnumbers = np.arange(8) + 1
    trialsteps_x = np.tile(stepnumbers,(trialsteps.shape[0],1))
    ax.plot(trialsteps_x,trialsteps,'k.')
    ax.set_title('stepping')
    ax.set_xlabel('step')
    ax.set_xlim(0,len(stepnumbers)+1)
    ax.set_xticks(stepnumbers)
    activityax = ax
    
    # Slips
    ax = fig.add_subplot(338)
    slipactivity = np.genfromtxt(os.path.join(path, 'Analysis/slip_activity.csv'))
    trialslips = np.array([np.sum(slipactivity[s,:],axis=0) for s in traj.slices])
    gapnumbers = np.arange(7) + 1
    trialslips_x = np.tile(gapnumbers,(trialslips.shape[0],1))
    ax.plot(trialslips_x,trialslips,'kx')
    ax.set_title('slips')
    ax.set_xlabel('gap')
    ax.set_xlim(0,len(gapnumbers)+1)
    ax.set_xticks(gapnumbers)
    slipax = ax
    
    # Trial conditions (WARNING! CONSIDER STEP STATE WRAPAROUND!!)
    ax = fig.add_subplot(339)
    width = 0.39    
    trialindices = trials.gettrialindices(path)
    steptrialpath = os.path.join(path, 'step{0}_trials.csv')
    stepstates = np.array([trials.gettrialstate(str.format(steptrialpath,i), trialindices)
    for i in xrange(1,7)]).T
    steptrialstate = np.array([stepstates[s.start,:] for s in traj.slices])
    fractionstabletrials = np.sum(steptrialstate,axis=0)/float(steptrialstate.shape[0])
    fractionstabletrials = np.insert(fractionstabletrials,[0,stepstates.shape[1]],1)
    unstablebars = ax.bar(stepnumbers,np.ones(stepnumbers.shape),width,color='r')
    stablebars = ax.bar(stepnumbers,fractionstabletrials,width,color='g')
    ax.set_title('manipulations')
    ax.set_xlabel('step')
    ax.set_xlim(0+width/2.,len(stepnumbers)+1+width/2.)
    ax.set_xticks(stepnumbers+width/2.)
    ax.set_xticklabels(stepnumbers)
    conditionax = ax
    
    # Select trial conditions
    def selectstepindices(evt,bars,trialstate):
        try:
            step = next(
            i-1 for i,bar in enumerate(bars)
            if bar.contains(evt)[0])
        except StopIteration:
            return []
                    
        if step >= 0 and step < trialstate.shape[1]:  
            ind = np.nonzero(trialstate[:,step])[0]
        else:
            ind = range(trialstate.shape[0])
        return ind

    notsteptrialstate = np.bitwise_not(steptrialstate)
    def onbuttonpress(evt):
        if evt.inaxes == conditionax:
            ind = selectstepindices(evt,stablebars,steptrialstate)
            if len(ind) == 0:
                ind = selectstepindices(evt,unstablebars,notsteptrialstate)
            conditionfilter[:] = ind
            updateselection()
    ax.figure.canvas.mpl_connect('button_press_event',onbuttonpress)
    
    plt.tight_layout(pad=0.5)
    return rawtraj,traj,vidtime,stepactivity,selector,sselector
Beispiel #3
0
        y = mtraj.data[s, 1]
    else:
        x = mtraj.data[s, 0] - 7 * trajectories.width_pixel_to_cm
        y = mtraj.data[s, 1]
    plt.plot(x, y, 'k', alpha=0.1)

bins = np.linspace(0, 40, 40)
rawspeedbins = np.array(trajectories.speedbins(mtraj, sp, bins))

# Compute baseline speed in 1st third of assay and subtract
baselinesp = np.nanmean(rawspeedbins[:, 0:rawspeedbins.shape[1] / 3], axis=1)
speedbins = rawspeedbins - baselinesp.reshape((len(baselinesp), 1))

# Get step state
trajtrials = trials.gettrialindices(path)
stepstate = trials.gettrialstate(os.path.join(path, 'step3_trials.csv'),
                                 trajtrials)

# Split trials into stable/unstable
validtrials = mtraj.slices
stabletrials = [i for i, s in enumerate(validtrials) if stepstate[s.start]]
unstabletrials = [
    i for i, s in enumerate(validtrials) if not stepstate[s.start]
]

plt.figure()
p = [plt.plot(t, 'g', alpha=0.1) for t in speedbins[stabletrials]]
p = [plt.plot(t, 'r', alpha=0.1) for t in speedbins[unstabletrials]]
m = np.nanmean(speedbins[stabletrials], axis=0)
plt.plot(m, 'g')
m = np.nanmean(speedbins[unstabletrials], axis=0)
plt.plot(m, 'r')
def get_randomized_speed_profiles(sessions):    
    avgSpeeds_allsess = []
    trialTypes_allsess = []

    # Select Session
    for s in sessions:
        
        # Load trials
        rawtrials = trajectories.genfromtxt(s)
        validtrials = trajectories.heightfilter(rawtrials,430,590)
        [plt.plot(t[:,0],t[:,1],'k',alpha=0.1) for t in validtrials.tolist()]
        plt.gca().invert_yaxis()
        numTrials = validtrials.slices.shape[0]
        print numTrials
    
        # There is some misalignment for sessions on the last 4 animals..there session 0 is other session 1
#        if a >= 10:
#            s = s-1
        
        # Look at all Trajectories
        traj = validtrials
        preprocess.make_videoanalysis(os.path.join(s,'Analysis'))
        vtimepath = os.path.join(s, 'Analysis/videotime.csv')
        vtime = np.genfromtxt(vtimepath)
        trajtrials = trials.gettrialindices(s)
        stepstate = trials.gettrialstate(os.path.join(s,'step3_trials.csv'),trajtrials)
        
        #print str.format('a:s {0}:{1} {2} {3}', a, s, numTrials, len(validtrials.slices))
        
        # Set Valid Trials (No exploration or tracking errors)
        crossings = traj
    
        # Set Binning and Range
        avgSpeeds = np.zeros((numTrials, numBins))
        trialTypes = np.zeros((numTrials, 1))
        for t in range(0,numTrials):
        
            #label_indices = np.array(pt.get_labeled_indices(labels,labelFilters[l]))
            #c = crossings[t]
            
            # Load X Trajectories and flip all of 'Left'
            trialX = crossings.data[crossings.slices[t],0]
            if trialX[0] > trialX[-1]:
                # ALign on 2 important rails (the center of rail 3 is 550)
                # and the centr of rail 4 is 737, therefore, the first encounter
                # is at 550 going "right", and when flipped, (1280-737 = 543)
                # going "left"...therefore, to correct for the shift, I subteact 1273 
                # and align the left and right trials
                trialX = np.abs(trialX-1273)
                
            # Load Y Trajectories
            trialY = crossings.data[crossings.slices[t],1]
            
            # Load and Parse Times
            trialT = vtime[crossings.slices[t]]
            
            # Measure Progression Speed
            diffX = np.diff(trialX)
            diffT = np.diff(trialT) # Time interval in seconds
            speedX = np.concatenate((np.zeros(1) , diffX/diffT))
        
            # Find enter/exit and crop trials
#            indR = np.where(trialX > 1200)
#            indL = np.where(trialX < 150)
#            if (np.size(indR) > 0) and (np.size(indL) > 0):
#                exitInd = indR[0][0]+1
#                enterInd = indL[0][-1]
#                
#            trialX = trialX[enterInd:exitInd]
#            trialY = trialY[enterInd:exitInd]
#            speedX = speedX[enterInd:exitInd]
            
            # Bin (progrssion - X) Speed Profiles (from position 200 to 1200)
            for b in range(0,numBins):
                bins = np.where((trialX >= (200+(b*binSize))) & (trialX < (200+(b*binSize)+binSize)))
                if np.size(bins) > 0:
                    avgSpeeds[t, b] = np.mean(speedX[bins])
                else:
                    avgSpeeds[t, b] = np.NaN
            
            # Correct for starting speed - - first Third of assay
            baseSpeed = stats.nanmean(avgSpeeds[t, 0:14])
            avgSpeeds[t,:] = avgSpeeds[t,:]/baseSpeed
            
            # Get Lables            
            if stepstate[crossings.slices[t].start]:
                trialTypes[t] = 0
            else:
                trialTypes[t] = 1
        
        # Pool All Average Speeds/TrialTypes Across Sessions        
        avgSpeeds_allsess.append(avgSpeeds)
        trialTypes_allsess.append(trialTypes)
    
    avgSpeeds = np.concatenate(avgSpeeds_allsess)
    trialTypes = np.concatenate(trialTypes_allsess)
    return avgSpeeds,trialTypes
def figure3(paths):
    stable = []
    unstable = []
    for path in paths:
        
        traj = trajectories.genfromtxt(path)
        steps = np.genfromtxt(os.path.join(path,'Analysis\step_activity.csv'))
        time = np.genfromtxt(os.path.join(path,'front_video.csv'),dtype=str)
        trajtrials = trials.gettrialindices(path)
        stepstate = trials.gettrialstate(os.path.join(path,'step3_trials.csv'),trajtrials)
        
        ftraj = trajectories.heightfilter(trajectories.lengthfilter(traj,0,500),0,6)
        
    #    plt.figure()
    #    for t in traj.tolist():
    #        plt.plot(len(t),max(t[:,1]),'k.')
    #    for t in ftraj.tolist():
    #        plt.plot(len(t),max(t[:,1]),'r.')
        
        traj = trajectories.mirrorleft(ftraj)
        #activesteptrials = [sum(steps[s,3 if s.step < 0 else 2]) / 255 for s in traj.slices]
        activesteptrials = [s for s in traj.slices
        if (sum(steps[s,3 if s.step < 0 else 2]) / 255) > 500]
        traj = trajectories.trajectories(traj.data,activesteptrials)
    
    #    plt.figure()    
    #    for t in traj.tolist():
    #        plt.plot(t[:,0],t[:,1],'k',alpha=0.1)
        
        speed = [np.insert(np.diff(traj.data[s,0])/timedelta(time[s]),0,0)
        for s in traj.slices]
        validtrials = [traj.slices[i] for i,s in enumerate(speed) if np.mean(s) > 0]
        
        traj = trajectories.trajectories(traj.data,validtrials)
        speed = [s for s in speed if np.mean(s) > 0]
        
    #    plt.figure()
    #    for sp in speed:
    #        plt.plot(sp,'k',alpha=0.1)
            
        # Bin (progrssion - X) Speed Profiles (from position 200 to 1200)
        numBins = 25
        binSize = 50 / numBins
        bins = range(0,50,binSize)
        speedbins = np.zeros((len(traj.slices),numBins))
        for i,t in enumerate(traj.tolist()):
            xs = t[:,0]
            binindices = np.digitize(xs,bins)
            for b in range(numBins):
                speedbin = speed[i][binindices == b]
                speedbins[i,b] = np.mean(speedbin) if speedbin.size > 0 else np.nan
            basespeed = stats.nanmean(speedbins[i,0:numBins/3])
            speedbins[i,:] /= basespeed
        
        stabletrials = [i for i,s in enumerate(validtrials) if stepstate[s.start]]
        unstabletrials = [i for i,s in enumerate(validtrials) if not stepstate[s.start]]
        
        stablespeeds = speedbins[stabletrials,:]
        unstablespeeds = speedbins[unstabletrials,:]
        stable.append(stablespeeds)
        unstable.append(unstablespeeds)
        
    def plotcurve(speeds,color):
        x = np.arange(numBins) * binSize
        mu = np.mean(speeds,axis=0)
        sd = np.std(speeds,axis=0)
        plt.plot(x,mu,color,linewidth=3)
        plt.plot(x,mu-sd,'k--')
        plt.plot(x,mu+sd,'k--')
        plt.fill_between(x,mu-sd,mu+sd,alpha=0.1,color=color)
    
    plt.figure()
    stablespeeds = np.concatenate(stable,0)
    unstablespeeds = np.concatenate(unstable,0)
    plotcurve(stablespeeds,'g')
    plotcurve(unstablespeeds,'r')
    return stablespeeds,unstablespeeds
        x = mtraj.data[s,0]
        y = mtraj.data[s,1]
    else:
        x = mtraj.data[s,0]-7*trajectories.width_pixel_to_cm
        y = mtraj.data[s,1]
    plt.plot(x,y,'k',alpha=0.1)

bins = np.linspace(0,40,40)
rawspeedbins = np.array(trajectories.speedbins(mtraj,sp,bins))

# Compute baseline speed in 1st third of assay and subtract
baselinesp = np.nanmean(rawspeedbins[:,0:rawspeedbins.shape[1]/3],axis=1)
speedbins = rawspeedbins-baselinesp.reshape((len(baselinesp),1))

# Get step state
trajtrials = trials.gettrialindices(path)
stepstate = trials.gettrialstate(os.path.join(path,'step3_trials.csv'),trajtrials)

# Split trials into stable/unstable
validtrials = mtraj.slices
stabletrials = [i for i,s in enumerate(validtrials) if stepstate[s.start]]
unstabletrials = [i for i,s in enumerate(validtrials) if not stepstate[s.start]]

plt.figure()
p = [plt.plot(t,'g',alpha=0.1) for t in speedbins[stabletrials]]
p = [plt.plot(t,'r',alpha=0.1) for t in speedbins[unstabletrials]]
m = np.nanmean(speedbins[stabletrials],axis=0)
plt.plot(m,'g')
m = np.nanmean(speedbins[unstabletrials],axis=0)
plt.plot(m,'r')
plt.show()