多行轴标签嵌套分组variables

我希望两个不同的嵌套分组variables的级别出现在图下方的分隔线上,而不是图例中。 我现在所拥有的是这个代码:

data <- read.table(text = "Group Category Value S1 A 73 S2 A 57 S1 B 7 S2 B 23 S1 C 51 S2 C 87", header = TRUE) ggplot(data = data, aes(x = Category, y = Value, fill = Group)) + geom_bar(position = 'dodge') + geom_text(aes(label = paste(Value, "%")), position = position_dodge(width = 0.9), vjust = -0.25) 

在这里输入图像描述

我想要的是这样的:

在这里输入图像描述

有任何想法吗?

您可以为axis.text.x创build一个自定义元素函数。

在这里输入图像描述

 library(ggplot2) library(grid) ## create some data with asymmetric fill aes to generalize solution data <- read.table(text = "Group Category Value S1 A 73 S2 A 57 S3 A 57 S4 A 57 S1 B 7 S2 B 23 S3 B 57 S1 C 51 S2 C 57 S3 C 87", header=TRUE) # user-level interface axis.groups = function(groups) { structure( list(groups=groups), ## inheritance since it should be a element_text class = c("element_custom","element_blank") ) } # returns a gTree with two children: # the categories axis # the groups axis element_grob.element_custom <- function(element, x,...) { cat <- list(...)[[1]] groups <- element$group ll <- by(data$Group,data$Category,I) tt <- as.numeric(x) grbs <- Map(function(z,t){ labs <- ll[[z]] vp = viewport( x = unit(t,'native'), height=unit(2,'line'), width=unit(diff(tt)[1],'native'), xscale=c(0,length(labs))) grid.rect(vp=vp) textGrob(labs,x= unit(seq_along(labs)-0.5, 'native'), y=unit(2,'line'), vp=vp) },cat,tt) gX <- textGrob(cat, x=x) gTree(children=gList(do.call(gList,grbs),gX), cl = "custom_axis") } ## # gTrees don't know their size grobHeight.custom_axis = heightDetails.custom_axis = function(x, ...) unit(3, "lines") ## the final plot call ggplot(data=data, aes(x=Category, y=Value, fill=Group)) + geom_bar(position = position_dodge(width=0.9),stat='identity') + geom_text(aes(label=paste(Value, "%")), position=position_dodge(width=0.9), vjust=-0.25)+ theme(axis.text.x = axis.groups(unique(data$Group)), legend.position="none") 

ggplot2 2.0.0中引入的切面参数现在通过分面相当简单地创build了这个图的简单版本。 为了让情节不受干扰,只需将panel.margin设置为0即可。

以下是从@ agtudy的答案中使用具有不同数量的Groups per Category的数据集的示例。

  • 我用scales = "free_x"从类别中删除了额外的组,虽然这并不总是可取的。
  • switch = "x"参数将facet标签移动到底部。 我一起删除了条形背景,但是我可以看到,在某些情况下,留下条形矩形将会很有用。
  • 我使用width = 1 ,使每个类别触摸栏 – 默认情况下,他们之间有空格。

ggplot2_2.0.0的代码:

 ggplot(data = data, aes(x = Group, y = Value, fill = Group)) + geom_bar(stat = "identity") + geom_text(aes(label = paste(Value, "%")), vjust = -0.25) + facet_wrap(~Category, switch = "x", scales = "free_x") + theme(panel.margin = unit(0, "lines"), strip.background = element_blank()) 

ggplot2_2.2.0的代码, switchstrip.positionpanel.marginpanel.spacing ,在theme使用strip.placement

 ggplot(data = data, aes(x = Group, y = Value, fill = Group)) + geom_bar(stat = "identity", width = 1) + geom_text(aes(label = paste(Value, "%")), vjust = -0.25) + facet_wrap(~Category, strip.position = "bottom", scales = "free_x") + theme(panel.spacing = unit(0, "lines"), strip.background = element_blank(), strip.placement = "outside") 

在这里输入图像描述

你可以在facet_grid使用scales = "free_x" ,如果你想要所有的小节都是相同的宽度,不pipe每个分类有多less组。 您也可能想要更改x轴的标签; 我不确定它应该是什么,也许类别而不是组?

 ggplot(data = data, aes(x = Group, y = Value, fill = Group)) + geom_bar(stat = "identity", width = 1) + geom_text(aes(label = paste(Value, "%")), vjust = -0.25) + facet_grid(~Category, switch = "x", scales = "free_x", space = "free_x") + theme(panel.margin = unit(0, "lines"), strip.background = element_blank()) + xlab("Category") 

在这里输入图像描述

agstudy的方法的替代方法是编辑gtable并插入由ggplot2计算的“轴”

 p <- ggplot(data=data, aes(x=Category, y=Value, fill=Group)) + geom_bar(position = position_dodge(width=0.9),stat='identity') + geom_text(aes(label=paste(Value, "%")), position=position_dodge(width=0.9), vjust=-0.25) axis <- ggplot(data=data, aes(x=Category, y=Value, colour=Group)) + geom_text(aes(label=Group, y=0), position=position_dodge(width=0.9)) annotation <- gtable_filter(ggplotGrob(axis), "panel", trim=TRUE) annotation[["grobs"]][[1]][["children"]][c(1,3)] <- NULL #only keep textGrob library(gtable) g <- ggplotGrob(p) gtable_add_grobs <- gtable_add_grob # let's use this alias g <- gtable_add_rows(g, unit(1,"line"), pos=4) g <- gtable_add_grobs(g, annotation, t=5, b=5, l=4, r=4) grid.newpage() grid.draw(g) 

在这里输入图像描述

给出类似(虽然不相同)的结果的一个非常简单的解决scheme是使用刻面。 缺点是类别标签是高于而不是低于。

 ggplot(data=data, aes(x=Group, y=Value, fill=Group)) + geom_bar(position = 'dodge', stat="identity") + geom_text(aes(label=paste(Value, "%")), position=position_dodge(width=0.9), vjust=-0.25) + facet_grid(. ~ Category) + theme(legend.position="none") 

使用刻面提供辅助标签

@agstudy已经回答了这个问题,我将自己使用它,但如果你接受更丑陋,更简单的方法,那么在他回答之前,

 data <- read.table(text = "Group Category Value S1 A 73 S2 A 57 S1 B 7 S2 B 23 S1 C 51 S2 C 87", header=TRUE) p <- ggplot(data=data, aes(x=Category, y=Value, fill=Group)) p + geom_bar(position = 'dodge') + geom_text(aes(label=paste(Value, "%")), position=position_dodge(width=0.9), vjust=-0.25) + geom_text(colour="darkgray", aes(y=-3, label=Group), position=position_dodge(width=0.9), col=gray) + theme(legend.position = "none", panel.background=element_blank(), axis.line = element_line(colour = "black"), axis.line.x = element_line(colour = "white"), axis.ticks.x = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), panel.background = element_blank()) + annotate("segment", x = 0, xend = Inf, y = 0, yend = 0) 

哪个会给我们:

在这里输入图像描述