Colouring ggplot x axis in facets
我正在尝试在图表上突出显示 x 轴值,我可以根据此示例执行此操作,但是当我尝试处理事物时遇到了问题。刻面沿 x 轴具有不同的大小和顺序。这最终使事情变得复杂。我还怀疑每个方面的 x 轴必须相同,但是我希望有人可以证明我的不同。
我的例子是纯样本数据,我的集合的大小有点大,所以如果我在真实数据集上测试它会导致更多问题,我现在很抱歉。
数据
1
2 3 4 5 6 7 8 |
library(data.table)
dt1 <- data.table(name=as.factor(c(“steve”,”john”,”mary”,”sophie”,”steve”,”sophie”)), activity=c(“a”,”a”,”a”,”a”,”b”,”b”), value=c(22,32,12,11,25,32), colour=c(“black”,”black”,”black”,”red”,”black”,”red”)) dt1[,myx := paste(activity, name,sep=”.”)] |
根据此 SO 问题帮助对 x 轴上的项目进行排序的功能。
1
|
roles <- function(x) sub(“[^_]*\\\\.”,””,x )
|
图表
1
2 3 4 5 |
ggplot() +
geom_bar(data=dt1,aes(x=myx, y=value), stat=”identity”) + facet_grid( ~ activity, scales =”free_x”,space =”free_x”) + theme(axis.text.x = element_text(colour=dt1[,colour[1],by=myx][,V1])) + scale_x_discrete(labels=roles) |
您可以看到,即使将” 红色”分配给=”” sophie,格式也会应用于=”” john。其中一些与数据集的排序有关。<=”” p=”” class=”box-hide”>
图表2
如果我添加 setkey 我会接近正确的结果
1
2 3 4 5 6 |
setkey(dt1,myx)
ggplot() + geom_bar(data=dt1,aes(x=myx, y=value), stat=”identity”) + facet_grid( ~ activity, scales =”free_x”,space =”free_x”) + theme(axis.text.x = element_text(colour=dt1[,colour[1],by=myx][,V1])) + scale_x_discrete(labels=roles) |
不幸的是,我们看到第二个方面的 x 轴项目以??红色突出显示。我认为这是因为它从第一个图表中获取格式并在第二个图表中以相同的顺序应用它。
任何关于如何将格式应用到同一个人存在于多个活动中或一个人只存在于一个活动中的工作的想法将不胜感激。
如果你能忍受一个相当肮脏的黑客,我可以分享我在这些情况下所做的事情。基本上我搞乱了底层的网格结构,这基本上是很多 browser 和 str 在开头的调用:)
ggplot
1
2 3 4 |
p <- ggplot() +
geom_bar(data=dt1,aes(x=myx, y=value), stat=”identity”) + facet_grid( ~ activity, scales =”free_x”,space =”free_x”) + scale_x_discrete(labels=roles) |
网格
现在您必须提取表示 x 轴的底层 grob 对象才能更改颜色。
1
2 3 |
library(grid)
bp <- ggplotGrob(p) wh <- which(grepl(“axis-b”, bp$layout$name)) # get the x-axis grob |
bp$grobs[wh] 现在包含两个 x 轴。现在您必须更深入地了解对象才能更改颜色。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
bp$grobs[wh] <- lapply(bp$grobs[wh], function(gg) {
## we need to extract the right element ## this is not that straight forward, but in principle I used ‘str’ to scan through ## the objects to find out which element I would need kids <- gg$children wh <- which(sapply(kids$axis$grobs, function(.) grepl(“axis\\\\.text”, .$name))) axis.text <- kids$axis$grobs[[wh]] ## Now that we found the right element, we have to replicate the colour and change ## the element corresponding to ‘sophie’ axis.text$gp$col <- rep(axis.text$gp$col, length(axis.text$label)) axis.text$gp$col[grepl(“sophie”, axis.text$label)] <-“red”
## write the changed object back to the respective slot |
所以,现在我们要做的就是绘制网格对象:
1
|
grid.draw(bp)
|
诚然,这是一个相当粗略的 hack,但它提供了所需的内容:
更新
这不适用于较新版本的 ggplot2,因为 grob 的内部结构发生了变化。因此,您需要进行一些调整才能使其再次工作。原则上,相关的 grob 插槽向下移动了一个插槽,现在可以在 .$children[[1]]
中找到
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
bp$grobs[wh] <- lapply(bp$grobs[wh], function(gg) {
## we need to extract the right element ## this is not that straight forward, but in principle I used ‘str’ to scan through ## the objects to find out which element I would need kids <- gg$children wh <- which(sapply(kids$axis$grobs, function(.) grepl(“axis\\\\.text”, .$name))) axis.text <- kids$axis$grobs[[wh]]$children[[1]] ## Now that we found the right element, we have to replicate the colour and change ## the element corresponding to ‘sophie’ axis.text$gp$col <- rep(axis.text$gp$col, length(axis.text$label)) axis.text$gp$col[grepl(“sophie”, axis.text$label)] <-“red” ## write the changed object back to the respective slot kids$axis$grobs[[wh]]$children[[1]] <- axis.text gg$children <- kids gg }) grid.draw(bp) |
- 我怀疑它可能是这样的。现在看看我是否可以将它与这个 stackoverflow.com/questions/26727741/…
- 它为我指明了正确的方向,我已经设法使用带有刻面的双 y 轴图表来实现它。
- 任何提示如何使用 ggplot 2.0 和 grid 3.1.2 进行这项工作?
- 绝对享受!
试试:
1
2 3 4 |
ggplot() +
geom_bar(data=dt1,aes(x=name, y=value, fill = name), stat=”identity”) + |
- 这并没有真正解决为 x 轴标签着色的问题。
来源:https://www.codenong.com/26966883/