使用ggplot2在图表中加粗显示个别坐标轴标签

14
我想要将单独的轴标签加粗。我知道@MrFlick的这个答案,但我不知道如何做到a)对多个项目进行操作,以及b)是否可以使用标签的名称而不是列表(或表达式)中的项目编号。

编辑(开始)

我也知道这个答案,但它基于填充美学(即a <- ifelse(data$category == 0, "red", "blue")来着色标签。这对我的情况不起作用,因为我不想根据填充美学来着色标签,而是想按照我喜欢的方式单独加粗它们

编辑(结束)

这是一个示例数据集:

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))

然后我根据特定的因子组合对我的标签进行排序,然后在绘图的多个面板中应该保持这种排序。请参阅我之前的问题这里

clone_order <- xx %>% subset(TREAT == "C"  & YEAR == "X") %>%
  arrange(-VALUE) %>% select(CLONE) %>% unlist()    
xx <- xx %>% mutate(CLONE = factor(CLONE, levels = clone_order))

ggplot(xx, aes(x=CLONE, y=VALUE, fill=YEAR)) + 
  geom_bar(stat="identity", position="dodge") +
  facet_wrap(~TREAT)

enter image description here

现在我想要加粗列表中的 CloneABE。我确信这样做肯定有办法,但我无法弄清楚如何操作。理想情况下,我们希望能够通过a)使用列表/表达式中的项目编号,以及b)通过使用标签(例如ABE)来实现。

3个回答

19
你可以在 scale_x_discrete 中创建一个命名的表达式向量(将文本转换为粗体),并使用 parse=TRUE 来评估这些表达式:
ggplot(xx, aes(x=CLONE, y=VALUE, fill=YEAR)) + 
    geom_bar(stat="identity", position="dodge") +
    facet_wrap(~TREAT) +
    scale_x_discrete(labels=c("A"=expression(bold(A)), "C"=expression(bold(C)),
                              "E"=expression(bold(E)), parse=TRUE))

你可能可以通过编程的方式创建表达式向量,而不是手动输入它们,但是我现在想不起来怎么做了。

输入图片描述


1
谢谢@eipi10!我也喜欢这个答案,因为它很简单(即点赞)。但是@hrbrmstr的回答给了我更多的控制。 - Stefan
是的,我也喜欢他的回答。 - eipi10

18

这是一种通用的方法来创建加粗向量:

colorado <- function(src, boulder) {
  if (!is.factor(src)) src <- factor(src)                   # make sure it's a factor
  src_levels <- levels(src)                                 # retrieve the levels in their order
  brave <- boulder %in% src_levels                          # make sure everything we want to make bold is actually in the factor levels
  if (all(brave)) {                                         # if so
    b_pos <- purrr::map_int(boulder, ~which(.==src_levels)) # then find out where they are
    b_vec <- rep("plain", length(src_levels))               # make'm all plain first
    b_vec[b_pos] <- "bold"                                  # make our targets bold
    b_vec                                                   # return the new vector
  } else {
    stop("All elements of 'boulder' must be in src")
  }
}

ggplot(xx, aes(x=CLONE, y=VALUE, fill=YEAR)) + 
  geom_bar(stat="identity", position="dodge") +
  facet_wrap(~TREAT) +
  theme(axis.text.x=element_text(face=colorado(xx$CLONE, c("A", "B", "E"))))

哇,这太棒了!谢谢!还有一个问题,除了加粗之外,使用 axis.text.x 中的 size= 是否也可以增加加粗标签的字体大小,比如说增加 2pt? - Stefan
1
嗯。大多数element_text()的参数都可以进行向量化,但你需要复制并调整该函数,使其成为一个“大小”改变器而非“字体”改变器。 - hrbrmstr
尝试将其适应于交替顶部或底部对齐所选标签。我编写了代码,但它只生成一个空白图。在您的colorado'函数中,用1.0替换“plain”,用0.0替换“bold”。在绘图调用中:theme(axis.text.x=element_text(vjust=colorado2(xx$CLONE, c("A", "B", "E"))))'。然而,更改占据了一半的图形区域,这不是我想要的。有什么办法可以在图形区域内缩放标签区域中的0或1吗?@hrbrmstr - user2498193
1
定义一个新问题anony-user @user2498193 - hrbrmstr
没问题,@hrbrmstr - 新问题已经发布:https://dev59.com/0ajja4cB1Zd3GeqP8EOH 如果您有时间,感谢您的帮助! - user2498193

17

我不确定您是否可以按名称映射标签特性,但通过调用theme,肯定可以按位置实现:

ggplot(xx, aes(x=CLONE, y=VALUE, fill=YEAR)) + 
  geom_bar(stat="identity", position="dodge") +
  facet_wrap(~TREAT) +
  theme(axis.text.x = element_text(face = c('bold', 'bold', 'plain', 'plain', 'bold')))
请注意,axis.text.x中列出的字体与您的X轴标签(五个元素)的长度相同。这会产生以下结果:
enter image description here

谢谢!使用axis.text.x肯定是一个选项,但有点繁琐,因为我有34个因子水平。这就是为什么我希望以名称指定要加粗的那些,而不是通过计算位置。我已经给你的答案点赞了,但想再开放一段时间。也许有人有不同的想法。 - Stefan
玩弄这个更多,看起来 element_text 只按位置工作并忽略命名。减少打字的一个选项是明智地使用 rep,例如:c(rep('plain', 10), rep(c('bold', 'plain', each = 2)) 将使前10个标签为 plain,接下来的2个为 bold,再接下来的2个为 plain。 - jdobres
正是我所需要的 - 感谢 @jdobres!我使用逻辑向量来创建我的“face”向量。 - jesseaam

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