Daniel James
Daniel James

Reputation: 1433

How to Use Texture Fill in Stacked-Bar Chart for Facet Grid

I have this stacked-bar chart with a facet grid. Instead of the four colours used, I want to use the texture of different kinds. I am changing from coloured to texture to make each bar different if printed on black and white paper.

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)
MB_MAE_sd1 <-  runif(12, min = 0, max = 2)
TMB_MAE_sd1 <- runif(12, min = 0, max = 2)
MB_MAE_sd3 <-  runif(12, min = 2, max = 5)
TMB_MAE_sd3 <- runif(12, min = 2, max = 5)
MB_MAE_sd5 <-  runif(12, min = 5, max = 10)
TMB_MAE_sd5 <- runif(12, min = 5, max = 10)
MB_MAE_sd10 <-  runif(12, min = 7, max = 16)
TMB_MAE_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, TMB_MAE_sd1, MB_RMSE_sd3, TMB_MAE_sd3, MB_RMSE_sd5, TMB_MAE_sd5, MB_RMSE_sd10, TMB_MAE_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", "MAE_MB", "MAE_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() +
  geom_bar(data=NEWDAT[NEWDAT$Colour %in% c("RMSE_MB", "RMSE_TMB"),], 
           aes(x = phi, y=value, fill=rev(Colour)), stat="identity") +
  geom_bar(data=NEWDAT[NEWDAT$Colour %in% c("MAE_MB", "MAE_TMB"),], 
           aes(x=phi, y=-value, fill=Colour), stat="identity") +
  geom_hline(yintercept=0, colour="grey40") +
  facet_grid(sd ~ n, scales = "free") +
  scale_fill_manual(breaks=c("MAE_MB", "MAE_TMB", "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)) 

Here is its output

I have visited Filling bars in barplot with textiles in ggplot2 [duplicate] and How to add texture to fill colours in ggplot2 but because of the complexity of my case I am unable to apply the answers therein.

Upvotes: 1

Views: 340

Answers (1)

Shafee
Shafee

Reputation: 19987

You may want to try the package {ggpattern} which would be a nice way to print a plot on Black and White Paper.


library(ggplot2)
library(reshape2)
library(ggpattern)

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)
MB_MAE_sd1 <- runif(12, min = 0, max = 2)
TMB_MAE_sd1 <- runif(12, min = 0, max = 2)
MB_MAE_sd3 <- runif(12, min = 2, max = 5)
TMB_MAE_sd3 <- runif(12, min = 2, max = 5)
MB_MAE_sd5 <- runif(12, min = 5, max = 10)
TMB_MAE_sd5 <- runif(12, min = 5, max = 10)
MB_MAE_sd10 <- runif(12, min = 7, max = 16)
TMB_MAE_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, TMB_MAE_sd1, MB_RMSE_sd3, TMB_MAE_sd3, MB_RMSE_sd5, TMB_MAE_sd5, MB_RMSE_sd10, TMB_MAE_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", "MAE_MB", "MAE_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() +
    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"
    ) +
    geom_col_pattern(
        data = NEWDAT[NEWDAT$Colour %in% c("MAE_MB", "MAE_TMB"), ],
        aes(x = phi, y = -value, pattern = Colour, pattern_angle = Colour),
        fill            = "white",
        colour          = "black",
        pattern_density = 0.1,
        pattern_fill    = "black",
        pattern_colour  = "black"
    ) +
    geom_hline(yintercept = 0, colour = "grey40") +
    facet_grid(sd ~ n, scales = "free") +
    scale_fill_manual(
        breaks = c("MAE_MB", "MAE_TMB", "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))


plot_with_pattern

Upvotes: 2

Related Questions