R 如何在X轴上创建具有多个标签的绘图,前面的代码建议不适用';好像不行

R 如何在X轴上创建具有多个标签的绘图,前面的代码建议不适用';好像不行,r,ggplot2,r-grid,gtable,R,Ggplot2,R Grid,Gtable,我有一些数据测量一个物种的迁移率,有三个不同的变量(暴露、季节和地点)。我想创建一个在X轴上列出季节和曝光的绘图,并在图例中创建站点。我已经在Excel中很容易地完成了这项工作,并希望在R中复制相同的类型。目前,我正在使用一段代码,它似乎适用于其他用户,但我的问题类似,但这似乎不适用于我的问题 脚本: dput(Data2) structure(list(Season = structure(c(2L, 2L, 2L, 3L, 3L, 3L, 1L, 1L, 1L, 4L, 4L, 4L, 2

我有一些数据测量一个物种的迁移率,有三个不同的变量(暴露、季节和地点)。我想创建一个在X轴上列出季节和曝光的绘图,并在图例中创建站点。我已经在Excel中很容易地完成了这项工作,并希望在R中复制相同的类型。目前,我正在使用一段代码,它似乎适用于其他用户,但我的问题类似,但这似乎不适用于我的问题

脚本:

dput(Data2)
structure(list(Season = structure(c(2L, 2L, 2L, 3L, 3L, 3L, 1L, 
1L, 1L, 4L, 4L, 4L, 2L, 2L, 2L, 3L, 3L, 3L, 1L, 1L, 1L, 4L, 4L, 
4L), .Label = c("Autumn", "Spring", "Summer ", "Winter"), class = "factor"), 
Exposure = structure(c(1L, 3L, 2L, 4L, 3L, 2L, 4L, 3L, 2L, 
4L, 3L, 2L, 1L, 3L, 2L, 4L, 3L, 2L, 4L, 3L, 2L, 4L, 3L, 2L
), .Label = c(" Sheltered", "Exposed", "Moderately Exposed", 
"Sheltered"), class = "factor"), Average = c(1L, 2L, 4L, 
3L, 4L, 2L, 2L, 4L, 2L, 4L, 3L, 2L, 2L, 5L, 4L, 3L, 2L, 1L, 
1L, 1L, 2L, 4L, 2L, 2L), Site = c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L), SEM = c(0.5, 0.1, 0.4, 0.5, 1, 0.5, 0.5, 0.5, 
0.5, 0.5, 0.2, 0.5, 0.5, 0.1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 
0.3, 0.2, 0.5, 0.5)), class = "data.frame", row.names = c(NA, 
-24L))


`setwd("C:/Users/phl5/Documents/PippaPhD")
 getwd()
 read.csv("Graphed_Data.csv")
 Data2<-read.csv("Graphed_Data.csv")

 library(ggplot2)
 library(gtable)
 library(grid)

 dodge<- position_dodge(width=0.9)

 ggplot(Data2, aes(x = interaction(Exposure, Season), y = Average, fill 
  = factor(Site))) +
 geom_bar(stat = "identity", position = position_dodge()) +
 geom_errorbar(aes(ymax = Average + SEM, ymin = Average - SEM), position 
 = dodge, width = 0.2)


 g1<- ggplot(data = Data2, aes(x = interaction(Exposure, Season), y = 
 Average, fill = factor(Site))) +
 geom_bar(stat = "identity", position = position_dodge()) +
 geom_errorbar(aes(ymax = Average + SEM, ymin = Average - SEM), position 
 = dodge, width = 0.2) +
 coord_cartesian(ylim = c(0, 12.5))+ 
 annotate("text", x = 1:12, y = 400,
       label = rep(c("Exposed", "Moderately Exposed", "Sheltered"),4)) +
 annotate("text", c(0.5, 1.5, 2.0, 2.5), y = -800, label = c("Spring", 
 "Summer", "Autumn", "Winter"))+
 theme_classic()+
 theme(plot.margin = unit(c(1,1,1,1), "lines"),
    axis.title.x = element_blank(),
    axis.text.x = element_blank())

 g2 <- ggplot_gtable(ggplot_build(g1))
 g2$layout$clip[g2$layout$name == "panel"] <- "off"
 grid.draw(g2)`
