def make_category_scatter_figure(): categories = get_data() # Build a figure and place a single axes instance in it. fig = plt.figure(figsize=(4,3)) ax1 = fig.add_subplot(1,1,1) # Use our helper function to do the category scatter plot. cs = CategoryScatter( ax1, categories ) # Locate the axes spines on the left and bottom. spine_placer(ax1, location='left,bottom' ) # Finalize the category scatter plot (stuff that can only be done # after the spines are placed). cs.finalize() # Add standard y label. ax1.set_ylabel('y value (units)') # Now, add a final few touchups. ax1.spines['bottom'].set_color('none') # don't draw bottom spine ax1.yaxis.set_major_locator( mticker.MaxNLocator(nbins=4) ) auto_reduce_spine_bounds( ax1 ) fig.tight_layout() return fig
def plot_ci_for_ms(path, figname, vals, figsize=(6,4)): figname = os.path.splitext(figname)[0] NAMES = {'TH>trpA1 head':'TH>trpA1 (head)', 'TH>trpA1 thorax':'TH>trpA1 (thorax)', 'TH head':'TH (head)', 'TH thorax':'TH (thorax)', 'trpA1 head':'trpA1 (head)', 'trpA1 thorax':'trpA1 (thorax)', 'controls head':'controls (head)', 'controls thorax':'controls (thorax)', } COLORS = {'TH>trpA1 head':flymad_plot.RED, 'TH>trpA1 thorax':flymad_plot.ORANGE, 'TH head':flymad_plot.GREEN, 'TH thorax':flymad_plot.BLUE, 'trpA1 head':flymad_plot.GREEN, 'trpA1 thorax':flymad_plot.BLUE, 'controls head':flymad_plot.GREEN, 'controls thorax':flymad_plot.BLUE, } ORDER = ['TH>trpA1 head', 'TH>trpA1 thorax', 'TH head', 'TH thorax', 'trpA1 head', 'trpA1 thorax', 'controls head', 'controls thorax', ] figure_title = "THGAL4 %s cumulative incidence" % figname fig = plt.figure(figsize=figsize) ax = fig.add_subplot(1,1,1) for gt in sorted(vals, cmp=lambda a,b: cmp(ORDER.index(a), ORDER.index(b))): ax.plot(vals[gt]['x'],vals[gt]['y'], lw=2,clip_on=False, color=COLORS[gt],label=NAMES[gt]) spine_placer(ax, location='left,bottom' ) ax.legend() ax.set_xlabel('Time (s)') ax.set_ylabel('Cumulative incidence (%)') ax.set_ylim([0,100]) ax.set_xlim([0,20]) flymad_plot.retick_relabel_axis(ax, [0,10,20], [0,100]) fig.savefig(flymad_plot.get_plotpath(path,"thgal4_ci_%s.png" % figname), bbox_inches='tight') fig.savefig(flymad_plot.get_plotpath(path,"thgal4_ci_%s.svg" % figname), bbox_inches='tight')
def make_many_timeseries_figure(): # Generate some fake data in 4 timeseries times = np.arange( 0, 200.0, 0.01 ) nt = len(times) ys = [] for i in range(4): ys.append( np.sin( times*2*np.pi*0.02 + i*20 ) + 0.13*np.random.randn(nt) ) # Build a figure and place a two axes instances in it. fig = plt.figure(figsize=(8,6)) ax1 = fig.add_subplot(2,1,1) ax2 = fig.add_subplot(2,1,2) # Use our helper function to plot the multiple timeseries. mts1 = ManyTimeseries( ax1, times, ys, show=['all','mean'] ) # Use our helper function to plot the multiple timeseries. mts2 = ManyTimeseries( ax2, times, ys, show=['mean','std'] ) # Locate the axes spines. spine_placer(ax1, location='left' ) spine_placer(ax2, location='left,bottom' ) # Finalize the plots (stuff that can only be done # after the spines are placed). mts1.finalize() mts2.finalize() # Add standard axis labels. ax1.set_ylabel('y1 value (units)') ax2.set_ylabel('y2 value (units)') ax2.set_xlabel('time (seconds)') # Now, add a final few touchups. ax1.yaxis.set_major_locator( mticker.MaxNLocator(nbins=4) ) ax1.set_xticks([]) ax2.yaxis.set_major_locator( mticker.MaxNLocator(nbins=4) ) auto_reduce_spine_bounds( ax1 ) auto_reduce_spine_bounds( ax2 ) fig.tight_layout() return fig
def plot_data(path, data): ci_html_buf = '' for exp_name in data: gts = data[exp_name].keys() laser = '130ht' gts_string = 'vs'.join(gts) figname = laser + '_' + gts_string fig = plt.figure("Song (%s)" % figname, figsize=(10, 6)) ax = fig.add_subplot(1, 1, 1) datasets = {} for gt in gts: if flymad_analysis.genotype_is_exp(gt): color = flymad_plot.RED order = 1 elif flymad_analysis.genotype_is_ctrl(gt): color = flymad_plot.BLACK order = 2 elif flymad_analysis.genotype_is_trp_ctrl(gt): order = 3 color = flymad_plot.BLUE else: color = 'cyan' order = 0 gtdf = data[exp_name][gt] datasets[gt] = dict(xaxis=gtdf['mean']['t'].values, value=gtdf['mean']['zx'].values, std=gtdf['std']['zx'].values, n=gtdf['n']['zx'].values, order=order, df=gtdf, label=flymad_analysis.human_label(gt), color=color, N=len(gtdf['df']['obj_id'].unique())) pvalue_buf = '' for gt in datasets: label = flymad_analysis.human_label(gt) if '>' not in label: continue # OK, this is a Gal4 + UAS - do head vs thorax stats gtdf = data[exp_name][gt]['df'] ci_data = do_cum_incidence(gtdf, label) ci_html_buf += ci_data['buf'] ax_cum = ci_data['ax'] spine_placer(ax_cum, location='left,bottom') ax_cum.set_ylabel('Fraction extending wing (%)') ax_cum.set_xlabel('Time (s)') note = '%s\n%s\np-value: %.3g\n%d flies\nn=%d, %d' % ( label, madplot.p2stars(ci_data['p_value']), ci_data['p_value'], len(gtdf['obj_id'].unique()), ci_data['n_head'], ci_data['n_thorax']) ax_cum.text( 0, 1, #top left note, fontsize=10, horizontalalignment='left', verticalalignment='top', transform=ax_cum.transAxes, zorder=0) ci_data['fig'].savefig(flymad_plot.get_plotpath( path, "song_cum_inc_%s.png" % figname), bbox_inches='tight') ci_data['fig'].savefig(flymad_plot.get_plotpath( path, "song_cum_inc_%s.svg" % figname), bbox_inches='tight') # for i in range(len(head_times)): # head_values = gtdf[gtdf['t']==head_times[i]] # thorax_values = gtdf[gtdf['t']==thorax_times[i]] # test1 = head_values['zx'].values # test2 = thorax_values['zx'].values # hval, pval = kruskal(test1, test2) # pvalue_buf += 'Pulse %d: Head vs thorax WEI p-value: %.3g (n=%d, %d)\n'%( # i+1, pval, len(test1), len(test2) ) #all experiments used identical activation times headtargetbetween = dict( xaxis=data['pIP10']['wtrpmyc']['first']['t'].values, where=data['pIP10']['wtrpmyc']['first']['ttm'].values > 0) thoraxtargetbetween = dict( xaxis=data['pIP10']['wtrpmyc']['first']['t'].values, where=data['pIP10']['wtrpmyc']['first']['ttm'].values < 0) flymad_plot.plot_timeseries_with_activation( ax, targetbetween=[headtargetbetween, thoraxtargetbetween], sem=True, note=pvalue_buf, **datasets) ax.set_xlabel('Time (s)') ax.set_ylabel('Wing extension index') ax.set_ylim([-0.05, 0.4] if gts_string == "40347vswtrpmycvs40347trpmyc" else [-0.05, 1.0]) ax.set_xlim([-10, 180]) flymad_plot.retick_relabel_axis( ax, [0, 60, 120, 180], [0, 0.2, 0.4] if gts_string == "40347vswtrpmycvs40347trpmyc" else [0, 0.5, 1]) fig.savefig(flymad_plot.get_plotpath(path, "song_%s.png" % figname), bbox_inches='tight') fig.savefig(flymad_plot.get_plotpath(path, "song_%s.svg" % figname), bbox_inches='tight') with open(flymad_plot.get_plotpath(path, "song_cum_in.html"), mode='w') as fd: fd.write(ci_html_buf)
def plot_ci_for_ms(path, figname, vals, figsize=(6, 4)): figname = os.path.splitext(figname)[0] NAMES = { 'TH>trpA1 head': 'TH>trpA1 (head)', 'TH>trpA1 thorax': 'TH>trpA1 (thorax)', 'TH head': 'TH (head)', 'TH thorax': 'TH (thorax)', 'trpA1 head': 'trpA1 (head)', 'trpA1 thorax': 'trpA1 (thorax)', 'controls head': 'controls (head)', 'controls thorax': 'controls (thorax)', } COLORS = { 'TH>trpA1 head': flymad_plot.RED, 'TH>trpA1 thorax': flymad_plot.ORANGE, 'TH head': flymad_plot.GREEN, 'TH thorax': flymad_plot.BLUE, 'trpA1 head': flymad_plot.GREEN, 'trpA1 thorax': flymad_plot.BLUE, 'controls head': flymad_plot.GREEN, 'controls thorax': flymad_plot.BLUE, } ORDER = [ 'TH>trpA1 head', 'TH>trpA1 thorax', 'TH head', 'TH thorax', 'trpA1 head', 'trpA1 thorax', 'controls head', 'controls thorax', ] figure_title = "THGAL4 %s cumulative incidence" % figname fig = plt.figure(figsize=figsize) ax = fig.add_subplot(1, 1, 1) for gt in sorted(vals, cmp=lambda a, b: cmp(ORDER.index(a), ORDER.index(b))): ax.plot(vals[gt]['x'], vals[gt]['y'], lw=2, clip_on=False, color=COLORS[gt], label=NAMES[gt]) spine_placer(ax, location='left,bottom') ax.legend() ax.set_xlabel('Time (s)') ax.set_ylabel('Cumulative incidence (%)') ax.set_ylim([0, 100]) ax.set_xlim([0, 20]) flymad_plot.retick_relabel_axis(ax, [0, 10, 20], [0, 100]) fig.savefig(flymad_plot.get_plotpath(path, "thgal4_ci_%s.png" % figname), bbox_inches='tight') fig.savefig(flymad_plot.get_plotpath(path, "thgal4_ci_%s.svg" % figname), bbox_inches='tight')
color='black', linewidth=0.5, ) ax.errorbar( [this_x_value], [np.mean(this_y_values)], [scipy.stats.sem(this_y_values)], clip_on=False, color='black', linewidth=0.5, capsize=2, ) xticks.append(this_x_value) tick_labels.append(name_key) spine_placer(ax, location='left,bottom') ax.spines['bottom'].set_color('none') ax.spines['bottom'].set_position(('outward', 5)) ax.set_yticks([0, 20]) ax.set_xticks(xticks) ax.set_xticklabels(tick_labels, rotation='vertical') ax.set_ylabel('latency (sec)') fig1.subplots_adjust(left=0.4, bottom=0.65) # do not clip text svg1_fname = 'th_gal4_latency_%s_%s.svg' % (measurement, pooled_str) fig1.savefig(svg1_fname) # --- plots -------------------------------- fig2 = plt.figure('scatter ' + measurement + pooled_str, figsize=(3, 5)) ax = fig2.add_subplot(111)
clip_on=False, color='black', linewidth=0.5, ) ax.errorbar( [this_x_value], [ np.mean(this_y_values) ], [ scipy.stats.sem( this_y_values ) ], clip_on=False, color='black', linewidth=0.5, capsize=2, ) xticks.append( this_x_value ) tick_labels.append( name_key ) spine_placer(ax, location='left,bottom' ) ax.spines['bottom'].set_color('none') ax.spines['bottom'].set_position(('outward',5)) ax.set_yticks([0,20]) ax.set_xticks(xticks) ax.set_xticklabels(tick_labels, rotation='vertical') ax.set_ylabel('latency (sec)') fig1.subplots_adjust(left=0.4,bottom=0.65) # do not clip text svg1_fname = 'th_gal4_latency_%s_%s.svg'%(measurement,pooled_str) fig1.savefig(svg1_fname) # --- plots -------------------------------- fig2 = plt.figure('scatter '+measurement+pooled_str,figsize=(3,5)) ax = fig2.add_subplot(111) tick_labels = [] xticks = []
def plot_data(path, data): ci_html_buf = '' for exp_name in data: gts = data[exp_name].keys() laser = '130ht' gts_string = 'vs'.join(gts) figname = laser + '_' + gts_string fig = plt.figure("Song (%s)" % figname,figsize=(10,6)) ax = fig.add_subplot(1,1,1) datasets = {} for gt in gts: if flymad_analysis.genotype_is_exp(gt): color = flymad_plot.RED order = 1 elif flymad_analysis.genotype_is_ctrl(gt): color = flymad_plot.BLACK order = 2 elif flymad_analysis.genotype_is_trp_ctrl(gt): order = 3 color = flymad_plot.BLUE else: color = 'cyan' order = 0 gtdf = data[exp_name][gt] datasets[gt] = dict(xaxis=gtdf['mean']['t'].values, value=gtdf['mean']['zx'].values, std=gtdf['std']['zx'].values, n=gtdf['n']['zx'].values, order=order, df=gtdf, label=flymad_analysis.human_label(gt), color=color, N=len(gtdf['df']['obj_id'].unique())) pvalue_buf = '' for gt in datasets: label=flymad_analysis.human_label(gt) if '>' not in label: continue # OK, this is a Gal4 + UAS - do head vs thorax stats gtdf = data[exp_name][gt]['df'] ci_data = do_cum_incidence(gtdf, label) ci_html_buf += ci_data['buf'] ax_cum = ci_data['ax'] spine_placer(ax_cum, location='left,bottom' ) ax_cum.set_ylabel('Fraction extending wing (%)') ax_cum.set_xlabel('Time (s)') note = '%s\n%s\np-value: %.3g\n%d flies\nn=%d, %d'%(label, madplot.p2stars(ci_data['p_value']), ci_data['p_value'], len(gtdf['obj_id'].unique()), ci_data['n_head'], ci_data['n_thorax']) ax_cum.text(0, 1, #top left note, fontsize=10, horizontalalignment='left', verticalalignment='top', transform=ax_cum.transAxes, zorder=0) ci_data['fig'].savefig(flymad_plot.get_plotpath(path,"song_cum_inc_%s.png" % figname), bbox_inches='tight') ci_data['fig'].savefig(flymad_plot.get_plotpath(path,"song_cum_inc_%s.svg" % figname), bbox_inches='tight') # for i in range(len(head_times)): # head_values = gtdf[gtdf['t']==head_times[i]] # thorax_values = gtdf[gtdf['t']==thorax_times[i]] # test1 = head_values['zx'].values # test2 = thorax_values['zx'].values # hval, pval = kruskal(test1, test2) # pvalue_buf += 'Pulse %d: Head vs thorax WEI p-value: %.3g (n=%d, %d)\n'%( # i+1, pval, len(test1), len(test2) ) #all experiments used identical activation times headtargetbetween = dict(xaxis=data['pIP10']['wtrpmyc']['first']['t'].values, where=data['pIP10']['wtrpmyc']['first']['ttm'].values > 0) thoraxtargetbetween = dict(xaxis=data['pIP10']['wtrpmyc']['first']['t'].values, where=data['pIP10']['wtrpmyc']['first']['ttm'].values < 0) flymad_plot.plot_timeseries_with_activation(ax, targetbetween=[headtargetbetween,thoraxtargetbetween], sem=True, note=pvalue_buf, **datasets ) ax.set_xlabel('Time (s)') ax.set_ylabel('Wing extension index') ax.set_ylim([-0.05,0.4] if gts_string == "40347vswtrpmycvs40347trpmyc" else [-0.05,1.0]) ax.set_xlim([-10,180]) flymad_plot.retick_relabel_axis(ax, [0, 60, 120, 180], [0, 0.2, 0.4] if gts_string == "40347vswtrpmycvs40347trpmyc" else [0, 0.5, 1]) fig.savefig(flymad_plot.get_plotpath(path,"song_%s.png" % figname), bbox_inches='tight') fig.savefig(flymad_plot.get_plotpath(path,"song_%s.svg" % figname), bbox_inches='tight') with open(flymad_plot.get_plotpath(path,"song_cum_in.html"),mode='w') as fd: fd.write(ci_html_buf)
def plot_timeseries_with_activation(ax, targetbetween=None, downsample=1, sem=False, legend_location='upper right', note="", individual=None, individual_title=None, marker=None,linestyle='-',markersize=1, return_dict=False, **datasets): ORDER_LAST = 100 DEFAULT_COLORS = {"exp":RED,"ctrl":BLACK} trans = mtransforms.blended_transform_factory(ax.transData, ax.transAxes) final_copy = os.environ.get('FLYMAD_FINAL') def _ds(a): if downsample == 1: return a else: tmp = [] for i in range(0,len(a),downsample): vals = a[i:i+downsample] tmp.append( scipy.stats.nanmean(vals) ) return np.array(tmp) def _dn(a,b): nans_a, = np.where(np.isnan(a)) nans_b, = np.where(np.isnan(b)) nans_all = np.union1d(nans_a, nans_b) n_nans = len(nans_all) if n_nans: print "\tremoving %d nans from plot" % n_nans clean_a = np.delete(a,nans_all) clean_b = np.delete(b,nans_all) return clean_a, clean_b def _sort_by_order(a,b): return cmp(datasets[a].get('order', ORDER_LAST), datasets[b].get('order', ORDER_LAST)) def _fill_between(f_ax, f_xaxis, f_where, f_facecolor, f_zorder): f_ax.fill_between(f_xaxis, 0, 1, where=f_where, edgecolor='none', facecolor=f_facecolor, alpha=0.15, transform=trans, zorder=f_zorder) if targetbetween is not None: if not (isinstance(targetbetween, list) or isinstance(targetbetween, tuple)): targetbetween = [targetbetween] for tb in targetbetween: _fill_between(ax, tb['xaxis'], tb['where'], tb.get('facecolor','yellow'), tb.get('zorder',1)) if any(['std' in datasets[exp] for exp in datasets]): note += "+/- SEM\n" if sem else "+/- STD\n" note += "" if downsample == 1 else ("downsample x %d\n" % downsample) #zorder = 1 = back top_zorder = 60 bottom_zorder = 30 plotted = {} exps_colors = [plt.cm.gnuplot(i) for i in np.linspace(0, 1.0, len(datasets))] cur_zorder = 2 for data,default_color in zip(sorted(datasets.keys(), cmp=_sort_by_order), exps_colors): exp = datasets[data] label = exp.get('label',data) note += "N(%s)=%s\n" % (label,exp.get('N','??')) if exp.get('ontop'): this_zorder = top_zorder + cur_zorder else: this_zorder = bottom_zorder + cur_zorder print "plotting %s (%s) zorder %s" % (label,data,this_zorder) if 'std' in exp: if sem: spread = exp['std'] / np.sqrt(exp['n']) else: spread = exp['std'] else: spread = None if exp.get('color') is None: color = default_color else: color = DEFAULT_COLORS.get(data,default_color) if spread is not None: ax.fill_between(exp['xaxis'][::downsample], _ds(exp['value']+spread), _ds(exp['value']-spread), alpha=0.1, color=color, zorder=this_zorder) x,y = _dn(exp['xaxis'][::downsample], _ds(exp['value'])) zorder = this_zorder + 1 plotted[data] = dict(x=x,y=y,color=color,label=label,zorder=zorder) ax.plot(x,y, color=color,label=label, lw=2,linestyle=linestyle,clip_on=exp.get('clip_on',True), marker=marker,markerfacecolor=color,markersize=markersize,markeredgecolor='none', zorder=zorder) cur_zorder -= 2 spine_placer(ax, location='left,bottom' ) l = ax.legend(loc=legend_location) l.set_zorder(1+top_zorder+cur_zorder) ax.text(0, 1, #top left note, fontsize=10, horizontalalignment='left', verticalalignment='top', transform=ax.transAxes, color='white' if final_copy else 'k', zorder=-100) axs = [ax] figs = {} if (not final_copy) and (individual is not None) and isinstance(individual, dict): for data in individual: try: #try to avoid creating many duplicate figures #based on the title be unique if provided if individual_title: fignum = hash(individual_title) if plt.fignum_exists(fignum): continue else: fignum = None individual_title = "" individual_title += data gdf = datasets[data]['df'] groupcol = individual[data]['groupby'] xcol = individual[data]['xaxis'] ycol = individual[data]['yaxis'] grouper = gdf.groupby(groupcol) nts = len(grouper) gs,nr_nc = get_gridspec_to_fit_nplots(nts) fig2 = plt.figure(fignum, figsize=(2*max(nr_nc),2*max(nr_nc))) fig2.suptitle(individual_title) print 'plotting', nts, 'individual timeseries for', data for gridspec_id,(name,group) in zip(gs,grouper): #we can't assume these are numpy arrays here, but #np.array does the right thing and converts pandas things #while being no-op on np arrays grp_xaxis = np.array(group[xcol]) grp_yaxis = np.array(group[ycol]) iax = fig2.add_subplot(gridspec_id) print "\tplot",name,xcol,"vs",ycol x,y = _dn(grp_xaxis[::downsample], _ds(grp_yaxis)) iax.plot(x, y, label=str(name), color='k') iax.legend(loc=legend_location) # if fb_wherecol: # _fill_between(iax, # grp_xaxis, # np.array(group[fb_wherecol]) > 0, # 'yellow') axs.append(iax) figs[md5.md5(individual_title).hexdigest()] = fig2 except KeyError, e: print "\terror plotting individual timeseries (%s)" % e
def plot_timeseries_with_activation(ax, targetbetween=None, downsample=1, sem=False, legend_location='upper right', note="", individual=None, individual_title=None, marker=None, linestyle='-', markersize=1, return_dict=False, **datasets): ORDER_LAST = 100 DEFAULT_COLORS = {"exp": RED, "ctrl": BLACK} trans = mtransforms.blended_transform_factory(ax.transData, ax.transAxes) final_copy = os.environ.get('FLYMAD_FINAL') def _ds(a): if downsample == 1: return a else: tmp = [] for i in range(0, len(a), downsample): vals = a[i:i + downsample] tmp.append(scipy.stats.nanmean(vals)) return np.array(tmp) def _dn(a, b): nans_a, = np.where(np.isnan(a)) nans_b, = np.where(np.isnan(b)) nans_all = np.union1d(nans_a, nans_b) n_nans = len(nans_all) if n_nans: print "\tremoving %d nans from plot" % n_nans clean_a = np.delete(a, nans_all) clean_b = np.delete(b, nans_all) return clean_a, clean_b def _sort_by_order(a, b): return cmp(datasets[a].get('order', ORDER_LAST), datasets[b].get('order', ORDER_LAST)) def _fill_between(f_ax, f_xaxis, f_where, f_facecolor, f_zorder): f_ax.fill_between(f_xaxis, 0, 1, where=f_where, edgecolor='none', facecolor=f_facecolor, alpha=0.15, transform=trans, zorder=f_zorder) if targetbetween is not None: if not (isinstance(targetbetween, list) or isinstance(targetbetween, tuple)): targetbetween = [targetbetween] for tb in targetbetween: _fill_between(ax, tb['xaxis'], tb['where'], tb.get('facecolor', 'yellow'), tb.get('zorder', 1)) if any(['std' in datasets[exp] for exp in datasets]): note += "+/- SEM\n" if sem else "+/- STD\n" note += "" if downsample == 1 else ("downsample x %d\n" % downsample) #zorder = 1 = back top_zorder = 60 bottom_zorder = 30 plotted = {} exps_colors = [ plt.cm.gnuplot(i) for i in np.linspace(0, 1.0, len(datasets)) ] cur_zorder = 2 for data, default_color in zip(sorted(datasets.keys(), cmp=_sort_by_order), exps_colors): exp = datasets[data] label = exp.get('label', data) note += "N(%s)=%s\n" % (label, exp.get('N', '??')) if exp.get('ontop'): this_zorder = top_zorder + cur_zorder else: this_zorder = bottom_zorder + cur_zorder print "plotting %s (%s) zorder %s" % (label, data, this_zorder) if 'std' in exp: if sem: spread = exp['std'] / np.sqrt(exp['n']) else: spread = exp['std'] else: spread = None if exp.get('color') is None: color = default_color else: color = DEFAULT_COLORS.get(data, default_color) if spread is not None: ax.fill_between(exp['xaxis'][::downsample], _ds(exp['value'] + spread), _ds(exp['value'] - spread), alpha=0.1, color=color, zorder=this_zorder) x, y = _dn(exp['xaxis'][::downsample], _ds(exp['value'])) zorder = this_zorder + 1 plotted[data] = dict(x=x, y=y, color=color, label=label, zorder=zorder) ax.plot(x, y, color=color, label=label, lw=2, linestyle=linestyle, clip_on=exp.get('clip_on', True), marker=marker, markerfacecolor=color, markersize=markersize, markeredgecolor='none', zorder=zorder) cur_zorder -= 2 spine_placer(ax, location='left,bottom') l = ax.legend(loc=legend_location) l.set_zorder(1 + top_zorder + cur_zorder) ax.text( 0, 1, #top left note, fontsize=10, horizontalalignment='left', verticalalignment='top', transform=ax.transAxes, color='white' if final_copy else 'k', zorder=-100) axs = [ax] figs = {} if (not final_copy) and (individual is not None) and isinstance( individual, dict): for data in individual: try: #try to avoid creating many duplicate figures #based on the title be unique if provided if individual_title: fignum = hash(individual_title) if plt.fignum_exists(fignum): continue else: fignum = None individual_title = "" individual_title += data gdf = datasets[data]['df'] groupcol = individual[data]['groupby'] xcol = individual[data]['xaxis'] ycol = individual[data]['yaxis'] grouper = gdf.groupby(groupcol) nts = len(grouper) gs, nr_nc = get_gridspec_to_fit_nplots(nts) fig2 = plt.figure(fignum, figsize=(2 * max(nr_nc), 2 * max(nr_nc))) fig2.suptitle(individual_title) print 'plotting', nts, 'individual timeseries for', data for gridspec_id, (name, group) in zip(gs, grouper): #we can't assume these are numpy arrays here, but #np.array does the right thing and converts pandas things #while being no-op on np arrays grp_xaxis = np.array(group[xcol]) grp_yaxis = np.array(group[ycol]) iax = fig2.add_subplot(gridspec_id) print "\tplot", name, xcol, "vs", ycol x, y = _dn(grp_xaxis[::downsample], _ds(grp_yaxis)) iax.plot(x, y, label=str(name), color='k') iax.legend(loc=legend_location) # if fb_wherecol: # _fill_between(iax, # grp_xaxis, # np.array(group[fb_wherecol]) > 0, # 'yellow') axs.append(iax) figs[md5.md5(individual_title).hexdigest()] = fig2 except KeyError, e: print "\terror plotting individual timeseries (%s)" % e