def summary_fig(radii, curves, Ntot): fig, ax = ge.figure(right=8, figsize=(1.5, 1.5)) ge.title(ax, 'n=%i ROIS' % len(curves)) axi = ge.inset(fig, [.73, .35, .3, .4]) axi.pie([100 * len(curves) / Ntot, 100 * (1 - len(curves) / Ntot)], explode=(0, 0.1), colors=[plt.cm.tab10(2), plt.cm.tab10(3)], labels=['responsive at low radius\n\n\n', ''], autopct='%1.1f%%', shadow=True, startangle=90) axi.axis( 'equal') # Equal aspect ratio ensures that pie is drawn as a circle. curves = np.array(curves) ge.scatter(x=radii, y=np.mean(curves, axis=0), sy=np.std(curves, axis=0), no_set=True, ms=5, ax=ax, lw=2) ge.set_plot(ax, xlabel='size ($^{o}$)', ylabel='$\delta$ dF/F') return fig
def plot_row_column_of_quantity(self): single_cond = self.build_single_conditions() COL_CONDS = self.build_column_conditions() ROW_CONDS = self.build_row_conditions() COLOR_CONDS = self.build_color_conditions() if (len(COLOR_CONDS) > 1) and (self.color.text() != ''): COLORS = [ getattr(ge, self.color.text())((c % 10) / 10.) for c in np.arange(len(COLOR_CONDS)) ] elif (len(COLOR_CONDS) > 1): COLORS = [ ge.tab10((c % 10) / 10.) for c in np.arange(len(COLOR_CONDS)) ] elif self.color.text() != '': COLORS = [getattr(ge, self.color.text())] else: COLORS = ['k'] if self.fig_presets.currentText() == 'raw-traces-preset': fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)), reshape_axes=False, top=0.4, bottom=0.4, left=0.7, right=0.7, wspace=0.5, hspace=0.5) else: fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)), reshape_axes=False) self.ylim = [np.inf, -np.inf] for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): for icolor, color_cond in enumerate(COLOR_CONDS): cond = np.array( single_cond & col_cond & row_cond & color_cond)[:self.EPISODES['resp'].shape[0]] if self.EPISODES['resp'][cond, :].shape[0] > 0: my = self.EPISODES['resp'][cond, :].mean(axis=0) if self.withSTDbox.isChecked(): sy = self.EPISODES['resp'][cond, :].std(axis=0) ge.plot(self.EPISODES['t'], my, sy=sy, ax=AX[irow][icol], color=COLORS[icolor], lw=1) self.ylim = [ min([self.ylim[0], np.min(my - sy)]), max([self.ylim[1], np.max(my + sy)]) ] else: AX[irow][icol].plot(self.EPISODES['t'], my, color=COLORS[icolor], lw=1) self.ylim = [ min([self.ylim[0], np.min(my)]), max([self.ylim[1], np.max(my)]) ] if self.screen.isChecked() and not (self.parent.visual_stim is not None): print('initializing stim [...]') self.parent.load_VisualStim() if self.screen.isChecked(): inset = ge.inset(AX[irow][icol], [.8, .9, .3, .25]) self.parent.visual_stim.show_frame(\ self.EPISODES['index_from_start'][cond][0], ax=inset, parent=self.parent, enhance=True, label=None) if self.withStatTest.isChecked(): for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): for icolor, color_cond in enumerate(COLOR_CONDS): cond = np.array( single_cond & col_cond & row_cond & color_cond)[:self.EPISODES['resp'].shape[0]] test = stat_test_for_evoked_responses( self.EPISODES, cond, interval_pre=[self.t0pre, self.t1pre], interval_post=[self.t0post, self.t1post], test='wilcoxon') AX[irow][icol].plot([self.t0pre, self.t1pre], self.ylim[0] * np.ones(2), 'k-', lw=2) AX[irow][icol].plot([self.t0post, self.t1post], self.ylim[0] * np.ones(2), 'k-', lw=2) ps, size = pval_to_star(test) AX[irow][icol].annotate( ps, ((self.t1pre + self.t0post) / 2., self.ylim[0]), va='top', ha='center', size=size, xycoords='data') if (self.ymin.text() != '') and (self.ymax.text() != ''): self.ylim = [float(self.ymin.text()), float(self.ymax.text())] if (self.xmin.text() != '') and (self.xmax.text() != ''): self.xlim = [float(self.xmin.text()), float(self.xmax.text())] else: self.xlim = [self.EPISODES['t'][0], self.EPISODES['t'][-1]] for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): ge.set_plot(AX[irow][icol], spines=(['left', 'bottom'] if self.axis.isChecked() else []), ylim=self.ylim, xlim=self.xlim, xlabel=(self.xbarlabel.text() if self.axis.isChecked() else ''), ylabel=(self.ybarlabel.text() if self.axis.isChecked() else '')) if self.stim.isChecked(): AX[irow][icol].fill_between( [0, np.mean(self.EPISODES['time_duration'])], self.ylim[0] * np.ones(2), self.ylim[1] * np.ones(2), color='grey', alpha=.2, lw=0) if not self.axis.isChecked(): ge.draw_bar_scales(AX[0][0], Xbar=(0. if self.xbar.text() == '' else float( self.xbar.text())), Xbar_label=self.xbarlabel.text(), Ybar=(0. if self.ybar.text() == '' else float( self.ybar.text())), Ybar_label=self.ybarlabel.text(), Xbar_fraction=0.1, Xbar_label_format='%.1f', Ybar_fraction=0.2, Ybar_label_format='%.1f', loc='top-left') if self.label.text() != '': ge.annotate(fig, ' '+self.label.text()+\ (1+int(self.nlabel.text()))*'\n', (0,0), color=COLORS[0], ha='left', va='bottom') if self.annot.isChecked(): S = '' if hasattr(self, 'roiPick'): S += 'roi #%s' % self.roiPick.text() for i, key in enumerate(self.varied_parameters.keys()): if 'single-value' in getattr(self, '%s_plot' % key).currentText(): S += ', %s=%.2f' % (key, getattr( self, '%s_values' % key).currentText()) ge.annotate(fig, S, (0, 0), color='k', ha='left', va='bottom') return fig, AX
def plot_row_column_of_quantity(self): self.Pcond = self.data.get_protocol_cond(self.pbox.currentIndex() - 1) single_cond = self.build_single_conditions() COL_CONDS = self.build_column_conditions() ROW_CONDS = self.build_row_conditions() COLOR_CONDS = self.build_color_conditions() if (len(COLOR_CONDS) > 1) and (self.color.text() != ''): COLORS = [ getattr(ge, self.color.text())((c % 10) / 10.) for c in np.arange(len(COLOR_CONDS)) ] elif (len(COLOR_CONDS) > 1): COLORS = [ ge.tab10((c % 10) / 10.) for c in np.arange(len(COLOR_CONDS)) ] elif self.color.text() != '': COLORS = [getattr(ge, self.color.text())] else: COLORS = ['k'] fig, AX = ge.figure( axes=(len(COL_CONDS), len(ROW_CONDS)), **dv_tools.FIGURE_PRESETS[self.fig_presets.currentText()]) self.ylim = [np.inf, -np.inf] for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): for icolor, color_cond in enumerate(COLOR_CONDS): cond = np.array(single_cond & col_cond & row_cond & color_cond)[:self.EPISODES.resp.shape[0]] if self.EPISODES.resp[cond, :].shape[0] > 0: my = self.EPISODES.resp[cond, :].mean(axis=0) if self.withSTDbox.isChecked(): sy = self.EPISODES.resp[cond, :].std(axis=0) ge.plot(self.EPISODES.t, my, sy=sy, ax=AX[irow][icol], color=COLORS[icolor], lw=1) self.ylim = [ min([self.ylim[0], np.min(my - sy)]), max([self.ylim[1], np.max(my + sy)]) ] else: AX[irow][icol].plot(self.EPISODES.t, my, color=COLORS[icolor], lw=1) self.ylim = [ min([self.ylim[0], np.min(my)]), max([self.ylim[1], np.max(my)]) ] if self.annot.isChecked(): # column label if (len(COL_CONDS) > 1) and (irow == 0) and (icolor == 0): s = '' for i, key in enumerate( self.varied_parameters.keys()): if 'column' in getattr( self, '%s_plot' % key).currentText(): s += format_key_value( key, getattr(self.EPISODES, key)[cond][0] ) + 4 * ' ' # should have a unique value ge.annotate(AX[irow][icol], s, (1, 1), ha='right', va='bottom') # row label if (len(ROW_CONDS) > 1) and (icol == 0) and (icolor == 0): s = '' for i, key in enumerate( self.varied_parameters.keys()): if 'row' in getattr(self, '%s_plot' % key).currentText(): s += format_key_value( key, getattr(self.EPISODES, key)[cond][0] ) + 4 * ' ' # should have a unique value ge.annotate(AX[irow][icol], s, (0, 0), ha='right', va='bottom', rotation=90) # n per cond ge.annotate(AX[irow][icol], ' n=%i' % np.sum(cond) + '\n' * icolor, (.99, 0), color=COLORS[icolor], size='xx-small', ha='left', va='bottom') if self.screen.isChecked() and not (self.data.visual_stim is not None): print('initializing stim [...]') self.data.init_visual_stim() if self.screen.isChecked(): inset = ge.inset(AX[irow][icol], [.8, .9, .3, .25]) self.data.visual_stim.show_frame(\ self.EPISODES.index_from_start[cond][0], ax=inset, enhance=True, label=None) if self.withStatTest.isChecked(): for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): for icolor, color_cond in enumerate(COLOR_CONDS): cond = np.array( single_cond & col_cond & row_cond & color_cond)[:self.EPISODES.resp.shape[0]] results = self.EPISODES.stat_test_for_evoked_responses( episode_cond=cond, interval_pre=[self.t0pre, self.t1pre], interval_post=[self.t0post, self.t1post], test='wilcoxon') ps, size = results.pval_annot() AX[irow][icol].annotate( ps, ((self.t1pre + self.t0post) / 2., self.ylim[0]), va='top', ha='center', size=size, xycoords='data') AX[irow][icol].plot([self.t0pre, self.t1pre], self.ylim[0] * np.ones(2), 'k-', lw=2) AX[irow][icol].plot([self.t0post, self.t1post], self.ylim[0] * np.ones(2), 'k-', lw=2) # color label if self.annot.isChecked() and (len(COLOR_CONDS) > 1): for icolor, color_cond in enumerate(COLOR_CONDS): cond = np.array(single_cond & color_cond)[:self.EPISODES.resp.shape[0]] for i, key in enumerate(self.varied_parameters.keys()): if 'color' in getattr(self, '%s_plot' % key).currentText(): s = format_key_value( key, getattr(self.EPISODES, key)[cond][0]) ge.annotate(fig, s, (1. - icolor / (len(COLOR_CONDS) + 2), 0), color=COLORS[icolor], ha='right', va='bottom') if (self.ymin.text() != '') and (self.ymax.text() != ''): self.ylim = [float(self.ymin.text()), float(self.ymax.text())] if (self.xmin.text() != '') and (self.xmax.text() != ''): self.xlim = [float(self.xmin.text()), float(self.xmax.text())] else: self.xlim = [self.EPISODES.t[0], self.EPISODES.t[-1]] for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): ge.set_plot(AX[irow][icol], spines=(['left', 'bottom'] if self.axis.isChecked() else []), ylim=self.ylim, xlim=self.xlim, xlabel=(self.xbarlabel.text() if self.axis.isChecked() else ''), ylabel=(self.ybarlabel.text() if self.axis.isChecked() else '')) if self.stim.isChecked(): AX[irow][icol].fill_between( [0, np.mean(self.EPISODES.time_duration)], self.ylim[0] * np.ones(2), self.ylim[1] * np.ones(2), color='grey', alpha=.2, lw=0) if not self.axis.isChecked(): ge.draw_bar_scales(AX[0][0], Xbar=(0. if self.xbar.text() == '' else float( self.xbar.text())), Xbar_label=self.xbarlabel.text(), Ybar=(0. if self.ybar.text() == '' else float( self.ybar.text())), Ybar_label=self.ybarlabel.text() + ' ', Xbar_fraction=0.1, Xbar_label_format='%.1f', Ybar_fraction=0.2, Ybar_label_format='%.1f', loc='top-left') if self.label.text() != '': ge.annotate(fig, ' '+self.label.text()+\ (1+int(self.nlabel.text()))*'\n', (0,0), color=COLORS[0], ha='left', va='bottom') if self.annot.isChecked(): S = '' if hasattr(self, 'roiPick'): S += 'roi #%s, ' % self.roiPick.text() for i, key in enumerate(self.varied_parameters.keys()): if 'single-value' in getattr(self, '%s_plot' % key).currentText(): S += '%s=%s, ' % (key, getattr( self, '%s_values' % key).currentText()) ge.annotate(fig, S, (0, 0), color='k', ha='left', va='bottom') if self.annot.isChecked(): ge.annotate( fig, "%s, %s, %s, %s" % (self.data.metadata['subject_ID'], self.data.protocols[self.pbox.currentIndex() - 1][:20], self.data.metadata['filename'].split('\\')[-2], self.data.metadata['filename'].split('\\')[-1]), (0, 1), color='k', ha='left', va='top', size='x-small') return fig, AX
def OS_ROI_analysis(FullData, roiIndex=0, iprotocol=0, subprotocol_id=0, verbose=False, response_significance_threshold=0.01, with_responsive_angles=False, stat_test_props=dict(interval_pre=[-2, 0], interval_post=[1, 3], test='wilcoxon', positive=True)): """ orientation selectivity ROI analysis """ EPISODES = EpisodeResponse(FullData, protocol_id=iprotocol, quantity='CaImaging', subquantity='dF/F', roiIndex=roiIndex) fig, AX = FullData.plot_trial_average( EPISODES=EPISODES, quantity='CaImaging', subquantity='dF/F', roiIndex=roiIndex, column_key='angle', ybar=1., ybarlabel='1dF/F', xbar=1., xbarlabel='1s', fig_preset='raw-traces-preset+right-space', with_annotation=True, with_stat_test=True, stat_test_props=stat_test_props, verbose=verbose) ax = ge.inset(fig, (0.88, 0.4, 0.1, 0.4)) angles, y, sy, responsive_angles = [], [], [], [] responsive = False for i, angle in enumerate(EPISODES.varied_parameters['angle']): stats = EPISODES.stat_test_for_evoked_responses( episode_cond=EPISODES.find_episode_cond('angle', i), **stat_test_props) angles.append(angle) y.append(np.mean(stats.y)) # means "post" sy.append(np.std(stats.y)) # std "post" if stats.significant(threshold=response_significance_threshold): responsive = True responsive_angles.append(angle) ge.plot(angles, np.array(y), sy=np.array(sy), ax=ax, axes_args=dict(ylabel='<post dF/F> ', xlabel='angle ($^{o}$)', xticks=angles, size='small'), m='o', ms=2, lw=1) SI = orientation_selectivity_index(angles, y) ge.annotate(fig, 'SI=%.2f ' % SI, (1, 0.97), va='top', ha='right', xycoords='figure fraction', weight='bold', fontsize=8, color=('k' if responsive else 'lightgray')) ge.annotate(fig, ('responsive' if responsive else 'unresponsive'), (0.78, 0.98), ha='left', va='top', xycoords='figure fraction', weight='bold', fontsize=8, color=(plt.cm.tab10(2) if responsive else plt.cm.tab10(3))) if with_responsive_angles: return fig, SI, responsive, responsive_angles else: return fig, SI, responsive
def DS_ROI_analysis(FullData, roiIndex=0, iprotocol=0, verbose=False, response_significance_threshold=0.01, with_responsive_angles=False, fig=None, AX=None, CaImaging_options=dict(quantity='CaImaging', subquantity='dF/F'), stat_test_props=dict(interval_pre=[-2, 0], interval_post=[1, 3], test='wilcoxon'), inset_coords=(0.92, 0.4, 0.07, 0.4)): """ direction selectivity ROI analysis """ EPISODES = EpisodeResponse(FullData, protocol_id=iprotocol, roiIndex=roiIndex, verbose=verbose, **CaImaging_options) fig, AX = FullData.plot_trial_average( EPISODES=EPISODES, protocol_id=iprotocol, roiIndex=roiIndex, column_key='angle', ybar=1., ybarlabel='1dF/F', xbar=1., xbarlabel='1s', fig=fig, AX=AX, no_set=False, fig_preset='raw-traces-preset+right-space', with_annotation=True, with_stat_test=True, stat_test_props=stat_test_props, verbose=verbose, **CaImaging_options) ax = ge.inset(fig, inset_coords) angles, y, sy, responsive_angles = [], [], [], [] responsive = False for i, angle in enumerate(EPISODES.varied_parameters['angle']): means_pre = EPISODES.compute_stats_over_repeated_trials( 'angle', i, interval_cond=EPISODES.compute_interval_cond( stat_test_props['interval_pre']), quantity='mean') means_post = EPISODES.compute_stats_over_repeated_trials( 'angle', i, interval_cond=EPISODES.compute_interval_cond( stat_test_props['interval_post']), quantity='mean') stats = EPISODES.stat_test_for_evoked_responses( episode_cond=EPISODES.find_episode_cond('angle', i), **stat_test_props) angles.append(angle) y.append(np.mean(means_post)) sy.append(np.std(means_post)) if stats.significant(response_significance_threshold): responsive = True responsive_angles.append(angle) ge.plot(angles, np.array(y), sy=np.array(sy), ax=ax, axes_args=dict(ylabel='<post dF/F> ', xlabel='angle ($^{o}$)', xticks=np.array(angles)[::int(len(angles) / 4)], size='small'), m='o', ms=2, lw=1) SI = orientation_selectivity_index(angles, y) ge.annotate(ax, 'SI=%.2f\n ' % SI, (1, 1), ha='right', weight='bold', fontsize=8, color=('k' if responsive else 'lightgray')) ge.annotate(ax, ('responsive' if responsive else 'unresponsive'), (0., 1), ha='left', weight='bold', fontsize=8, color=(plt.cm.tab10(2) if responsive else plt.cm.tab10(3))) if with_responsive_angles: return fig, SI, responsive, responsive_angles else: return fig, SI, responsive
def interaction_fig(responses, static_patch_label='...', moving_dots_label='...', mixed_label='...', random=False, Ybar=0.2, Ybar_label='0.2dF/F', tmin=-3): fig, AX = ge.figure(axes=(3, 1), figsize=(1., 1), wspace=0.5, right=8, top=2) ax = ge.inset(fig, [.9, .4, .07, .5]) ax.bar([0], [responses['linear-integral']], color=ge.red) ax.bar([1], [responses['mixed-integral']], color='k') ge.set_plot(ax, ['left'], ylabel='integ. (resp.s)') # static-patch cond = responses['t_contour'] > tmin / 2. AX[0].plot(responses['t_contour'][cond], responses['contour'][cond], color='k') ge.set_plot(AX[0], [], title=static_patch_label) # mv Dots cond = responses['t_motion'] > tmin AX[1].plot(responses['t_motion'][cond], responses['motion' if not random else 'random'][cond], color='k') ge.set_plot(AX[1], [], title=moving_dots_label) # mixed interaction_panel( responses, ax=AX[2], title=mixed_label, mixed_key='mixed' if not random else 'mixed-random', linear_key='linear' if not random else 'linear-random', with_episodes_highlights= False, # only after that we have set common lims tmin=tmin) ge.set_common_ylims(AX) ge.set_common_xlims(AX) AX[0].fill_between([0, responses['patch-duration']], AX[0].get_ylim()[0] * np.ones(2), AX[0].get_ylim()[1] * np.ones(2), color=ge.blue, alpha=.3, lw=0) AX[1].fill_between([0, responses['mvDot-duration']], AX[1].get_ylim()[0] * np.ones(2), AX[1].get_ylim()[1] * np.ones(2), color=ge.orange, alpha=.1, lw=0) AX[2].plot( responses['delay'] + np.arange(2) * responses['integral_window'], AX[2].get_ylim()[1] * np.ones(2), 'k-') AX[2].fill_between(responses['delay'] + np.arange(2) * responses['patch-duration'], AX[2].get_ylim()[0] * np.ones(2), AX[2].get_ylim()[1] * np.ones(2), color=ge.blue, alpha=.3, lw=0) AX[2].fill_between([0, responses['mvDot-duration']], AX[2].get_ylim()[0] * np.ones(2), AX[2].get_ylim()[1] * np.ones(2), color=ge.orange, alpha=.1, lw=0) for ax in AX: ge.draw_bar_scales(ax, Xbar=1, Xbar_label='1s', Ybar=Ybar, Ybar_label=Ybar_label) ge.annotate(fig, ' n=%iROIs' % responses['nROIs'], (0.02, 0.02)) return fig, AX, ax
def tuning_modulation_fig(curves, full_resp=None): # running vs still --- raw evoked response fig, ax = ge.figure(figsize=(1.5, 1.5), right=6) ge.plot(curves['angles'], curves['all'], label='all', color='grey', ax=ax, no_set=True, lw=2, alpha=.5) ge.plot(curves['angles'], curves['running_mean'], color=ge.orange, ms=4, m='o', ax=ax, lw=2, label='running', no_set=True) ge.plot(curves['angles'], curves['still_mean'], color=ge.blue, ms=4, m='o', ax=ax, lw=2, label='still', no_set=True) ge.legend(ax, ncol=3, loc=(.3, 1.)) ge.set_plot(ax, xlabel='angle ($^{o}$) w.r.t. pref. orient.', ylabel='evoked resp, ($\delta$ dF/F) ', xticks=[0, 90, 180, 270]) if (full_resp is not None) and ('speed_level' in full_resp) and ('pupil_level' in full_resp): inset = ge.inset(fig, [.8, .5, .16, .28]) ge.scatter(full_resp['pupil_level'][full_resp['running_cond']], full_resp['speed_level'][full_resp['running_cond']], ax=inset, no_set=True, color=ge.orange) ge.scatter(full_resp['pupil_level'][~full_resp['running_cond']], full_resp['speed_level'][~full_resp['running_cond']], ax=inset, no_set=True, color=ge.blue) ge.annotate(ax, 'n=%i cells\n' % full_resp['Ncells'], (0., 1.), ha='center') ge.set_plot(inset, xlabel='pupil size (mm)', ylabel='run. speed (cm/s) ', title='episodes (n=%i) ' % full_resp['Neps']) ge.annotate(inset, 'n=%i' % (np.sum(full_resp['running_cond']) / full_resp['Ncells']), (0., 1.), va='top', color=ge.orange) ge.annotate(inset, '\nn=%i' % (np.sum(~full_resp['running_cond']) / full_resp['Ncells']), (0., 1.), va='top', color=ge.blue) if len(curves['constricted_mean']) > 0: # constricted vs dilated --- raw evoked response fig2, ax = ge.figure(figsize=(1.5, 1.5), right=6) ge.plot(curves['angles'], curves['all'], label='all', color='grey', ax=ax, no_set=True, lw=2, alpha=.5) ge.plot(curves['angles'], curves['constricted_mean'], color=ge.green, ms=4, m='o', ax=ax, lw=2, label='constricted', no_set=True) ge.plot(curves['angles'], curves['dilated_mean'], color=ge.purple, ms=4, m='o', ax=ax, lw=2, label='dilated', no_set=True) ge.legend(ax, ncol=3, loc=(.1, 1.)) ge.set_plot(ax, xlabel='angle ($^{o}$) w.r.t. pref. orient.', ylabel='evoked resp, ($\delta$ dF/F) ', xticks=[0, 90, 180, 270]) if (full_resp is not None) and ('speed_level' in full_resp) and ('pupil_level' in full_resp): inset2 = ge.inset(fig2, [.8, .5, .16, .28]) ge.scatter(full_resp['pupil_level'][full_resp['dilated_cond']], full_resp['speed_level'][full_resp['dilated_cond']], ax=inset2, no_set=True, color=ge.purple) ge.scatter(full_resp['pupil_level'][full_resp['constricted_cond']], full_resp['speed_level'][full_resp['constricted_cond']], ax=inset2, no_set=True, color=ge.green) ge.annotate(ax, 'n=%i cells\n' % len(np.unique(full_resp['roi'])), (0., 1.), ha='right') ge.set_plot(inset2, xlabel='pupil size (mm)', ylabel='run. speed (cm/s) ', ylim=inset.get_ylim(), title='episodes (n=%i) ' % full_resp['Neps']) ge.annotate( inset2, 'n=%i' % (np.sum(full_resp['constricted_cond']) / full_resp['Ncells']), (0., 1.), va='top', color=ge.green) ge.annotate( inset2, '\nn=%i' % (np.sum(full_resp['dilated_cond']) / full_resp['Ncells']), (0., 1.), va='top', color=ge.purple) else: fig2 = None return fig, fig2
def plot_trial_average( self, # episodes props protocol_id=0, quantity='Photodiode-Signal', subquantity='dF/F', roiIndex=0, dt_sampling=1, # ms interpolation='linear', baseline_substraction=False, prestim_duration=None, condition=None, COL_CONDS=None, column_keys=[], column_key='', ROW_CONDS=None, row_keys=[], row_key='', COLOR_CONDS=None, color_keys=[], color_key='', fig_preset='', xbar=0., xbarlabel='', ybar=0., ybarlabel='', with_std=True, with_screen_inset=False, with_stim=True, with_axis=False, with_stat_test=False, stat_test_props={}, color='k', label='', ylim=None, xlim=None, fig=None, AX=None, verbose=False): # ----- building episodes ------ self.roiIndices = [roiIndex] self.CaImaging_key = subquantity self.EPISODES = build_episodes( self, protocol_id=protocol_id, quantity=quantity, prestim_duration=prestim_duration, dt_sampling=dt_sampling, baseline_substraction=baseline_substraction, verbose=verbose) # this sets "self.Pcond" if with_screen_inset and (self.visual_stim is None): print('initializing stim [...]') self.init_visual_stim() if condition is None: condition = np.ones(np.sum(self.Pcond), dtype=bool) elif len(condition) == len(self.Pcond): condition = condition[self.Pcond] # ----- building episodes ------ if column_key != '': COL_CONDS = self.build_conditions([ np.sort( np.unique( self.nwbfile.stimulus[column_key].data[self.Pcond])) ], [column_key]) elif column_keys != '': COL_CONDS = self.build_conditions([ np.sort(np.unique(self.nwbfile.stimulus[key].data[self.Pcond])) for key in column_keys ], column_keys) elif (COL_CONDS is None): COL_CONDS = [np.ones(np.sum(self.Pcond), dtype=bool)] if row_key != '': ROW_CONDS = self.build_conditions([ np.sort( np.unique(self.nwbfile.stimulus[row_key].data[self.Pcond])) ], [row_key]) elif row_keys != '': ROW_CONDS = self.build_conditions([ np.sort(np.unique(self.nwbfile.stimulus[key].data[self.Pcond])) for key in row_keys ], row_keys) elif (ROW_CONDS is None): ROW_CONDS = [np.ones(np.sum(self.Pcond), dtype=bool)] if COLOR_CONDS is None: COLOR_CONDS = [np.ones(np.sum(self.Pcond), dtype=bool)] # if (len(COLOR_CONDS)>1) and (self.color.text()!=''): # COLORS = [getattr(ge, self.color.text())((c%10)/10.) for c in np.arange(len(COLOR_CONDS))] # elif (len(COLOR_CONDS)>1): # COLORS = [ge.tab10((c%10)/10.) for c in np.arange(len(COLOR_CONDS))] # elif self.color.text()!='': # COLORS = [getattr(ge, self.color.text())] # else: COLORS = [color] if (fig is None) and (AX is None) and (fig_preset == 'raw-traces-preset'): fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)), reshape_axes=False, top=0.4, bottom=0.4, left=0.7, right=0.7, wspace=0.5, hspace=0.5) elif (fig is None) and (AX is None): fig, AX = ge.figure(axes=(len(COL_CONDS), len(ROW_CONDS)), reshape_axes=False) self.ylim = [np.inf, -np.inf] for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): for icolor, color_cond in enumerate(COLOR_CONDS): cond = np.array( condition & col_cond & row_cond & color_cond)[:self.EPISODES['resp'].shape[0]] if self.EPISODES['resp'][cond, :].shape[0] > 0: my = self.EPISODES['resp'][cond, :].mean(axis=0) if with_std: sy = self.EPISODES['resp'][cond, :].std(axis=0) ge.plot(self.EPISODES['t'], my, sy=sy, ax=AX[irow][icol], color=COLORS[icolor], lw=1) self.ylim = [ min([self.ylim[0], np.min(my - sy)]), max([self.ylim[1], np.max(my + sy)]) ] else: AX[irow][icol].plot(self.EPISODES['t'], my, color=COLORS[icolor], lw=1) self.ylim = [ min([self.ylim[0], np.min(my)]), max([self.ylim[1], np.max(my)]) ] if with_screen_inset: inset = ge.inset(AX[irow][icol], [.8, .9, .3, .25]) self.visual_stim.show_frame(\ self.EPISODES['index_from_start'][cond][0], ax=inset, enhance=True, label=None) if with_stat_test: for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): for icolor, color_cond in enumerate(COLOR_CONDS): cond = np.array( single_cond & col_cond & row_cond & color_cond)[:self.EPISODES['resp'].shape[0]] test = stat_test_for_evoked_responses( self.EPISODES, cond, **stat_test_props) AX[irow][icol].plot(stat_test_props['interval_pre'], self.ylim[0] * np.ones(2), 'k-', lw=1) AX[irow][icol].plot(stat_test_props['interval_post'], self.ylim[0] * np.ones(2), 'k-', lw=1) ps, size = pval_to_star(test) AX[irow][icol].annotate( ps, ((stat_test_props['interval_post'][0] + stat_test_props['interval_pre'][1]) / 2., self.ylim[0]), va='top', ha='center', size=size, xycoords='data') if xlim is None: self.xlim = [self.EPISODES['t'][0], self.EPISODES['t'][-1]] else: self.xlim = xlim if ylim is not None: self.ylim = ylim for irow, row_cond in enumerate(ROW_CONDS): for icol, col_cond in enumerate(COL_CONDS): ge.set_plot( AX[irow][icol], spines=(['left', 'bottom'] if with_axis else []), # xlabel=(self.xbarlabel.text() if with_axis else ''), # ylabel=(self.ybarlabel.text() if with_axis else ''), ylim=self.ylim, xlim=self.xlim) if with_stim: AX[irow][icol].fill_between( [0, np.mean(self.EPISODES['time_duration'])], self.ylim[0] * np.ones(2), self.ylim[1] * np.ones(2), color='grey', alpha=.2, lw=0) if not with_axis: ge.draw_bar_scales(AX[0][0], Xbar=xbar, Xbar_label=xbarlabel, Ybar=ybar, Ybar_label=ybarlabel, Xbar_fraction=0.1, Xbar_label_format='%.1f', Ybar_fraction=0.2, Ybar_label_format='%.1f', loc='top-left') if label != '': ge.annotate(fig, label, (0, 0), color=color, ha='left', va='bottom') # if self.annot.isChecked(): # S='' # if hasattr(self, 'roiPick'): # S+='roi #%s' % self.roiPick.text() # for i, key in enumerate(self.varied_parameters.keys()): # if 'single-value' in getattr(self, '%s_plot' % key).currentText(): # S += ', %s=%.2f' % (key, getattr(self, '%s_values' % key).currentText()) # ge.annotate(fig, S, (0,0), color='k', ha='left', va='bottom') return fig, AX