How to customize the X axis of two factors and colour bars based on two factors

ぐ巨炮叔叔 提交于 2019-12-13 02:49:23

问题


I've produced a plot with data showing dislodgement at two different sites based on two main factors (Season and Exposure) which are both labelled in the X axis. I'd like to edit the X axis for seasons so it is not in alphabetical order but labelled from Spring - Winter (instead of Autumn to Winter). On the second row showing Exposure; the are two sets of Exposed labels; I can see that this is because it is being centered in one every three labels of the Season labels but can't seem to correct it.

If possible too, I would like to change the colours of my bars based on season with a lighter shade of the same colour for the second site. Ideally, green for Spring, Yellow for Summer, Brown for Autumn and Grey for Winter, and place ticks in between the seasons and a longer tick in between exposure

desired colour coded bars output from excel

I've tried using this code; Season <- as.character(data$Season) #Then turn it back into a factor with the levels in the correct order Season <- factor(data$Season), levels=unique(data$Season) To correct the alphabetical order for Seasons but it does nothing, even after I have corrected the labels in my csv. file to the correct order.

This is my full code that I'm using at the moment that was kindly provided for me by a stack overflow user on a previous question.

output from R using current code

library(ggplot2)
library(gtable)
library(grid)
Season <- (data$Season)
Site <- (data$Site)
Exposure <- (data$Exposure)
Average <- data$Average
SEM <- data$SEM
gg <- ggplot(aes(x=as.factor(Site), y=Average, fill=as.factor(Site)), Season, data = data)
gg <- gg + geom_bar(stat = 'identity')
gg <- gg + scale_fill_discrete(guide_legend(title = 'Site'))
gg <- gg + scale_fill_manual(values=c('black', 'grey85'), guide_legend(title = 'Site')) 
gg <- gg + theme_classic() 
gg <- gg + geom_errorbar(aes(ymin=Average-SEM, ymax=Average+SEM), width=.3)
gg <- gg + facet_wrap(~Exposure*Season, strip.position=c('bottom'), nrow=1, drop=F)
gg <- gg + scale_y_continuous(expand = expand_scale(mult = c(0, .05)))
gg <- gg + theme(axis.text.x = element_blank(),
                 axis.ticks.x = element_blank(),
                 axis.title.x = element_blank(),
                 axis.line = element_line(color='black'),
                 strip.placement = 'outside', 
                 panel.spacing.x=unit(0, "lines"), 
                 panel.grid.major.x = element_blank(), 
                 panel.grid = element_blank(), 
                 panel.background = element_rect(fill='white'), 
                 strip.background = element_rect(fill='white', color='white') 
)
print(gg)
season.levels <- levels(data$Season)
exposure.levels <- levels(data$Exposure)
g <- ggplotGrob(gg)
grob.numbers <- grep("strip-b", g$layout$name)
b.strips <- gtable_filter(g, "strip-b", trim = FALSE)

season.left.panels <- seq(1, by=length(levels(data$Exposure)), length.out = length(season.levels))
season.right.panels <- seq(length(exposure.levels), by=length(exposure.levels), length.out = length(season.levels))
left <- b.strips$layout$l[season.left.panels]
right <- b.strips$layout$r[season.right.panels]
top <- b.strips$layout$t[3]
bottom <- b.strips$layout$b[3]
mat   <- matrix(vector("list", length = 10), nrow = 2)
mat[] <- list(zeroGrob())
for (i in 1:length(season.levels)) {
  res <- gtable_matrix("season.strip", mat, unit(c(1, 0, 1, 0, 1), "null"), unit(c(1, 1), "null"))
  season.left <- season.left.panels[i]
  res <- gtable_add_grob(res, g$grobs[[grob.numbers[season.left]]]$grobs[[3]], 2, 1, 2, 5)
  for (j in 0:2) {
    exposure.x <- season.left+j
    res$grobs[[c(1, 5, 9)[j+1]]] <- g$grobs[[grob.numbers[exposure.x]]]$grobs[[3]]
  }
  new.grob.name <- paste0(levels(data$Season)[i], '-strip')
  g <- gtable_add_grob(g, res, t = top,  l = left[i],  b = top,  r = right[i], name = c(new.grob.name))
  new.grob.no <- grep(new.grob.name, g$layout$name)[3]
  g$grobs[[new.grob.no]]$grobs[[nrow(g$grobs[[new.grob.no]]$layout)]]$children[[3]]$children[[3]]$gp <- gpar(fontface='bold')
}
grid.newpage()
grid.draw(g)

回答1:


You can use the alpha aesthetic to get different shades of the color per Site and then manually assign your desired colors:

data$Season <- factor(data$Season, levels=c('Spring', 'Summer', 'Autumn', 'Winter'))
data$Site <- as.factor(data$Site)
gg <- ggplot(aes(x=Site, y=Average, fill=Season), data=data)
gg <- gg + geom_bar(stat = 'identity', aes(alpha=Site))
gg <- gg + scale_alpha_manual(values=c(1, .7), guide_legend(title = 'Site'))
gg <- gg + scale_fill_manual(values=c('green', 'yellow', 'brown', 'grey'), guide_legend(title = 'Season')) # to get bars desired colors instead of ggplot's default colors
gg <- gg + theme_classic() # get white background and black axis.line for x- and y-axis
gg <- gg + geom_errorbar(aes(ymin=Average-SEM, ymax=Average+SEM), width=.3)
gg <- gg + facet_wrap(~Season*Exposure, strip.position=c('bottom'), nrow=1, drop=F)
gg <- gg + scale_y_continuous(expand = expand_scale(mult = c(0, .05))) # remove space below zero
gg <- gg + theme(axis.text.x = element_blank(),
                 axis.ticks.x = element_blank(),
                 axis.title.x = element_blank(),
                 axis.line = element_line(color='black'),
                 strip.placement = 'outside', # place x-axis above (factor-label-) strips
                 panel.spacing.x=unit(0, "lines"), # remove space between facets (for continuous x-axis)
                 panel.grid.major.x = element_blank(), # remove vertical grid lines
                 # panel.grid = element_blank(), # remove all grid lines
                 # panel.background = element_rect(fill='white'), # choose background color for plot area
                 strip.background = element_rect(fill='white', color='white')  # choose background for factor labels, color just matters for theme_classic()
)
print(gg)



来源:https://stackoverflow.com/questions/55836092/how-to-customize-the-x-axis-of-two-factors-and-colour-bars-based-on-two-factors

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!