Esempio n. 1
0
 def plot_inc_exc_trials(IncTrsMat, ax, title=None, ytitle=None,
                         xlab='Trial #', ylab=None,):
     # Plot on heatmap.
     sns.heatmap(IncTrsMat, cmap='RdYlGn', center=0.5, cbar=False, ax=ax)
     # Set tick labels.
     putil.hide_tick_marks(ax)
     tr_ticks = [1] + list(np.arange(25, IncTrsMat.shape[1]+1, 25))
     ax.xaxis.set_ticks(tr_ticks)
     ax.set_xticklabels(tr_ticks)
     putil.rot_xtick_labels(ax, 0)
     putil.rot_ytick_labels(ax, 0, va='center')
     putil.set_labels(ax, xlab, ylab, title, ytitle)
Esempio n. 2
0
def plot_auc_heatmap(aroc_mat,
                     cmap='viridis',
                     events=None,
                     xlbl_freq=500,
                     ylbl_freq=10,
                     xlab='time',
                     ylab='unit index',
                     title='AROC over time',
                     ffig=None,
                     fig=None):
    """Plot ROC AUC of list of units on heatmap."""

    fig = putil.figure(fig)

    # Plot heatmap.
    yticklabels = np.arange(len(aroc_mat.index)) + 1
    ax = pplot.heatmap(aroc_mat,
                       vmin=0,
                       vmax=1,
                       cmap=cmap,
                       xlab=xlab,
                       ylab=ylab,
                       title=title,
                       yticklabels=yticklabels)

    # Format labels.
    xlbls = pd.Series(aroc_mat.columns.map(str))
    xlbls[aroc_mat.columns % xlbl_freq != 0] = ''
    putil.set_xtick_labels(ax, lbls=xlbls)
    putil.rot_xtick_labels(ax, rot=0, ha='center')
    putil.sparsify_tick_labels(fig,
                               ax,
                               'y',
                               istart=ylbl_freq - 1,
                               freq=ylbl_freq,
                               reverse=True)
    putil.hide_tick_marks(ax)
    putil.hide_spines(ax)

    # Plot events.
    if events is not None:
        putil.plot_events(events,
                          add_names=False,
                          color='black',
                          alpha=0.3,
                          ls='-',
                          lw=1,
                          ax=ax)

    # Save plot.
    putil.save_fig(ffig, dpi=300)
Esempio n. 3
0
def plot_trial_type_distribution(UA, RecInfo, utids=None, tr_par=('S1', 'Dir'),
                                 save_plot=False, fname=None):
    """Plot distribution of trial types."""

    # Init.
    par_str = util.format_to_fname(str(tr_par))
    if utids is None:
        utids = UA.utids(as_series=True)
    recs = util.get_subj_date_pairs(utids)
    tasks = RecInfo.index.get_level_values('task').unique()
    tasks = [task for task in UA.tasks() if task in tasks]  # reorder tasks

    # Init plotting.
    putil.set_style('notebook', 'darkgrid')
    fig, gsp, axs = putil.get_gs_subplots(nrow=len(recs), ncol=len(tasks),
                                          subw=4, subh=3, create_axes=True)

    for ir, rec in enumerate(recs):
        for it, task in enumerate(tasks):

            ax = axs[ir, it]
            rt = rec + (task,)
            if rt not in RecInfo.index:
                ax.set_axis_off()
                continue

            # Get includecd trials and their parameters.
            inc_trs = RecInfo.loc[rt, 'trials']
            utid = utids.xs(rt, level=('subj', 'date', 'task'))[0]
            TrData = UA.get_unit(utid[:-1], utid[-1]).TrData.loc[inc_trs]

            # Create DF to plot.
            anw_df = TrData[[tr_par, 'correct']].copy()
            anw_df['answer'] = 'error'
            anw_df.loc[anw_df.correct, 'answer'] = 'correct'
            all_df = anw_df.copy()
            all_df.answer = 'all'
            comb_df = pd.concat([anw_df, all_df])

            if not TrData.size:
                ax.set_axis_off()
                continue

            # Plot as countplot.
            sns.countplot(x=tr_par, hue='answer', data=comb_df,
                          hue_order=['all', 'correct', 'error'], ax=ax)
            sns.despine(ax=ax)
            putil.hide_tick_marks(ax)
            putil.set_max_n_ticks(ax, 6, 'y')
            ax.legend(loc=[0.95, 0.7])

            # Add title.
            title = '{} {}'.format(rec, task)
            nce = anw_df.answer.value_counts()
            nc, ne = [nce[c] if c in nce else 0 for c in ('correct', 'error')]
            pnc, pne = 100*nc/nce.sum(), 100*ne/nce.sum()
            title += '\n\n# correct: {} ({:.0f}%)'.format(nc, pnc)
            title += '      # error: {} ({:.0f}%)'.format(ne, pne)
            putil.set_labels(ax, title=title, xlab=par_str)

            # Format legend.
            if (ir != 0) or (it != 0):
                ax.legend_.remove()

    # Save plot.
    if save_plot:
        title = 'Trial type distribution'
        if fname is None:
            fname = util.join(['results', 'decoding', 'prepare',
                               par_str + '_trial_type_distr.pdf'])

        putil.save_fig(fname, fig, title, w_pad=3, h_pad=3)
