I am trying to have this barplot use the data from column SPP
as the x axis labels rather than funct_form
, but unsure how to do this.
data sample:
top32reads <- structure(list(identifier = 1:10, SPP = c("Penstemon", "Rosaceae Group 1",
"Abies", "Hypericum", "Saxifraga OR Micranthes OR Boykinia",
"Eriogonum", "Vaccinium", "Oenothera", "Oxyria digyna", "Chamerion"
), max = c(0.520063568, 0.479127183, 0.503981446, 0.717687654,
0.434079314, 0.362801825, 0.191388889, 0.219305556, 0.263381525,
0.383032052), readsum = c(6.716942576, 5.503499137, 3.881683753,
3.798417906, 3.49976764, 2.309000619, 1.913782497, 1.616440058,
1.59921115, 1.478810665), funct_type = c("Forb", "Forb", "Conifer",
"Forb", "Forb", "Forb", "Shrub", "Forb", "Forb", "Forb"), frequencyformula = c(52L,
50L, 40L, 45L, 47L, 47L, 46L, 43L, 40L, 41L), frequency = c(1,
0.961538462, 0.769230769, 0.865384615, 0.903846154, 0.903846154,
0.884615385, 0.826923077, 0.769230769, 0.788461538)), row.names = c(NA,
10L), class = "data.frame")
barplot code:
library(ggplot2)
library(dplyr)
library(forcats)
library(scales)
library(colorspace)
top32reads%>%
mutate(funct_type = fct_reorder(.f = funct_type, .x = -readsum, min),
main_color = brewer_pal("qual")(n_distinct(funct_type))[funct_type]
) %>%
group_by(funct_type) %>%
mutate(lvl = as.integer(fct_reorder(SPP, readsum)),
relvl = rescale(lvl, c(0, .6), from = c(0, max(length(lvl), 5))),
sub_color = darken(main_color, relvl)) %>%
ggplot(aes(x = funct_type, y = readsum))
geom_col(aes(fill = sub_color),
position = position_dodge2(width = .9, preserve = "single"))
scale_fill_identity()
ylab("Sum of read percentages across samples")
xlab("OTUs Consumed by Functional Type")
ggtitle("Diet by Relative Read Abundance")
theme_bw()
theme(axis.title = element_text(size = 16, face = "bold"),
strip.text.y = element_text(size = 18, face="bold"),
plot.title = element_text(size = 28, face = "bold", hjust = 0.5),
axis.text = element_text(size = 18, face = "bold"),
legend.position = "bottom")
when i try to switch out SPP
for funct_type
in aes()
, (also adding axis.text.x=element_text(angle=90)
) I end up with this
which obviously does not have the same ordering and spacing as previously
CodePudding user response:
Revised Answer
If you want to keep everything the same but use SPP
for the x-axis you just need to update the ggplot call. e.g.
ggplot(aes(x = SPP, y = readsum))
And you can use coord_flip
to rotate the axes.
Which gets you this.
Old Answer
Is this what you're thinking? I removed some of the extra styling you had for demonstrative purposes. Also it's helpful in the future to include all the packages that you're using for the reprex.
You can use facet_wrap
to display different groups which in this case are shown at the top. Then use SPP
as your x variable.
library(ggplot2)
library(dplyr)
library(forcats)
library(scales)
library(colorspace)
top32reads = top32reads %>%
mutate(funct_type = fct_reorder(.f = funct_type, .x = -readsum, min),
main_color = brewer_pal("qual")(n_distinct(funct_type))[funct_type]
) %>%
group_by(funct_type) %>%
mutate(lvl = as.integer(fct_reorder(SPP, readsum)),
relvl = rescale(lvl, c(0, .6), from = c(0, max(length(lvl), 5))),
sub_color = darken(main_color, relvl)) %>%
ungroup()
top32reads %>%
ggplot(aes(x = SPP, y = readsum))
geom_col(aes(fill = sub_color),
position = position_dodge2(width = .9, preserve = "single"))
scale_fill_identity()
ylab("Sum of read percentages across samples")
xlab("OTUs Consumed by Functional Type")
ggtitle("Diet by Relative Read Abundance")
theme_bw()
facet_wrap(~ funct_type)
coord_flip()
CodePudding user response:
This is actually not trivial. I think user Jamie's idea of using facets is very good 1. But it requires a bit more work on the underlying ordered factors. You have already created an ordered factor by function type (well done), but then you did not make use of it as your x variable. Do it!
You will see, I have retained the function type labels (as strips in the facets. You can also completely remove them, (using theme), and if you want more space between your funcion types, increase the strip spacing with panel.spacing
. I've removed a lot of unnecessary code for the problem. Some comments in the code.
## when doing complex data wrangling,
## I prefer to first create a proper object
## instead of piping into ggplot directly
df_fct <-
top32reads %>%
mutate(funct_type = fct_reorder(.f = funct_type, .x = -readsum, min),
main_color = brewer_pal("qual")(n_distinct(funct_type))[funct_type]
) %>%
group_by(funct_type) %>%
## don't convert your factor to integer yet
mutate(lvl = fct_reorder(SPP, desc(readsum)),
## but only now
relvl = rescale(as.integer(lvl), c(0, .6), from = c(0, max(length(lvl), 5))),
sub_color = darken(main_color, relvl),
## this is just one suggestion to reformat the labels.
## There are other ways to deal with the long labels
## e.g., user jamie has flipped the coordinates which I find a good idea
spp_lab = factor(lvl, levels = levels(lvl), labels = gsub(" ", "\n", levels(lvl))))
ggplot(df_fct , aes(x = spp_lab , y = readsum))
geom_col(aes(fill = sub_color),
position = position_dodge2(width = .9, preserve = "single"))
scale_fill_identity()
## facet by funct_type, switch strip to bottom
facet_grid(~funct_type, switch = "x", scales = "free_x", space = "free_x")
## place strip outside
theme(strip.placement = "outside")