使用ggplot2在坐标轴上将个别标签加粗。

6

这个问题的灵感来自于以下问题和解决方案:Highlighting individual axis labels in bold using ggplot2

我希望根据满足特定条件来选择性地调整水平轴标签的对齐方式。因此,借鉴上述问题和答案,我设置了一个示例:

require(ggplot2)
require(dplyr)
set.seed(36)
xx<-data.frame(YEAR=rep(c("X", "Y"), each=20),
           CLONE=rep(c("A", "B", "C", "D", "E"), each=4, 2),
           TREAT=rep(c("T1", "T2", "T3", "C"), 10),
           VALUE=sample(c(1:10), 40, replace=T))

# Simple plot with factors on y axis
ggplot(xx, aes(x = VALUE, y=CLONE, fill=YEAR)) + 
    geom_bar(stat="identity", position="dodge") +
    facet_wrap(~TREAT)

这里输入图片描述

好的,我采用了上面问题和答案中的函数来生成一个仅包含理由的向量:

# Modify to control justification
colorado2 <- function(src, boulder) {
    if (!is.factor(src)) src <- factor(src)                   
    src_levels <- levels(src)                                 
    brave <- boulder %in% src_levels                         
    if (all(brave)) {                                         
        b_pos <- purrr::map_int(boulder, ~which(.==src_levels)) 
        b_vec <- rep(0.2, length(src_levels))               
        b_vec[b_pos] <- 0.9                                 
        b_vec                                                  
    } else {
        stop("All elements of 'boulder' must be in src")
    }
}

# Redraw the plot with modifcation
ggplot(xx, aes(x = VALUE, y=CLONE, fill=YEAR)) + 
    geom_bar(stat="identity", position="dodge") +
    facet_wrap(~TREAT) +
    theme(axis.text.y=element_text(hjust=colorado2(xx$CLONE, c("A", "B", "E"))))

我遇到了这个不幸的问题: enter image description here 标签在我想要的方向上是对齐的,但占用了太多的绘图空间,原因我无法理解。如何解决这个问题?
2个回答

2

我做了一些调查。问题出在ggplot设置y轴grob的宽度上。它假设所有标签的hjust都相同。我们可以通过对grob树进行一些破解来解决这个问题。以下代码已经在ggplot2的开发版本中测试过,可能无法与当前发布的版本完全相同。

首先,一个简单的可重现示例:

p <- ggplot(mpg, aes(manufacturer, hwy)) + geom_boxplot() + coord_flip() + 
  theme(axis.text.y = element_text(hjust = c(rep(1, 10), rep(0, 5))))
p # doesn't work

图片描述进入此处

问题在于轴图形的grob宽度被设置为整个绘图区域。但是我们可以手动调整宽度。不幸的是,我们必须在多个位置进行修复:

# get a vector of the y labels as strings
ylabels <- as.character(unique(mpg$manufacturer))

library(grid)
g <- ggplotGrob(p)

# we need to fix the grob widths at various locations in the grob tree
g$grobs[[3]]$children[[2]]$widths[1] <- max(stringWidth(ylabels))
g$grobs[[3]]$width <- sum(grobWidth(g$grobs[[3]]$children[[1]]), grobWidth(g$grobs[[3]]$children[[2]]))
g$widths[3] <- g$grobs[[3]]$width

# draw the plot
grid.newpage()
grid.draw(g)

这里输入图片描述

ggplot2的轴绘制代码可能可以像我在这里所做的那样从一开始就计算宽度,然后问题就会消失。


1
你所使用的方法是黑客攻击底层网格图形引擎,结果可能并不明显。请参阅此处的答案,该答案进入了grob树并修复了问题。
然而,对于问题陈述中所述的问题,有一个简单的解决方案,不需要任何黑客攻击。只需制作一些带有一些尾随空格的标签即可。我在这里手动完成了此操作,但您也可以编写一个执行此操作的函数。
ggplot(xx, aes(x = VALUE, y=CLONE, fill=YEAR)) + 
  geom_bar(stat="identity", position="dodge") +
  scale_y_discrete(breaks = c("A", "B", "C", "D", "E"),
                   labels = c("A    ", "B    ", "C", "D", "E    ")) +
  facet_wrap(~TREAT)

enter image description here


哎呀,我没意识到那个解决方案会有任何问题!所以我觉得你的解决方案存在对齐问题。在我的真实数据中,它不是字母,而是长度不同的单词。假设这些单词是:c("啤酒", "喜力", "健力士", "红酒", "梅洛", "霞多丽", "威士忌", "米德尔顿", "詹姆森"),我想让啤酒、红酒和威士忌左对齐,其他的右对齐 - 它们需要左或右对齐。 - user2498193
1
我发布了第二个回答来解决这个问题。 - Claus Wilke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接