Daniel James
Daniel James

Reputation: 1433

Ggplot2: Facet Grid With Multiple-Line Plot

I want to make a multiple-line plot in `facet_grid like this:

What I want

I have the following R code that draws column bar plots in the facet grid

library(ggplot2)
library(reshape2)
set.seed(199)
MB_RMSE_sd1 <-  runif(12, min = 0, max = 2)
TMB_RMSE_sd1 <- runif(12, min = 0, max = 2)
MB_RMSE_sd3 <-  runif(12, min = 2, max = 5)
TMB_RMSE_sd3 <- runif(12, min = 2, max = 5)
MB_RMSE_sd5 <- runif(12, min = 5, max = 10)
TMB_RMSE_sd5 <- runif(12, min = 5, max = 10)
MB_RMSE_sd10 <-  runif(12, min = 7, max = 16)
TMB_RMSE_sd10 <- runif(12, min = 7, max = 16)
ID <- rep(rep(c("N10_AR0.8", "N10_AR0.9", "N10_AR0.95", "N15_AR0.8", "N15_AR0.9", "N15_AR0.95", "N20_AR0.8", "N20_AR0.9", "N20_AR0.95", "N25_AR0.8", "N25_AR0.9", "N25_AR0.95"), 2), 1)
df1 <- data.frame(ID, MB_RMSE_sd1, MB_RMSE_sd3, MB_RMSE_sd5, MB_RMSE_sd10, TMB_RMSE_sd1, TMB_RMSE_sd3, TMB_RMSE_sd5, TMB_RMSE_sd10)
reshapp1 <- reshape2::melt(df1, id = "ID")

NEWDAT <- data.frame(value = reshapp1$value, year = reshapp1$ID, n = rep(rep(c("10", "15", "20", "25"), each = 3), 16), Colour = rep(rep(c("RMSE_MB", "RMSE_TMB"), each = 12), 4), sd = rep(rep(c(1, 3, 5, 10), each = 48), 1),  phi = rep(rep(c("0.8", "0.9", "0.95"), 16), 4))

NEWDAT$sd <- with(NEWDAT, factor(sd, levels = sd, labels = paste("sd =", sd)))
NEWDAT$year <- factor(NEWDAT$year, levels = NEWDAT$year[1:12])
NEWDAT$n <- with(NEWDAT, factor(n, levels = n, labels = paste("n = ", n)))

library(ggpattern)
ggplot() +
  geom_col_pattern(
    data = NEWDAT[NEWDAT$Colour %in% c("RMSE_MB", "RMSE_TMB"), ],
    aes(x = phi, y = value, pattern = rev(Colour), pattern_angle = rev(Colour)),
    fill            = 'white',
    colour          = 'black', 
    pattern_density = 0.1, 
    pattern_fill    = 'black',
    pattern_colour  = 'black'
  ) +
  facet_grid(sd ~ n, scales = "free") +
  scale_fill_manual(
    breaks = c("RMSE_MB", "RMSE_TMB"),
    values = c("red", "blue", "orange", "green")
  ) +
  scale_y_continuous(expand = c(0, 0), label = ~ abs(.)) +
  guides(fill = guide_legend(reverse = TRUE)) +
  labs(fill = "") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = -90, vjust = 0.5))
#ggsave("AR1.pdf", height = 8, width = 7, device = "pdf", dpi = 700)

EDIT1 What I have after using the answer below:

library(ggplot2)
library(reshape2)
set.seed(199)
MB_RMSE_sd1 <-  runif(12, min = 0, max = 2)
TMB_RMSE_sd1 <- runif(12, min = 0, max = 2)
MB_RMSE_sd3 <-  runif(12, min = 2, max = 5)
TMB_RMSE_sd3 <- runif(12, min = 2, max = 5)
MB_RMSE_sd5 <- runif(12, min = 5, max = 10)
TMB_RMSE_sd5 <- runif(12, min = 5, max = 10)
MB_RMSE_sd10 <-  runif(12, min = 7, max = 16)
TMB_RMSE_sd10 <- runif(12, min = 7, max = 16)
ID <- rep(rep(c("N10_AR0.8", "N10_AR0.9", "N10_AR0.95", "N15_AR0.8", "N15_AR0.9", "N15_AR0.95", "N20_AR0.8", "N20_AR0.9", "N20_AR0.95", "N25_AR0.8", "N25_AR0.9", "N25_AR0.95"), 1), 1)
df1 <- data.frame(ID, MB_RMSE_sd1, MB_RMSE_sd3, MB_RMSE_sd5, MB_RMSE_sd10, TMB_RMSE_sd1, TMB_RMSE_sd3, TMB_RMSE_sd5, TMB_RMSE_sd10)
reshapp1 <- reshape2::melt(df1, id = "ID")

NEWDAT <- data.frame(value = reshapp1$value, year = reshapp1$ID, n = 
rep(rep(c("10", "15", "20", "25"), each = 3), 16), Colour = 
rep(rep(c("RMSE_MB", "RMSE_TMB"), each = 3), 16), sd = rep(rep(c(1, 3, 5, 10), each = 24), 1),  phi = rep(rep(c("0.8", "0.9", "0.95"), 16), 4))

NEWDAT$sd <- with(NEWDAT, factor(sd, levels = sd, labels = paste("sd =", sd)))
NEWDAT$year <- factor(NEWDAT$year, levels = NEWDAT$year[1:12])
NEWDAT$n <- with(NEWDAT, factor(n, levels = n, labels = paste("n = ", n)))

ggplot(NEWDAT, aes(phi, value)) +
  geom_line(aes(linetype = Colour)) + geom_point() +
  scale_y_continuous(expand = c(0, 0), label = ~ abs(.)) +
  guides(fill = guide_legend(reverse = TRUE)) +
  #labs(fill = "") +
  facet_grid(sd ~ n, scales = "free") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = -90, vjust = 0.5))

which produces this line plot

WHAT I WANT

Each 3 points up should for a line while the 3 point down should form another line

Upvotes: 0

Views: 839

Answers (1)

Rui Barradas
Rui Barradas

Reputation: 76673

Here is a solution.
After reshaping the data, remove the duplicates with unique. Then the plot is easy, map the colour to linetype and the two lines shall be automatically separated.

library(ggplot2)
library(reshape2)

reshapp1 <- reshape2::melt(df1, id = "ID")
reshapp1 <- unique(reshapp1)

NEWDAT <- data.frame(value = reshapp1$value, year = reshapp1$ID,
                     n = rep(rep(c("10", "15", "20", "25"), each = 3), 16), 
                     Colour = rep(rep(c("RMSE_MB", "RMSE_TMB"), each = 12), 4), 
                     sd = rep(rep(c(1, 3, 5, 10), each = 48), 1),  
                     phi = rep(rep(c(0.8, 0.9, 0.95), 16), 4))

NEWDAT$sd <- with(NEWDAT, factor(sd, levels = sd, labels = paste("sd =", sd)))
NEWDAT$year <- factor(NEWDAT$year, levels = NEWDAT$year[1:12])
NEWDAT$n <- with(NEWDAT, factor(n, levels = n, labels = paste("n = ", n)))

ggplot(NEWDAT, aes(phi, value)) +
  geom_line(aes(linetype = Colour)) +
  scale_y_continuous(expand = c(0, 0), label = ~ abs(.)) +
  guides(fill = guide_legend(reverse = TRUE)) +
  #labs(fill = "") +
  facet_grid(sd ~ n, scales = "free") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = -90, vjust = 0.5))

#ggsave("AR1.pdf", height = 8, width = 7, device = "pdf", dpi = 700)

Created on 2022-09-03 by the reprex package (v2.0.1)

Upvotes: 1

Related Questions