danjgale / surfplot

A package for publication-ready brain surface figures
https://surfplot.readthedocs.io/en/latest/
Other
53 stars 14 forks source link

Can a surfplot figure be added as a subfigure in Matplotlib ? #15

Closed maelleF closed 2 years ago

maelleF commented 2 years ago

Hi ! I wanted to create a figure with multiple subjects renders, and I understood that the result of p.build() is a figure from matplotlib, so I tried using different strategies using subfigures (https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subfigures.html), but it seems that p.build() override as the main figure each time I tried. I didn't find any option in your documentation, so I wanted to know if surfplot figures are compatible with subfigures ?

#mesh, gii_like data for surface visualisation
fslr = datasets.fetch_fslr()
lh, rh = fslr['inflated'] #'inflated' 'midthickness'
p = spl.Plot(surf_lh=lh, surf_rh=rh)

#main figure
whole_fig = plt.figure()
subs_figs = whole_fig.subfigures(1,len(subs))
grid = plt.GridSpec(1, len(subs))

positions = range(len(subs))
#data for each subject
for sub, pos in zip(subs, positions):
    #select data sub
    # ...
    #transform data from parcellation to volumetric (niimg)
    r2_img = nilearn.regions.signals_to_img_labels(data_sub,MIST_path)
    #transform data from volumetric to surface/vertices (giimg)
    gii_lh, gii_rh = transforms.mni152_to_fslr(r2_img, fslr_density='32k', method='linear')

    p = spl.Plot(surf_lh=lh, surf_rh=rh)#, label_text={'top':sub})
    p.add_layer({'left': gii_lh, 'right': gii_rh})
    subs_figs[pos] = p.build()

whole_fig.suptitle('test', fontsize='xx-large')   
savepath = os.path.join(results_path, 'test_surface')
whole_fig.savefig(savepath)
plt.close()

Thanks in advance for your understanding

danjgale commented 2 years ago

Hi @maelleF!

You are correct, the .build() method returns a full matplotlib figure. This is required to include colourbars (if specified) in the output. The best workaround I can think of is to save each subject's surfplot figure as an image, and then afterwards, load each image into suplots of a separate figure (i.e. using a function like plt.imread())

maelleF commented 2 years ago

Sorry for the late answer, I also had different conversations with colleagues and we had the same conclusions to use the surfplot image. Thanks for your input !