dput(数据2)
结构(列表)季节=结构(c(2L、2L、2L、3L、3L、3L、1L、,
1L,1L,4L,4L,4L,2L,2L,3L,3L,3L,1L,1L,1L,1L,4L,4L,
4L),.Label=c(“秋”、“春”、“夏”、“冬”),class=“因子”),
曝光=结构(c(1L、3L、2L、4L、3L、2L、4L、3L、2L、,
4L、3L、2L、1L、3L、2L、4L、3L、2L、4L、3L、2L、4L、3L、2L、3L、2L
),.Label=c(“遮蔽”、“暴露”、“中度暴露”,
“受保护”),class=“factor”),平均值=c(1L、2L、4L,
3L,4L,2L,2L,4L,2L,4L,3L,2L,2L,5L,4L,3L,2L,1L,
1L,1L,2L,4L,2L,2L),站点=c(1L,1L,1L,1L,1L,1L,
1L,1L,1L,1L,1L,1L,2L,2L,2L,2L,2L,2L,2L,2L,2L,2L,2L,2L,
2L,2L,2L),SEM=c(0.5,0.1,0.4,0.5,1,0.5,0.5,0.5,
0.5, 0.5, 0.2, 0.5, 0.5, 0.1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 
0.3,0.2,0.5,0.5),class=“data.frame”,row.names=c(NA,
-(24升)
`setwd(“C:/Users/phl5/Documents/pippahd”)
getwd()
read.csv(“Graphed_Data.csv”)

数据2由于您没有提供与代码一起使用的示例数据,因此我正在尝试解决您与预先存在的数据(
cars
)有关的问题。 查看了所需的输出后,我在
r
中创建了一个条形图:

library(ggplot2)
ggplot(data = cars, aes(x =  speed, y = dist)) + 
  geom_bar(stat="identity", position = "dodge") 

您的代码存在手动将x轴覆盖为空的问题,如下所示:

ggplot(data = cars, aes(x =  speed, y = dist)) + 
  geom_bar(stat="identity", show.legend = F, position = "dodge") + 
  theme(
        axis.title.x = element_blank(),
        axis.text.x = element_blank())
如您所见,当您控制
axis.title
/
axis.text


编辑2:

关于OP在评论中的第二个问题:

  • 无需添加
    geom_hline()
    来显示轴,只需将
    axis.line
    添加到
    theme()
    panel.spacing.x=unit(0,“线”)
    以使其在面上连续
  • 每个季节只有一个标签有点棘手。您需要编辑
    ggplot
    gtable
    。 一种方法是:

  • 谢谢您的建议。这是我希望实现的事情。这是一种使背景纯白色而不是网格化和轴线的方法吗?也可能只有一个标签说明赛季,而不是三次重复?可能把中间的标签留在三个标签中,这样它就可以很好地居中了?太好了,谢谢!我已经删除了围绕x轴的额外间距,并添加了一条y轴线。但我正在努力为x轴添加一条黑线。我使用了代码“geom_hline(yintercept=0”)'但这会在标签之间产生一条带空格的黑色虚线,只有当我取出代码以消除x轴周围的多余间距时才会出现。这是一种解决方法,它可以在x轴周围产生一条连续线而不留空格吗?最后,切换x轴标签是否简单,先使用曝光标签/直接曝光标签在酒吧下面,然后是季节?感谢代码,这正是我想要的。我有另一个基于此代码的问题,但我认为创建一个新问题比不断评论更容易,如果您能提出任何建议,我将非常感激?
    gg <- ggplot(aes(x=as.factor(Site), y=Average, fill=as.factor(Site)), data=data)
    gg <- gg + geom_bar(stat = 'identity')
    gg <- gg + scale_fill_discrete(guide_legend(title = 'Site')) # just to get 'site' instead of 'as.factor(Site)' as legend title
    # gg <- gg + scale_fill_manual(values=c('black', 'grey85'), guide_legend(title = 'Site')) # to get bars in black and grey 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()
    )
    
    # facet factor levels
    season.levels <- levels(data$Season)
    exposure.levels <- levels(data$Exposure)
    
    # convert to gtable
    g <- ggplotGrob(gg)
    
    # find the grobs of the strips in the original plot
    grob.numbers <- grep("strip-b", g$layout$name)
    # filter strips from layout 
    b.strips <- gtable_filter(g, "strip-b", trim = FALSE)
    # b.strips$layout shows the strips position in the cell grid of the plot
    # b.strips$layout
    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[1]
    bottom <- b.strips$layout$b[1]
    
    # create empty matrix as basis to overly new gtable on the strip
    mat   <- matrix(vector("list", length = 10), nrow = 2)
    mat[] <- list(zeroGrob())
    
    # add new gtable matrix above each strip
    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]
      # place season labels below exposure labels in row 2 of the overlayed gtable for strips
      res <- gtable_add_grob(res, g$grobs[[grob.numbers[season.left]]]$grobs[[1]], 2, 1, 2, 5)
      # move exposure labels to row 1 of the overlayed gtable for strips
      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[[2]]
      }
      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)[1]
      g$grobs[[new.grob.no]]$grobs[[nrow(g$grobs[[new.grob.no]]$layout)]]$children[[2]]$children[[1]]$gp <- gpar(fontface='bold')
    }
    
    grid.newpage()
    grid.draw(g)
    
    gg <- ggplot(aes(x=as.factor(Site), y=Average, fill=as.factor(Site)), data=data)
    gg <- gg + geom_bar(stat = 'identity')
    # gg <- gg + scale_fill_discrete(guide_legend(title = 'Site')) # just to get 'site' instead of 'as.factor(Site)' as legend title
    gg <- gg + scale_fill_manual(values=c('black', 'grey85'), guide_legend(title = 'Site')) # to get bars in black and grey 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()
    )
    
    gg <- ggplot(aes(x=as.factor(Site), y=Average, fill=as.factor(Site)), data=data)
    gg <- gg + geom_bar(stat = 'identity')
    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_fill_discrete(guide_legend(title = 'Site'))
    gg <- gg + theme(axis.text.x = element_blank(),
                     axis.ticks.x = element_blank(),
                     axis.title.x = element_blank(),
                     panel.grid.major.x = element_blank(), # remove vertical grid lines
                     # panel.grid = element_blank(), # remove al grid lines
                     # panel.background = element_rect(fill='white'), # choose background color for plot area
                     strip.background = element_rect(fill='white')  # choose background for factor labels
                     )
    
    # facet factor levels
    season.levels <- levels(data$Season)
    exposure.levels <- levels(data$Exposure)
    # convert to gtable
    g <- ggplotGrob(gg)
    # find the grobs of the strips in the original plot
    grob.numbers <- grep("strip-b", g$layout$name)
    # filter strips from layout 
    b.strips <- gtable_filter(g, "strip-b", trim = FALSE)
    # b.strips$layout shows the strips position in the cell grid of the plot
    b.strips$layout
    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[1]
    bottom <- b.strips$layout$b[1]
    
    # create empty matrix as basis to overly new gtable on the strip
    mat   <- matrix(vector("list", length = 10), nrow = 2)
    mat[] <- list(zeroGrob())
    
    # add new gtable matrix above each strip
    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"))
      res <- gtable_add_grob(res, g$grobs[[grob.numbers[season.left.panels[i]]]]$grobs[[1]], 1, 1, 1, 5)
      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)
      g$grobs[[new.grob.no]]$grobs[[nrow(g$grobs[[new.grob.no]]$layout)]]$children[[2]]$children[[1]]$gp <- gpar(fontface='bold')
    }
    grid.newpage()
    grid.draw(g)
    
    data <- expand.grid(c('Spring', 'Summer', 'Autumn', 'Winter'), c('Sheltered', 'Moderately exposed', 'Exposed'), c(1, 2))
    names(data) <- c('Season', 'Exposure', 'Site')
    # adding some arbitrary values
    set.seed(42)
    data$Average <- sample(c(rep(3, 3), rep(2, 2), rep(1, 2), rep(NA, 17)))
    data$SEM <- NA
    SEM <- sample(c(rep(0.5, 3), rep(0.3, 2), rep(.1, 2)))
    data$SEM[which(!is.na(data$Average))] <- SEM
    
    gg <- ggplot(aes(x=as.factor(Site), y=Average, fill=as.factor(Site)), data=data)
    gg <- gg + geom_bar(stat = 'identity')
    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_fill_discrete(guide_legend(title = 'Site'))
    gg <- gg + theme(axis.text.x = element_blank(),
                     axis.ticks.x = element_blank(),
                     axis.title.x = element_blank())
    print(gg)