簡體   English   中英

如何訪問由 `ggplot2` 中的 `geom_text` 繪制的標簽尺寸?

[英]How can I access dimensions of labels plotted by `geom_text` in `ggplot2`?

據我所知ggplot2知道geom_text繪制的標簽的尺寸。 否則check_overlap選項將不起作用。

這些維度存儲在哪里以及如何訪問它們?


示例

library(ggplot2)
df <- data.frame(x = c(1, 2), 
                 y = c(1, 1), 
                 label = c("label-one-that-might-overlap-another-label", 
                           "label-two-that-might-overlap-another-label"), 
                 stringsAsFactors = FALSE)

使用check_overlap = FALSE (默認值),標簽相互check_overlap = FALSE

ggplot(df, aes(x, y)) + 
  geom_text(aes(label = label)) + 
  xlim(0, 3)                              

在此處輸入圖片說明

使用check_overlap = TRUE ,不會繪制第二個標簽,因為ggplot發現了重疊。

ggplot(df, aes(x, y)) + 
  geom_text(aes(label = label), check_overlap = TRUE) + 
  xlim(0, 3)

在此處輸入圖片說明

ggplot2如何知道這些標簽重疊? 我怎樣才能訪問這些信息?

在繪制文本之前,grid 包中的文本並沒有真正的大小。 下面,我們將創建一個輔助函數來測量文本,但除非您事先知道繪圖區域的設備和大小,否則這樣做沒有任何意義。 (對於那些makeContent() ,在繪制的makeContent()階段)。

library(grid)

label <- c("label-one-that-might-overlap-another-label", 
           "label-two-that-might-overlap-another-label")

measure_size <- function(txt, gp = gpar(), to = "mm") {
  if (is.grob(txt)) {
    grobs <- lapply(seq_along(txt$label), function(i) {
      g <- txt
      # Subset grob per label
      g$label <- g$label[[i]]
      g$gp[]  <- lapply(g$gp, function(x) {x[pmin(i, length(x))]})
      g$rot   <- g$rot[pmin(i, length(g$rot))]
      g
    })
  } else {
    grobs <- lapply(txt, function(t) textGrob(t, gp = gp))
  }
  
  heights <- do.call(unit.c, lapply(grobs, grobHeight))
  widths  <- do.call(unit.c, lapply(grobs, grobWidth))
  
  cbind(
    height = convertHeight(heights, to, valueOnly = TRUE),
    weight = convertWidth(widths,   to, valueOnly = TRUE)
  )
}

我們現在可以盡可能地猜測文本的大小,但正如人們所料,它在很大程度上取決於文本的圖形參數,實際大小是多少。 請注意,例如更改字體也會更改文本的大小。

measure_size(label)
#>      height   weight
#> [1,]  3.175 79.13109
#> [2,]  3.175 78.65566

measure_size(label, gp = gpar(fontfamily = "Garamond"))
#>        height   weight
#> [1,] 2.645833 69.67223
#> [2,] 2.645833 69.69704

現在將相同的技巧應用於 ggplot2 的文本層。

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.1.1

df <- data.frame(x = c(1, 2), 
                 y = c(1, 1), 
                 label = label)

p <- ggplot(df, aes(x, y)) + 
  geom_text(aes(label = label)) + 
  xlim(0, 3) 

textgrob <- layer_grob(p)[[1]]
measure_size(textgrob)
#>        height   weight
#> [1,] 2.645979 72.83233
#> [2,] 2.645979 72.39411

reprex 包(v2.0.1) 於 2021 年 12 月 13 日創建

我最近自己處理了很多文本,發現 {systemfonts}/{textshaping} 包准確地以像素為單位返回文本的大小,這當然取決於設備/分辨率。

systemfonts::string_width("My label")
#> [1] 46
textshaping::text_width("My label")
#> [1] 46

據我所知ggplot2知道geom_text繪制的標簽的尺寸。 否則, check_overlap選項將不起作用。

這些維度存儲在哪里,如何訪問它們?


說明性的例子

library(ggplot2)
df <- data.frame(x = c(1, 2), 
                 y = c(1, 1), 
                 label = c("label-one-that-might-overlap-another-label", 
                           "label-two-that-might-overlap-another-label"), 
                 stringsAsFactors = FALSE)

如果check_overlap = FALSE (默認值),則標簽會相互check_overlap = FALSE

ggplot(df, aes(x, y)) + 
  geom_text(aes(label = label)) + 
  xlim(0, 3)                              

在此處輸入圖片說明

如果check_overlap = TRUE ,則不會繪制第二個標簽,因為ggplot發現重疊。

ggplot(df, aes(x, y)) + 
  geom_text(aes(label = label), check_overlap = TRUE) + 
  xlim(0, 3)

在此處輸入圖片說明

ggplot2如何知道這些標簽重疊? 我如何訪問該信息?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM