cumulative variance plot for CompCor
@@ -544,3 +544,84 @@ def confoundplot(tseries, gs_ts, gs_dist=None, name=None,
return [ax_ts, ax_dist], gs
return ax_ts, gs
+
+
+def compcor_variance_plot(metadata_files, metadata_sources, output_file=None,
+ varexp_thresh=(0.5, 0.7, 0.9), fig=None):
+ metadata = {}
+ for file, source in zip(metadata_files, metadata_sources):
+ metadata[source] = pd.read_table(str(file))
+ metadata[source]['source'] = source
+ metadata = pd.concat(list(metadata.values()))
+ bbox_txt = {
+ 'boxstyle': 'round',
+ 'fc': 'white',
+ 'ec': 'none',
+ 'color': 'none',
+ 'linewidth': 0,
+ 'alpha': 0.8
+ }
+
+ decompositions = list(metadata.groupby(['source', 'mask']).groups.keys())
+
+ if fig is not None:
+ ax = [fig.add_subplot(1, len(decompositions), i+1)
+ for i in range(len(decompositions))]
+ elif len(decompositions) > 1:
+ fig, ax = plt.subplots(1, len(decompositions),
+ figsize=(5*len(decompositions), 5))
+ else:
+ ax = [plt.axes()]
+
+ for m, (source, mask) in enumerate(decompositions):
+ components = metadata[(metadata['mask'] == mask)
+ & (metadata['source'] == source)]
+ if len([m for s, m in decompositions if s==source]):
+ title_mask = ' ({} mask)'.format(mask)
+ else:
+ title_mask = ''
+ fig_title = '{}{}'.format(source, title_mask)
+
+ ax[m].plot(np.arange(components.shape[0]+1),
+ [0] + list(100*components['cumulative_variance_explained']),
+ color='purple',
+ linewidth=2.5)
+ ax[m].grid(False)
+ ax[m].set_xlabel('number of components in model')
+ ax[m].set_ylabel('cumulative variance explained (%)')
+ ax[m].set_title(fig_title)
+
+ varexp = {}
+
+ for i, thr in enumerate(varexp_thresh):
+ varexp[thr] = np.searchsorted(
+ components['cumulative_variance_explained'], thr) + 1
+ ax[m].axhline(y=100*thr, color='lightgrey', linewidth=0.25)
+ ax[m].axvline(x=varexp[thr], color='C{}'.format(i),
+ linewidth=2, linestyle=':')
+ ax[m].text(0, 100*thr, '{:.0f}'.format(100*thr),
+ fontsize='x-small', bbox=bbox_txt)
+ ax[m].text(varexp[thr][0], 25,
+ '{} components explain\n{:.0f}% of variance'.format(
+ varexp[thr][0], 100*thr),
+ rotation=90,
+ horizontalalignment='center',
+ fontsize='xx-small',
+ bbox=bbox_txt)
+
+ ax[m].set_yticks([])
+ ax[m].set_yticklabels([])
+ for tick in ax[m].xaxis.get_major_ticks():
+ tick.label.set_fontsize('x-small')
+ tick.label.set_rotation('vertical')
+ for side in ['top', 'right', 'left']:
+ ax[m].spines[side].set_color('none')
+ ax[m].spines[side].set_visible(False)
+
+ if output_file is not None:
+ figure = plt.gcf()
+ figure.savefig(output_file, bbox_inches='tight')
+ plt.close(figure)
+ figure = None
+ return output_file
+ return ax
