nomeal
nomeal

Reputation: 88

Display of various plots with shared x-axis in R

I'm currently trying to have a plot which displays various trajectories of time series with a shared x-axis (time).

time <- seq(from=0, to=1, length.out=101)

X1 <- runif(101)
X2 <- runif(101)
X3 <- runif(101)

par(mfcol=c(3,1))
plot(time,X1,type="l")
plot(time,X2,type="l")
plot(time,X3,type="l")

This creates the output output

I want the three plots in this example to be stacked onto each other with only one x-axis "time". In addition I want the labels of the y-axis "X1", "X2" and "X3" to stay left of the corresponding plot.

I really would appreciate any help and suggestions!

PS: I also already know about the "trick" to remove the x-axis from the two plots at the top, but this makes it hard to vary the number of plots; say I have "X1", "X2", "X3" and "X4" I would have to recalculate the place of the labels of the y-axis and this seems quite hard to me.

Edit: This is an exampe of how it should look:

enter image description here

Upvotes: 2

Views: 2196

Answers (2)

Allan Cameron
Allan Cameron

Reputation: 173803

Using ggplot you can do this quite easily by first putting your data into a data frame formatted like this:

df <- data.frame(value = c(X1, X2, X3), 
                 label = rep(c("X1", "X2", "X3"), each = 101),
                 time  = rep(time, 3))

And the plotting code looks like this:

library(ggplot2)

ggplot(df, aes(x = time, y = value)) +
  geom_line() +
  labs(y = "") +
  scale_y_continuous(expand = c(0.1, 0.1)) +
  facet_grid(label ~ ., switch = "y", scales = "free_y") +
  theme_classic() +
  theme(strip.background = element_blank(),
        strip.placement  = "outside",
        panel.spacing    = unit(0, "lines"),
        panel.border = element_rect(color = "black", fill = NA))

enter image description here

Note that as requested, the plotting code remains the same if you add an extra variable - you just update your data frame to include it. So, for example, I can add the variable X4 like this:

X4 <- rnorm(101, mean = 0, sd = 10)

df <- rbind(df, data.frame(value = X4, label = rep("X4", 101), time = time))

And now running the exact same plotting code produces:

enter image description here

Upvotes: 2

TarJae
TarJae

Reputation: 78927

You could use lattice package:

df <- data.frame(value = c(X1, X2, X3), 
                 label = rep(c("X1", "X2", "X3"), each = 101),
                 time  = rep(time, 3))

library(lattice)
xyplot(value~time|label,data=df,type="l",
       scales=list(y=list(relation="free")),
       layout=c(1,4))

enter image description here

Upvotes: 1

Related Questions