1
votes

Tracez plusieurs séries chronologiques l'une sous l'autre à l'aide de R

Je veux obtenir un tracé similaire à celui-ci, en ayant chaque canal d'une série temporelle eeg en dessous d'un autre tout en utilisant l'espace de traçage aussi bien que possible puisqu'il y a 64 canaux. Voici l'image. les colonnes 1, 2 et 4 sont intéressantes pour moi:

 entrez la description de l'image ici

En ce moment, j'utilise gg plot et facet wrap qui gaspille tellement d'espace sur les étiquettes et l'axe. Un simple tracé comme la première colonne suffira à comparer les différents canaux entre eux.

Voici mon code actuel:

library(ggplot2)
library(reshape2)

X1 <- c(1,2,3,4,5,6,7,8,9,19)
X2 <- c(1,4,2,4,1,4,1,4,1,4)
X3 <- c(1,2,3,4,5,6,7,8,9,10)
X4 <- c(1,2,3,4,5,6,7,8,9,1)
X5 <- c(1,4,2,4,1,4,1,4,1,4)
X6 <- c(1,2,3,4,5,6,7,8,9,10)
X7 <- c(1,2,3,4,5,6,7,8,9,11)
X8 <- c(1,4,2,4,1,4,1,4,1,4)
X9 <- c(1,2,3,4,5,6,7,8,9,10)
X10 <- c(1,2,3,4,5,6,7,8,9,10)

icaFrame <- data.frame(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10)

scale <- rep.int(c(1:10),10)


df_melt = melt(icaFrame[,1:10])
ggplot(df_melt, aes(x = scale, y = value)) + 
  geom_line() + 
  facet_wrap(~ variable, scales = 'free_y', ncol = 1)

Alors, comment puis-je créer un graphique aussi simple avec chaque série chronologique tracée sous l'autre en utilisant R?


2 commentaires

Pouvez-vous améliorer le jeu de données d'exemple (il n'y a pas de icaFrame )?


@PoGibas j'ai mis à jour mon code pour résoudre ce problème


3 Réponses :


0
votes

Je pense que j'ai pu obtenir quelque chose de proche de la première colonne en utilisant des facettes. Pour mettre les noms des facettes sur l'axe y, utilisez strip.position = 'left' dans la fonction facet. Cela économisera beaucoup d'espace.

Ensuite, pour vous rapprocher de la première colonne, vous devez jouer avec les éléments theme () .

library(ggplot2)
library(reshape2)

X1 <- c(1,2,3,4,5,6,7,8,9,19)
X2 <- c(1,4,2,4,1,4,1,4,1,4)
X3 <- c(1,2,3,4,5,6,7,8,9,10)
X4 <- c(1,2,3,4,5,6,7,8,9,1)
X5 <- c(1,4,2,4,1,4,1,4,1,4)
X6 <- c(1,2,3,4,5,6,7,8,9,10)
X7 <- c(1,2,3,4,5,6,7,8,9,11)
X8 <- c(1,4,2,4,1,4,1,4,1,4)
X9 <- c(1,2,3,4,5,6,7,8,9,10)
X10 <- c(1,2,3,4,5,6,7,8,9,10)

icaFrame <- data.frame(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10)

scale <- rep.int(c(1:10),10)

df_melt <- melt(icaFrame[,1:10])

ggplot(df_melt, aes(x = scale, y = value)) + 
  geom_line() + 
  # remove extra space in x axis
  scale_x_continuous(expand=c(0,0)) +
  # standard black and white background theme 
  theme_bw() +
  # customized theme elements (you can play around with them to get a better look:
  theme(axis.title = element_blank(),              # remove labels from axis
        panel.spacing = unit(0, units = 'points'), # remove spacing between facet panels
        panel.border = element_blank(),            # remove border in each facet
        panel.grid.major.y=element_blank(),        # remove grid lines from y axis
        panel.grid.minor.y=element_blank(),
        axis.line = element_line(),                # add axis lines to x and y
        axis.text.y=element_blank(),               # remove tick labels from y axis
        axis.ticks.y = element_blank(),            # remove tick lines from y axis
        strip.background = element_blank(),        # remove gray box from facet title
        # change rotation and alignment of text in facet title
        strip.text.y = element_text(angle = 180,   
                                  face = 'bold',
                                  hjust=1,
                                  vjust=0.5),
        # place facet title to the left of y axis
        strip.placement = 'outside'
        ) +
  # call facet_wrap with argument strip.position = 'left'
  facet_wrap(~ variable, scales = 'free_y', ncol = 1, strip.position = 'left')


0 commentaires

1
votes

MODIFIER: Ajout d'une autre approche en bas pour un emballage plus serré si l'espacement irrégulier est correct.

Voici une autre approche pour vous permettre de vous resserrer plus étroitement et d'autoriser les chevauchements:

XXX

 entrez la description de l'image ici


Voici une autre approche, qui trouve l'espacement minimum nécessaire entre chaque série pour éviter tout chevauchement.

library(dplyr)
min_space = 2
vertical_shift <- df_melt %>%
  # Add scale as a variable for use in next step
  group_by(variable) %>% mutate(scale = row_number()) %>% ungroup() %>%
  # Group by scale and track gap vs. prior variable
  group_by(scale) %>% mutate(gap = value - lag(value, default = 0)) %>% ungroup() %>%
  # Group by variable and find minimum gap
  group_by(variable) %>% 
  summarize(gap_needed_below = 1 - min(gap) + min_space) %>%
  ungroup() %>%
  mutate(cuml_gap = cumsum(gap_needed_below))

df_melt %>%
  group_by(variable) %>% mutate(scale = row_number()) %>% ungroup() %>%
  left_join(vertical_shift) %>%
  mutate(shifted_value = value + cuml_gap) %>%
ggplot(aes(x = scale, group = variable,
           y = shifted_value)) + 
  geom_line() +
  scale_y_continuous(breaks = vertical_shift_headers$cuml_gap + 1,
                     labels = vertical_shift_headers$variable,
                     minor_breaks = NULL) +
  labs(y="")

 entrez la description de l'image ici


0 commentaires

0
votes

Je pense que vous étiez assez proche. J'utiliserai data.table juste pour obtenir un nombre dont vous avez besoin pour étiqueter l'axe y, mais vous pouvez utiliser n'importe quel autre outil de base ou de dplyr. J'utiliserai également des données factices qui nous permettent de mieux voir le résultat (vos données croisent les valeurs, contrairement à l'image que vous avez collée).

ggplot(melt_dt, 
       aes(x = time, 
           y = value, 
           group = variable))+
   geom_line()+
   scale_y_continuous(breaks = crossings$V1, 
                      labels = crossings$variable)

Maintenant, tracez le tout: p>

# load libraries

library(data.table)
library(ggplot2)

# create dummy data

set.seed(1)
dt <- data.table(time = 1:10, 
                 EOG = sample(1:5, 10, TRUE), 
                 Pz = sample(6:10, 10, TRUE), 
                 Cz = sample(15:21, 10, TRUE))

# melt that data

melt_dt <- melt(dt, id.vars = 1)

# find mean values for each variable

crossings <- melt_dt[, mean(value), by = variable]

Ce qui produit:

Plot


0 commentaires