Esempio n. 4
0
def PD_across_units(UA, UInc, utids=None, fres=None, ffig=None):
    """
    Test consistency/spread of PD across units per recording.
    What is the spread in the preferred directions across units?

    Return population level preferred direction (and direction selectivity),
    that can be used to determine dominant preferred direction to decode.
    """

    # Init.
    if utids is None:
        utids = UA.utids(as_series=True)
    tasks = utids.index.get_level_values('task').unique()
    recs = util.get_subj_date_pairs(utids)

    # Get DS info frame.
    DSInfo = ua_query.get_DSInfo_table(UA, utids)
    DSInfo['include'] = UInc

    # Calculate population PD and DSI.
    dPPDres = {}
    for rec in recs:
        for task in tasks:

            # Init.
            rt = rec + (task,)
            rtDSInfo = DSInfo.xs(rt, level=[0, 1, -1])
            if rtDSInfo.empty:
                continue

            # Calculate population PD and population DSI.
            res = direction.calc_PPD(rtDSInfo.loc[rtDSInfo.include])
            dPPDres[rt] = res

    PPDres = pd.DataFrame(dPPDres).T

    # Save results.
    if fres is not None:
        results = {'DSInfo': DSInfo, 'PPDres': PPDres}
        util.write_objects(results, fres)

    # Plot results.

    # Init plotting.
    putil.set_style('notebook', 'darkgrid')
    fig, gsp, axs = putil.get_gs_subplots(nrow=len(recs), ncol=len(tasks),
                                          subw=6, subh=6, create_axes=True,
                                          ax_kws_list={'projection': 'polar'})
    xticks = direction.deg2rad(constants.all_dirs + 360/8/2*deg)

    for ir, rec in enumerate(recs):
        for it, task in enumerate(tasks):

            # Init.
            rt = rec + (task,)
            rtDSInfo = DSInfo.xs(rt, level=[0, 1, -1])
            ax = axs[ir, it]
            if rtDSInfo.empty:
                ax.set_axis_off()
                continue
            PDSI, PPD, PPDc, PADc = PPDres.loc[rt]

            # Plot PD - DSI on polar plot.
            sPPDc, sPADc = [int(v) if not np.isnan(v) else v
                            for v in (PPDc, PADc)]
            title = (' '.join(rt) + '\n' +
                     'PPDc = {}$^\circ$ - {}$^\circ$'.format(PPDc, PADc) +
                     ', PDSI = {:.2f}'.format(PDSI))
            PDrad = direction.deg2rad(util.remove_dim_from_series(rtDSInfo.PD))
            pplot.scatter(PDrad, rtDSInfo.DSI, rtDSInfo.include, ylim=[0, 1],
                          title=title, ytitle=1.08, c='darkblue', ec='k',
                          linewidth=1, s=80, alpha=0.8, zorder=2, ax=ax)

            # Highlight PPD and PAD.
            offsets = np.array([-45, 0, 45]) * deg
            for D, c in [(PPDc, 'g'), (PADc, 'r')]:
                if np.isnan(D):
                    continue
                hlDs = direction.deg2rad(np.array(D+offsets))
                for hlD, alpha in [(hlDs, 0.2), ([hlDs[1]], 0.4)]:
                    pplot.bars(hlD, len(hlD)*[1], align='center',
                               alpha=alpha, color=c, zorder=1, ax=ax)

            # Format ticks.
            ax.set_xticks(xticks, minor=True)
            ax.grid(b=True, axis='x', which='minor')
            ax.grid(b=False, axis='x', which='major')
            putil.hide_tick_marks(ax)

    # Save plot.
    title = 'Population direction selectivity'
    putil.save_fig(ffig, fig, title, w_pad=12, h_pad=20)

    return DSInfo, PPDres
