paw*_*els 32 r bar-chart ggplot2 axis-labels
我希望两个不同的嵌套分组变量的级别出现在图表下方的单独行中,而不是在图例中.我现在拥有的是这段代码:
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)
Run Code Online (Sandbox Code Playgroud)

我想拥有的是这样的:

有任何想法吗?
aos*_*ith 44
自ggplot2 2.2.0 以来的strip.position参数facet_wrap()和switch参数现在通过分面创建这个绘图的简单版本相当简单.要为绘图提供不间断的外观,请将其设置为0.facet_grid()panel.spacing
以下是使用@ agtudy答案的每个类别的不同组数的数据集的示例.
scales = "free_x"从没有它的类别中删除额外的组,尽管这并不总是可取的. strip.position = "bottom"参数将构面标签移动到底部.我一起删除了条带背景strip.background,但我可以看到离开条形矩形在某些情况下会很有用. width = 1在每个类别触摸中制作条形图 - 默认情况下它们之间有空格.我也用strip.placement,并strip.background在theme获得底部的条状并取出纸带矩形.
ggplot2_2.2.0或更新版本的代码:
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")
Run Code Online (Sandbox Code Playgroud)
如果您希望所有条形宽度相同space= "free_x",facet_grid()则可以使用in ,而不管每个类别有多少组.请注意,这使用switch = "x"而不是strip.position.您还可能想要更改x轴的标签; 我不确定应该是什么,也许是Category而不是Group?
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.spacing = unit(0, "lines"),
strip.background = element_blank(),
strip.placement = "outside") +
xlab("Category")
Run Code Online (Sandbox Code Playgroud)
较旧的代码版本
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())
Run Code Online (Sandbox Code Playgroud)
ags*_*udy 18
您可以为其创建自定义元素功能axis.text.x.

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)
g.X <- textGrob(cat, x=x)
gTree(children=gList(do.call(gList,grbs),g.X), 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")
Run Code Online (Sandbox Code Playgroud)
M A*_*lio 13
我知道这个问题已经很老了,但我想介绍最干净的方法来做到这一点ggh4x
library(ggplot2)
library(ggh4x)
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)
# Only one more line of code with the function 'guide_axis_nested'
# and changing the data from x axis to interaction(Group,Category, sep = "!")
ggplot(data = data, aes(x = interaction(Group,Category, sep = "!"), y = Value, fill = Group)) +
geom_col(position = 'dodge', show.legend = FALSE) +
geom_text(aes(label = paste(Value, "%")),
position = position_dodge(width = 0.9), vjust = -0.25) +
scale_x_discrete(guide = guide_axis_nested(delim = "!"), name = "Category")
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)

给出类似(但不相同)结果的非常简单的解决方案是使用刻面.缺点是类别标签高于而不是低于标签.
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")
Run Code Online (Sandbox Code Playgroud)
