如何在 ggplot facet wrap 标签中使用不同的字体大小?

Posted

技术标签:

【中文标题】如何在 ggplot facet wrap 标签中使用不同的字体大小?【英文标题】:How to use different font sizes in ggplot facet wrap labels? 【发布时间】:2016-07-19 23:18:06 【问题描述】:

我想在分面环绕的标签中创建两种不同大小的文本。

例如:

物种 X(14 号) 总捕获量 (n=133)(大小 12)

test <- read.csv(paste0(path, "Costello Artvgl2 for Stack.csv"), sep = ";", dec = ",", header = T)

str(test)


test$Wert <- factor(test$Wert, levels = c("one","two","three","four","five","six")) 


test$Sampling.site <- factor(test$Sampling.site, levels = c("Species X Area T","Species Y Area T","Species X Area A","Species Y Area B","Species X Area B","Species Y Area C"))


levels(test$Sampling.site) <-  c("Species X\nTotal catch (n=133)", "Species Y\nTotal catch (n=185)", "Species X\nSampling area A (n=57)", "Species Y\nSampling area B (n=122)",
                             "Species X\nSampling area B (n=76)",  "Species Y\nSampling area C (n=63)")

theme_new <- function(base_size = 12, base_family = base_family)
theme_bw(base_size = base_size) %+replace%
theme(
  axis.text.x =       element_text(size = 8 ),
  axis.text.y =       element_text(size = 8 ),
  axis.title.x =        element_text(size = 12, vjust = 0.01),
  axis.title.y =        element_text(size = 12, vjust = 0.9, angle = 90),

  plot.title =        element_text(size = 10, face = "bold"),

  legend.key=         element_rect(colour= NA, fill =NA, size = 0.5),
  legend.key.size =   unit(1, "lines"),
  legend.text =       element_text(size = 8),
  legend.title =      element_blank(),

  strip.background =  element_rect(fill = NA, colour = NA), 
  strip.text =        element_text(size = 8, face = "bold",hjust = 0.5, vjust = 0.9),

  panel.background =  element_rect(fill = "white"), 
  panel.border =      element_rect(fill = NA, colour="black"), 
  panel.grid.major =  element_blank(),
  panel.grid.minor =  element_blank(),
  panel.margin =      unit(1, "lines")

)


ggplot(test, aes(Fi, Pi),group=Wert)+
geom_point(aes(colour = factor(Wert),shape = factor(Wert)),size=3)      +                         
  scale_shape_manual(values=c(20,18,19,15,16,17))+                    
  scale_x_continuous(limits=c(0, 1),breaks=c(0,0.2,0.4,0.6,0.8,1.0))+     
  scale_colour_brewer(type = "qual", palette = "Paired")+
  scale_y_continuous(limits=c(0, 100),breaks=c(0,20,40,60,80,100))+        
  labs(x = "Frequency of occurrence", y = "Prey-specific abundance [%]")+ 
  facet_wrap(~Sampling.site,scales = "free",ncol = 2) +
  theme_new()

有没有可能意识到这一点?

【问题讨论】:

这是一个很好的问题,但您可以考虑使您的示例最小化且可重现。例如。改编the documentation中的一个例子。 如何上传excel文件,以便重现代码? 请不要。您的问题与您的特定数据无关,您问题中的大部分代码也无关紧要。做一个简单的例子来说明你的问题,让回答者付出最小的努力。同样,简单地使用文档中的一个示例是制作超级简单示例的直接方法。请记住,问题也应该对未来的读者有用。 See here for some more tips. @PapaLuzie 鉴于新的ggtext 包很容易解决这个问题,我建议接受克劳斯威尔克的新答案,而不是我的。 【参考方案1】:

目前正在开发的 ggtext 包为这个问题提供了更优雅的解决方案。它支持一小组 html 标签,可用于设置部分文本标签的样式。

注意:安装ggtext的开发版可能会拉入ggplot2的开发版。

library(tidyverse)
library(ggtext) # remotes::install_github("clauswilke/ggtext")
library(glue)
#> 
#> Attaching package: 'glue'
#> The following object is masked from 'package:dplyr':
#> 
#>     collapse

count(mtcars, cyl)  %>% 
  mutate(
    cyl_lab = as.character(
      glue("Cylinders: cyl<br><span style='font-size:9pt'>Count: n</span>")
    )
  ) %>%
  full_join(mtcars) %>%
  ggplot(aes(wt, mpg)) +
  geom_point() +
  facet_grid(. ~ cyl_lab) +
  theme_bw(12) +
  theme(strip.background=element_rect(fill=NA, color=NA),
        strip.text=element_markdown(size = 12, lineheight = 1.1))
#> Joining, by = "cyl"

由reprex package (v0.3.0) 于 2020-01-07 创建

【讨论】:

【参考方案2】:

下面的解决方案是一个 hack,它使用上标(或下标)来为构面标签的第二行获取较小的字体大小。我不知道如何更好地控制标签大小,而无需直接操作条形 grobs,尽管可能有一种方法可以编写 labeller 函数来做到这一点。

我们将使用内置的mtcars 数据框作为示例。首先,我们将添加用于分面和标签的列。我们将按cyl 进行刻面,但我们希望标签的第一行显示该刻面的柱面数,第二行显示该刻面中的数据点数。为此,我们将在mtcars 中创建两个新列,称为Label1Label2,我们将使用它们来创建构面标签的每一行。我们将通过这两列来分面以获得我们想要在图中的标签。 (Label3 类似于 Label2,但使用下标而不是上标;这仅在您想更改从第二行底部到绘图面板顶部的距离时才重要。)

Label1Label2 是文本字符串,但它们是表达式的形式,因此我们可以在创建绘图时使用label_parsed 来获得更小的下标文本。

library(ggplot2)
library(dplyr)
library(grid)

mtcars.new = mtcars %>% group_by(cyl) %>% 
  summarise(Label1=paste0("bold(Cylinders:~", unique(cyl),")"),
            Label2=paste0("bold(NULL[Count:~", length(cyl),"])"),
            Label3=paste0("bold(NULL^Count:~", length(cyl),")")) %>%
  full_join(mtcars)

现在我们可以创建情节了。 Label1Label2 的分面给了我们两条线。因为我们为Label2 创建了一个下标表达式,所以当我们使用label_parsed 标记构面时,它会以较小的字体呈现。相对于Label1,我更希望Label2 更大一点,但是没有办法用这种(hacky)方法来控制它。此外,虽然 element_text 有一个 lineheight 参数,但 ggplot 似乎并不尊重它。结果,我手动重置了条形标签的行高,以减少两个标签之间的空间。

p = ggplot(mtcars.new, aes(wt, mpg)) +
  geom_point() +
  facet_grid(. ~ Label1 + Label2, labeller=label_parsed) +
  theme_bw() +
  theme(strip.background=element_rect(fill=NA, color=NA),
        strip.text=element_text(size=12))

g <- ggplotGrob(p)
g$heights[[3]] = unit(0.5,"lines")

grid.draw(g)

【讨论】:

以上是关于如何在 ggplot facet wrap 标签中使用不同的字体大小?的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中使用带有 facet_wrap 的 ggplot2 显示多个轴标签

更改 facet wrap ggplot 中的标签 [重复]

ggplot重命名facet_wrap中的构面标签

如何控制显示哪些 facet_wrap 标签

R语言ggplot2可视化删除所有分面图(facet_wrap可视化的facet结果)的标签实战(Remove facet_wrap labels)

ggplot2中facet_wrap( )的高阶用法