Esempio n. 5
0
def plot_DR(dirs,
            resp,
            DSI=None,
            PD=None,
            baseline=None,
            plot_type='line',
            complete_missing_dirs=False,
            color='b',
            title=None,
            ffig=None,
            ax=None):
    """
    Plot response to each directions on polar plot, with a vector pointing to
    preferred direction (PD) with length DSI.
    Use plot_type to change between sector ('bar') and connected ('line') plot
    types.
    """

    ax = putil.axes(ax, polar=True)

    # Plot baseline.
    if baseline is not None:
        putil.add_baseline(baseline, ax=ax)

    # Remove NaNs.
    all_dirs = dirs
    not_nan = np.array(~pd.isnull(dirs) & ~pd.isnull(resp))
    dirs, resp = dirs[not_nan], np.array(resp[not_nan])

    # Prepare data.
    # Complete missing directions with 0 response.
    if complete_missing_dirs:
        for i, d in enumerate(all_dirs):
            if d not in dirs:
                dirs = np.insert(dirs, i, d) * dirs.units
                resp = np.insert(resp, i, 0) * 1 / s

    rad_dirs = dirs.rescale(rad)

    # Plot response to each directions on polar plot.
    if plot_type == 'bar':  # sector plot
        ndirs = all_dirs.size
        left_rad_dirs = rad_dirs - np.pi / ndirs  # no need for this in MPL 2.0?
        w = 2 * np.pi / ndirs  # same with edgecolor and else?
        pplot.bars(left_rad_dirs,
                   resp,
                   width=w,
                   alpha=0.50,
                   color=color,
                   lw=1,
                   edgecolor='w',
                   title=title,
                   ytitle=1.08,
                   ax=ax)
    else:  # line plot
        rad_dirs, resp = [np.append(v, [v[0]]) for v in (rad_dirs, resp)]
        pplot.lines(rad_dirs,
                    resp,
                    color=color,
                    marker='o',
                    lw=1,
                    ms=4,
                    mew=0,
                    title=title,
                    ytitle=1.08,
                    ax=ax)
        ax.fill(rad_dirs, resp, color=color, alpha=0.15)

    # Add arrow representing PD and weighted DSI.
    if DSI is not None and PD is not None:
        rho = np.max(resp) * DSI
        xy = (float(PD.rescale(rad)), rho)
        arr_props = dict(facecolor=color, edgecolor='k', shrink=0.0, alpha=0.5)
        ax.annotate('', xy, xytext=(0, 0), arrowprops=arr_props)

    # Remove spines and tick marks, maximize tick labels.
    putil.set_spines(ax, False, False)
    putil.hide_tick_marks(ax)

    # Save and return plot.
    putil.save_fig(ffig)
    return ax
Esempio n. 6
0
def plot_up_down_raster(Spikes, task, rec, itrs):
    """Plot spike raster for up-down dynamics analysis."""

    # Set params for plotting.
    uids, trs = Spikes.index, Spikes.columns
    plot_trs = trs[itrs]
    ntrs = len(plot_trs)
    nunits = len(uids)
    tr_gap = nunits / 2

    # Init figure.
    putil.set_style('notebook', 'ticks')
    fig = putil.figure(figsize=(10, ntrs))
    ax = fig.add_subplot(111)

    # Per trial, per unit.
    for itr, tr in enumerate(plot_trs):
        for iu, uid in enumerate(uids):

            # Init y level and spike times.
            i = (tr_gap + nunits) * itr + iu
            spk_tr = Spikes.loc[uid, tr]

            # Plot (spike time, y-level) pairs.
            x = np.array(spk_tr.rescale('ms'))
            y = (i+1) * np.ones_like(x)

            patches = [Rectangle((xi-wsp/2, yi-hsp/2), wsp, hsp)
                       for xi, yi in zip(x, y)]
            collection = PatchCollection(patches, facecolor=c, edgecolor=c)
            ax.add_collection(collection)

    # Add stimulus lines.
    for stim in constants.stim_dur.index:
        t_start, t_stop = constants.fixed_tr_prds.loc[stim]
        events = pd.DataFrame([(t_start, 't_start'), (t_stop, 't_stop')],
                              index=['start', 'stop'],
                              columns=['time', 'label'])
        putil.plot_events(events, add_names=False, color='grey',
                          alpha=0.5, ls='-', lw=0.5, ax=ax)

    # Add inter-trial shading.
    for itr in range(ntrs+1):
        ymin = itr * (tr_gap + nunits) - tr_gap + 0.5
        ax.axhspan(ymin, ymin+tr_gap, alpha=.05, color='grey')

    # Set tick labels.
    pos = np.arange(ntrs) * (tr_gap + nunits) + nunits/2
    lbls = plot_trs + 1
    putil.set_ytick_labels(ax, pos, lbls)
    # putil.sparsify_tick_labels(ax, 'y', freq=2, istart=1)
    putil.hide_tick_marks(ax, show_x_tick_mrks=True)

    # Format plot.
    xlim = constants.fixed_tr_prds.loc['whole trial']
    ylim = [-tr_gap/2, ntrs * (nunits+tr_gap)-tr_gap/2]
    xlab = 'Time since S1 onset (ms)'
    ylab = 'Trial number'
    title = '{} {}'.format(rec, task)
    putil.format_plot(ax, xlim, ylim, xlab, ylab, title)
    putil.set_spines(ax, True, False, False, False)

    # Save figure.
    fname = 'UpDown_dynamics_{}_{}.pdf'.format(rec, task)
    ffig = util.join(['results', 'UpDown', fname])
    putil.save_fig(ffig, fig, dpi=600)