I am trying to draw soil profiles with ggplot. However, geom_col groups first all sand layers together, then all peat layers and finally all clay layers. I would like the order to depend on the order in my dataframe or, alternatively, on the order of depth_min. So sand-caly-peat-sand for the first profile and peat-caly-peat for the last. I've tried using order as an aesthetic but that seems deprecated and searched the net extensively, but came up only with many posts about reversing the order of the stacks or changing the order of de legend. Any solutions? Or maybe I should not be (ab)using geom_col for this, but some other function (preferably ggplot)?
Reproducible example:
d <- read.csv(text='Location,depth_min,depth_max, depth,soil
1,0,20,20,sand
1,20,30,10,clay
1,30,60,30,peat
1,60,100,40,sand
2,0,30,30,clay
2,30,90,60,peat
3,0,40,40,peat
3,40,70,30,clay
3,70,120,50,peat',header=T)
d %>%
ggplot(aes(x=Location,y=depth, fill = soil))
geom_col(position="stack")
scale_y_reverse()
theme_bw()
CodePudding user response:
Try using geom_segment()
instead of geom_col()
. Here's an example that should get you closer to what you're looking for:
d %>%
ggplot()
geom_segment(aes(x = Location,
xend = Location,
y = depth_min,
yend = depth_max,
colour = soil),
size = 2)
scale_y_reverse()
CodePudding user response:
One option to achieve your desired result would be to add an index or order column to your data which could be mapped on the group
aesthetic to stack your data in your desired order:
library(dplyr)
library(ggplot2)
d %>%
group_by(Location) %>%
mutate(order = row_number()) %>%
ggplot(aes(x=Location,y=depth, fill = soil, group = order))
geom_col(position="stack")
scale_y_reverse()
theme_bw()
CodePudding user response:
One way of ordering / controlling the stacking is to coerce your fill-variable into a vector and define the levels in your desired order.
library(dplyr)
library(ggplot2)
# check what the following delivers
d %>% mutate(soil2 = factor(soil, levels = c("peat","clay","sand"))) %>% pull(soil2)
This gives you a factor with the defined ordering
[1] sand clay peat sand clay peat peat clay peat
Levels: peat clay sand
Assuming this is what we want we can inject this into ggplot. ggplot will order in accordance with the factor levels.
d %>%
mutate(soil2 = factor(soil, levels = c("peat","clay","sand"))) %>%
ggplot(aes(x=Location,y=depth, fill = soil2))
geom_col(position="stack")
theme_bw()
Try to change the order of the factor levels to see how this influences the stack order.
If you want to split your fills, you need to introduce a separate variable for and supply it to the group aesthetic as laid out above.