To visualise the topographical distribution of electric or magnetic brain activity on the head, FieldTrip uses a family of topoplot functions. There are several styles to choose from, which determine o.a. if contour lines will be plotted on top of the color image.
Now, the default setting cfg.style = ‘both’ (with contour lines) or cfg.style = ‘straight’ (without contour lines) rely on contour or contourf, which in Matlab 2014b and later plot a set of triangles rather than one rasterised figure. This massively increases file sizes, and can cause weird artefacts when saving and viewing as pdf (elaborate rant here).
Luckily, FieldTrip’s topoplot functions have the option cfg.style = ‘both_imsat’ or cfg.style = ‘straight_imsat’, which both call imagesc which produces smaller-size, rasterised topoplots. This setting changed one pdf document with 20 topoplots from 9 MB to 100 KB, without the need to save as bitmap. The ‘imsat’ styles are not documented in the high-level FieldTrip function, but if you want to do the detective work yourself I’d recommend having a look at topoplot_common, line 745.
tldr; FieldTrip’s topoplots, saved to pdf, will be ± 2MB smaller when using cfg.style = ‘straight_imsat’.
Disclaimer: this works in Matlab 2015a, FieldTrip version 0979eda, using the Painters renderer and saving to pdf.
8 thoughts on “Rasterised topoplots in FieldTrip”
This is very useful, thanks! I did not know of this simple way in fieldtrip to do it!
I usually use the eeglab topoplot function and did something similar there (i.e. export as png). Obviously then the electrodes/head are not vectors. But in eeglab it is possible to plot only the head/electrodes/contours. This I export in addition to the rasterized version and combine it in illustrator. As I tend to have many topoplots over time, I usually simply run my whole plotting script once with data, rasterized, and once with the vectors to later overlay.I did not find an automated version that later combines it.
Now my question: In fieldtrip, is the whole thing rasterized or only the data, but the lines are vectors? This would be a big advantage over my current solution.
The exact implementation depends on the code that does the actual plotting: in FieldTrip, using the straight_imsat style will first plot the colors using imagesc (rasterised) and then the contours of the head/nose/ears as a vector – see https://github.com/fieldtrip/fieldtrip/blob/master/plotting/ft_plot_topo.m. So this would do exactly what you now do manually!
I’m surprised that you say it’s different in EEGlab, since https://sccn.ucsd.edu/svn/software/eeglab/functions/sigprocfunc/topoplot.m seems to use imagesc and then contour on top… but I’ve never used EEGlab’s own topoplot function.
Another thing I do after plotting is making the head/nose/ears lines thinner, since I don’t like the very thick black lines. This does the trick:
lineObj = findobj(gca, ‘type’, ‘line’);
for l = 1:length(lineObj),
if get(lineObj(l), ‘LineWidth’) > 0.5,
set(lineObj(l), ‘LineWidth’, 0.5);
One downside of FieldTrip is that it does not support the extrapolated ‘skirt’ around the head that EEGlab achieves with the ‘plotrad’ option, and which I quite like… well, no software is perfect!
I think eeglab uses imagesc only if you specify ‘method’,”grid” and else uses the surface function (‘method’,’both’ is the default and indeed uses surface). ‘grid’ might allow an analogous solution which would be extremely nice 🙂
I will check it out as soon as I need to export topoplots again (hopefully sooner than later :D)
Thanks for the comment and the helpful line trick.
Thanks for these tips! Hopefully I’ll be trying them out soon 😉
Regarding the extrapolated skirt: FieldTrip can actually also plot those (see e.g. http://bit.ly/2fwlkus), but requires that you provide a corresponding layout. The (old) default is that electrodes from an ASCII *.lay file are squeezed into a sphere with a triangle (nose) at the top. If you specify a layout as *.mat file, you can include a “mask” and an “outline”. Try this
>> load CTF275_helmet.mat
and look into the CTF helmet layout structure.
It would be nice if someone would provide those as alternatives for the set of 10-20 EEG layouts that we now include in the release 😉
Thanks Robert, I’ll definitely be using the extrapolated helmet layout! I’ve added it to the list of CTF layouts on the Fieldtrip templates page.
Related to a discussion Benedikt and I had (see below), would FieldTrip ever consider changing its default colormap (e.g. to blue-white-red as shown above for ‘maxmin’ zlims, and magma for positive-only data)? There are many nice options out there, all of which are better than jet for interpreting and understanding color scales (for example, https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html) – Matlab already changed its default to parula, but this is not great for data with a natural zero-point.
Anne and I had a separate small discussion via FB. I repost it here because we thought it adds value to other users as well
> Benedikt Ehinger:
Thanks great post again! I left a comment & question. This reminds me that I wanted to write a blogpost about better contourlines in topoplots…
> Anne Urai
good to know there are more people out there who find these things worth their time 🙂 In my opinion, the best contourlines are no contourlines! Nicer to use lines to indicate significant clusters, and let the colormap speak for itself.
mhhh. as we learned from Tony colormaps can be deceiving. I think if contourlines are properly specified they do show great value. Contourlines for significance I’m not sure, where do you place them? do you interpolate the p-values?
I rather like the one you used in your example, show the electrodes that are significant. Or what I try to do, show the TFCE-cluster corrected p-values topoplots as an extra line of topoplots (this does not work well for normal clusters).
I tried to use transparency for significant clusters way back, but never got it to look adequately. So I might actually try out contourlines
If you are interested in this functionality in eeglab I made a small script available on github:
I leave it here because somebody might find this discussion via google