0

using this reproducible example tibble

 # install and attach packages
if (!require("pacman")) install.packages("pacman")
pacman::p_load(tidyverse, dplyr, ggplot2)  

# Create example dataset (tib1)
tib1 = tibble(location = c("loc1", rep(c("loc1", "loc2"), 8), rep("loc2",2)),
              drill = sort(c(1, rep(1:4, 4),4, 4)),
              thickness = c(20, 34, 99, 67, 29, 22, 53, 93, 64, 98, 76, 42, 49, 23, 11, 74, 
                            19, 50, 40),
              soiltype = c("gravel", rep( c("sand", "loam", "clay"),5 ), "sand", "gravel", "clay")) %>% 
  arrange(location, drill)

tib1 <- tib1 %>% group_by(location, drill) %>% 
  mutate(order = row_number(),
         bottom_of_layer = cumsum(thickness),
         top_of_layer = bottom_of_layer-thickness) %>% 
  ungroup %>% 
  select(location, drill, bottom_of_layer, top_of_layer, thickness, soiltype, order)

tib1

I would like to plot a cross section of a soil. I attempt to do this with geom_bar or geom_col from ggplot2. In the example data there is an order given (1:3). I would like the bars to be stacked in the order as specified in the "order column". So this would implicate that the bar where:

  • location == "loc2" and drill == 4 should be colored in the order (from top to bottom):

orange (loam) - yellow (sand) - grey(gravel) - seagreen (clay)

AND

  • location == "loc1" and drill == 1 should be colored in the order (from top to bottom):

grey(gravel) - yellow (sand) - seagreen (clay)

While the other stacked bars remain in the same order & color.

In other words: I need the colors in the stacked bar to vary along with the sequence as indicated in the column "order".

colpalette = c("darkseagreen3", "darkgrey", "#FF9966", "palegoldenrod")

ggplot(tib1,
       aes(x = drill))+
  geom_bar(aes(fill = soiltype, y = -thickness),
           stat = "identity")+
  scale_fill_manual(values = colpalette)+
  facet_wrap(vars(location), scale = "free_x")+
  xlab("drill")+
  ylab("depth (cm)")+
  ggtitle("how to plot the bars in the 'preferred order'? ",
          subtitle = "the order of loc2 and drill == 4 should be: loam-sand-gravel-clay")+
  theme_minimal()

cross section of soil profile with geom_bar

Comparable, but slightly different issues are:

Order of stacked bars ggplot2 - Soil profile and Change the order of Stacked Bar Chart in ggplot2

I wonder whether the thing I am asking for is possible at all in ggplot as:

Bar charts are automatically stacked when multiple bars are placed at the same location. The order of the fill is designed to match the legend.

So I might have to search for an alternative option... unless anyone has a hack? Any help, answers, alternative plotting options, links are appreciated :) I prefer ggplot2 if possible.

T. BruceLee
  • 501
  • 4
  • 16

2 Answers2

1

You should order the levels:

ie:

tib1 <- tib1 %>% 
    mutate(soiltype = ordered(soiltype, c("clay", "gravel", "sand", "loam")))

colpalette = c("darkseagreen3", "darkgrey","palegoldenrod","#FF9966")

ggplot(tib1,
       aes(x = drill))+
    geom_bar(aes(fill = soiltype, y = -thickness),
             stat = "identity")+
    scale_fill_manual(values = colpalette)+
    facet_wrap(vars(location), scale = "free_x")+
    xlab("drill")+
    ylab("depth (cm)")+
    ggtitle("how to plot the bars in the 'preferred order'? ",
            subtitle = "the order of loc2 and drill == 4 should be: loam-sand-gravel-clay")+
    theme_minimal()

enter image description here

Onyambu
  • 67,392
  • 3
  • 24
  • 53
  • Thanks for the answer @Onyambu, but I need the colors to be ordered by the order specified in the column. This means that for some soil profiles the sequence of colors is different than for others: So soil profile A might be from top to bottom: "yellow - green - yellow - orange" While soil profile B might have totally different order, lets say: "green - orange - yellow" being in the same plot. Is this possible in ggplot? if not so, is there another package that could provide a solution? – T. BruceLee Nov 12 '20 at 17:20
  • @T.BruceLee different ordering in the same plot? That is quite a task. Never seen that before. But probably you could consider ordering the ordering the levels differently within each subgroup(Dont really know whether this could work-Probably not). – Onyambu Nov 12 '20 at 17:24
  • Yes, its an odd question. As ggplot2 is not designed to visualize in that way. But worth a try nonetheless. – T. BruceLee Nov 12 '20 at 17:37
0

geom_col and geom_bar are not the appropriate ggplot2 functions when you want the fill or color to vary along with the sequence as the fill and or color are grouped in one bar. geom_rect is able to seperate two layer of fill or color within a bar/rectangle.

p1 <- ggplot(tib1)+
  geom_rect(data = tib1,
            aes(x = NULL, NULL, 
                xmin = drill-0.45, xmax = drill+0.45,
                fill = soiltype,
                ymin = -bottom_of_layer, ymax = -top_of_layer))+
  scale_fill_manual(values = colpalette)+
  facet_wrap(vars(location))+
  xlab("drill")+
  ylab("depth (cm)")+
  ggtitle("how to plot the bars in the 'preferred order'? ",
          subtitle = "the order of loc2 and drill == 4 should be: loam-sand-gravel-clay")+
  theme_minimal()

  # Optional:
  # Adding in text the column called "order"
p1 + geom_text(aes(x = drill,
                y = (bottom_of_layer + top_of_layer)/-2,
                label = order))

This is also possible with discrete x-axis values: how do I use geom_rect with discrete axis values

Soil profile plot with geom_rect

T. BruceLee
  • 501
  • 4
  • 16