1

I created stacked plot of species abundance over time in three different sites. The code I created plots different species in different colours depending on their order of abundance in the different sites. How can I adapt the code to assign the same colour to the same species in each site. Other questions involve assigning specific order in the graph this is different in that I just want to maintain the same order across different loops.

library(ggplot2)
library(cowplot)
library(plyr)
library(dplyr)
library(reshape2)
dat_all =  data.frame(year = rep(1:6, 15), site= rep(c("X","Y","Z"), each=6), 
species = rep(c("A","B","C","D","E"),each=3))

dat_all$abund= c(31, 36, 23, 23,4, 29, 9, 15,32, 28, 20, 1, 9, 17, 14, 2, 3, 
        27, 23, 28, 29, 33, 16, 22, 26, 27, 14, 9, 3, 14, 15, 13, 30, 30, 4, 
        16, 18, 14, 19, 16, 19, 10, 30, 24, 34, 32, 20, 12, 
        16, 21, 23, 17, 17, 17, 28, 16, 16, 13, 30, 23,24, 16, 6, 7, 21, 22, 
        23, 3, 12, 19, 19, 39, 6, 21, 21, 14, 12, 13, 13, 22, 10, 12, 24, 
        2,21, 25, 2, 12,30, 20)


cols2a= c("#c2c387","#74aff3","#f5dc9e", "#53c6ef","#f4b189")

for (s in unique(dat_all$site)){

dat = dat_all[dat_all$site == s, ]

dat$species = as.character(dat$species)

dat$species =
  factor(
    dat$species,
    levels =
      tapply(dat$abund, dat$species, sum) %>%
      sort %>%
      names
  )
# Aggregate to site / species
dat =
  ddply(
    dat,
    c("year", "species"),
    summarize,
    abundance = sum(abund)
  )

dat$year = factor(dat$year)

dat = dat[order(dat$year, -as.numeric(dat$species)), ]

#Add labels
dat=
  ddply(
    dat,
    c("year"),
    transform,
    pos = cumsum(abundance)
  )
dat$label = dat$species
dat$label[dat$abundance < 2] = NA


# ## Plot
g= ggplot(dat, aes(x =year, y = abundance)) +
  geom_hline(yintercept = 0, size = 0.25, colour = "darkgrey") +
  geom_bar(
    aes(fill = species),
    stat = "identity", colour = "black", size = 0.25
  ) +
  geom_text(
    aes(label = label, y = pos),
  vjust = 1.25, size = 2.5
  ) +
  scale_y_continuous(
    labels = round
  ) +
  ylab("Total abundance") +
  scale_fill_manual(
    values = cols2a,
    guide = FALSE
  ) +
  ggtitle( s ) +
  theme_bw() +
  theme(
    axis.title.x = element_blank(),
    axis.ticks.x = element_blank(),
    panel.border = element_blank(),
    panel.grid = element_blank()
  )

assign(paste0("plot",s), g)
}

plot_grid(plotX,plotY,plotZ)

As you can see, the colours change. For example Species B is more abundant and is pink in site X but Species D is the abundant pink species in Site Y & Z. Where am I going wrong? I still need the most dominant species to be at the base of the bar, but I need to colours to remain assigned to the same species throughout all loops.

Thanks enter image description here

Birdonawire
  • 199
  • 3
  • 10
  • Try `scale_fill_manual()` – Roman Jul 26 '17 at 12:30
  • Possible duplicate of [Order and color of bars in ggplot2 barplot](https://stackoverflow.com/questions/17331892/order-and-color-of-bars-in-ggplot2-barplot) or [here](https://stackoverflow.com/questions/39684259/how-to-change-the-color-spectrum-pattern-of-fill-in-ggplot2-bar-chart) – Roman Jul 26 '17 at 12:32

1 Answers1

1

You almost there, for scale_fill_manual(values = cols2a) to work as you want you need to assing group names to cols2a :

cols2a = c("#c2c387","#74aff3","#f5dc9e", "#53c6ef","#f4b189")
names(cols2a) = levels(dat_all$species)

Otherwise scale_fill_manual() colors groups in order of plotting.

Andrey Kolyadin
  • 1,301
  • 10
  • 14