我希望两个不同的嵌套分组变量的级别显示在绘图下方的单独行中,而不是在图例中。我现在拥有的是这段代码:
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)
我想拥有的是这样的:
有什么想法吗?
答案 0 :(得分:40)
strip.position
中的facet_wrap()
参数和switch
中的facet_grid()
参数,因为 ggplot2 2.2.0现在创建了一个简单的版本这个情节通过刻面相当简单。要为绘图提供不间断的外观,请将panel.spacing
设置为0。
以下是使用@ 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")
如果您希望所有条形宽度相同,无论每个类别有多少组,您都可以在space= "free_x"
中使用facet_grid()
。请注意,这使用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")
较旧的代码版本
首次推出此功能时,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())
答案 1 :(得分: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")
答案 2 :(得分:7)
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)
答案 3 :(得分:7)
一个非常简单的解决方案,它提供了一个类似(但不相同)的结果是使用刻面。缺点是类别标签高于而不是低于。
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")
答案 4 :(得分:4)
@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)
哪会给我们:
答案 5 :(得分:1)
这是使用我正在处理的用于分组条形图(ggNestedBarChart)的软件包的另一种解决方案:
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)
devtools::install_github("davedgd/ggNestedBarChart")
library(ggNestedBarChart)
library(scales)
p1 <- ggplot(data, aes(x = Category, y = Value/100, fill = Category), stat = "identity") +
geom_bar(stat = "identity") +
facet_wrap(vars(Category, Group), strip.position = "top", scales = "free_x", nrow = 1) +
theme_bw(base_size = 13) +
theme(panel.spacing = unit(0, "lines"),
strip.background = element_rect(color = "black", size = 0, fill = "grey92"),
strip.placement = "outside",
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
panel.grid.major.y = element_line(colour = "grey"),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = 0),
panel.background = element_rect(fill = "white"),
legend.position = "none") +
scale_y_continuous(expand = expand_scale(mult = c(0, .1)), labels = percent) +
geom_text(aes(label = paste0(Value, "%")), position = position_stack(0.5), color = "white", fontface = "bold")
ggNestedBarChart(p1)
ggsave("p1.png", width = 10, height = 5)
请注意,ggNestedBarChart可以根据需要对尽可能多的级别进行分组,而不仅限于两个级别(即本示例中的Category和Group)。例如,使用data(mtcars):
此示例的代码在GitHub页面上。