I would like to adapt the example I have found in this page and readapt it to my data in order to get the final topoplot realized with ggplot2
topoplot in ggplot2 – 2D visualisation of e.g. EEG data
Unfortunately it seems I having some problem with the interpolation system. Indeed when I try to plot the coordinates, they have spatial distribution very different from what they are supposed to be (my case is on the right and there is a different scale too)
This creates a problem to make work the interpolation example posted there. I tried to find some workaround and I used a different system with another package, called MBA
dat_interp <- mba.surf(cbind(dat$x, dat$y, dat$signal), no.X = 1000, no.Y = 1000)$xyz.est
mba_result <- MBA::mba.surf(cbind(dat$x, dat$y, dat$signal),
no.X = 1000, no.Y = 1000)
dat_interp_df <- expand.grid(x = dat_interp$x, y = dat_interp$y)
dat_interp_df$signal <- as.vector(dat_interp$z)
ggplot() +
geom_tile(data = dat_interp_df, aes(x = x, y = y, fill = signal)) +
geom_point(data = dat, aes(x = x, y = y, color = signal),
shape = 21, colour = 'black', fill = 'white', size = 2) +
scale_fill_viridis_c() +
scale_color_viridis_c() +
ggtitle("Topography") +
theme_void()
which is a result far away from what I would liek to recreate. Is there anyone that can help me with this out. Here as follows my data:
dput(dat)
structure(list(X = 1:64, label = c("AF3", "AF4", "AF7", "AF8",
"AFz", "C1", "C2", "C3", "C4", "C5", "C6", "CP1", "CP2", "CP3",
"CP4", "CP5", "CP6", "CPz", "Cz", "F1", "F2", "F3", "F4", "F5",
"F6", "F7", "F8", "FC1", "FC2", "FC3", "FC4", "FC5", "FC6", "FCz",
"FT7", "FT8", "Fp1", "Fp2", "Fpz", "Fz", "Iz", "O1", "O2", "Oz",
"P1", "P10", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9",
"PO3", "PO4", "PO7", "PO8", "POz", "Pz", "T7", "T8", "TP7", "TP8"
), x = c(-33.706, 35.738, -54.873, 55.806, 0.23117, -36.269,
37.675, -65.418, 67.104, -80.273, 83.413, -35.631, 38.16, -64.113,
66.3, -79.863, 83.134, 0, 0.47908, -27.501, 29.475, -50.221,
51.912, -64.49, 67.878, -70.233, 73.024, -34.049, 34.793, -60.191,
62.341, -77.199, 79.561, 0.37692, -80.826, 81.786, -29.391, 29.902,
0.11233, 0.31257, 0, -30.195, 29.937, 0, -29.247, 74.343, 32.545,
-53, 55.408, -66.98, 68.381, -72.811, 72.81, -73.635, -36.844,
36.608, -54.282, 55.984, 0, 0, -84.117, 85.068, -85.242, 85.591
), y = c(76.785, 77.701, 68.493, 69.657, 80.761, -9.7183, -9.3934,
-11.535, -10.868, -13.721, -12.764, -47.284, -47.123, -46.581,
-46.424, -46.109, -46.082, -47.183, -9.1413, 56.889, 57.599,
53.107, 54.323, 48.069, 49.861, 42.535, 44.399, 26.032, 26.41,
22.744, 23.681, 18.676, 19.984, 27.439, 14.106, 15.454, 83.929,
84.91, 88.283, 58.525, -118.78, -112.69, -111.73, -115.07, -80.356,
-74.343, -80.553, -78.576, -79.131, -77.052, -75.945, -72.811,
-72.81, -73.635, -101.23, -100.58, -97.927, -96.966, -102.2,
-81.305, -16.351, -15, -45.324, -45.51), signal = c(0.356912525947854,
0.441154040587387, 0.127495728211593, 0.209844264592143, 0.471423541381149,
0.920244846231276, 1.20067778812602, 0.901957655651085, 1.26828922845346,
0.913597538349512, 0.961279110570437, 1.70669913750882, 1.71209354564514,
1.54924715577636, 1.69030506815152, 1.57151232049429, 1.52222537801321,
1.7682950526965, 1.00052912202385, 0.258051875687978, 0.473055705981418,
0.281706344592271, 0.425239318349764, 0.391951492462168, 0.265733842589671,
0.207140129446265, 0.237923276586573, 0.284985208364728, 0.587702684164806,
0.337358918978001, 0.722237508242702, 0.532691597382293, 0.613087103723537,
0.395202773422108, 0.719928099089211, 0.256588947956852, 0.433203966266369,
0.360419814621179, 0.490884077829908, 0.391080737042044, 0.494551323229936,
1.33255331306293, 1.1550019409092, 0.943146310863848, 2.13507543110418,
0.605380856482758, 2.05759696362809, 2.16419480467961, 1.95371325977124,
1.99675377322271, 1.67495247573419, 1.64695492742097, 1.33445815225302,
0.772128251322973, 2.07429881383391, 1.60452882592484, 1.53601914533575,
1.38352896104063, 1.83063042527717, 2.17298717559065, 0.841149491013589,
0.443649019354451, 1.28666049614812, 0.982024863842714)), row.names = c(NA,
-64L), class = c("tbl_df", "tbl", "data.frame"))
Base R reducing package dependencies.
v0, eggheadplot
n
to 100
.MBA::mba.surf()
with n
around 1.2
, set extend=FALSE
, see help file. Not relevant here, but maybe in the future.image()
+ points()
+ contour()
+ polygon()
(+ chull()
). dat[c('x', 'y')] = lapply(dat[c('x', 'y')], \(x) (x - min(x))/(max(x) - min(x)))
x = y = seq(0, 1, length.out=n <- 1e3)
r = diff(range(dat$y)) / diff(range(dat$x))
Z = MBA::mba.surf(dat[c('x', 'y', 'signal')], length(x), length(y),
n=r, extend=FALSE)$xyz.est
par(xpd = TRUE)
image(Z, col=hcl.colors(n = n, palette = 'viridis'), asp = 1/r)
polygon(dat[c('x', 'y')][chull(dat[c('x', 'y')]), ])
points(dat$x, dat$y, col='white', pch=20)
contour(x, y, Z$z, add=TRUE, col='white', labcex=1)
polygon(c(.47, .5, .53), c(.99, 1.03, .99), col='white', border='black') # nose
Notice that the contour
lines are somewhat off. This is due to extend=FALSE
. It is time-consuming to initialise
But if you like it, I will spend some time on doing it. Once it is done, we can wrap functions in a long-lasting package.
Notes
(1) signal
range
> range(dat$signal)
[1] 0.1274957 2.1729872
(2) hcl.colors(n = n, palette = 'viridis')
is not the default colour palette used in image()
. A brilliant reference.
(3) We might want to use different spatial interpolation techniques.