Chú thích văn bản trên từng khía cạnh riêng lẻ trong ggplot2


150

Tôi muốn chú thích một số văn bản trên khía cạnh cuối cùng của cốt truyện với đoạn mã sau:

library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ cyl)
p <- p + annotate("text", label = "Test", size = 4, x = 15, y = 5)
print(p)

nhập mô tả hình ảnh ở đây

Nhưng mã này chú thích văn bản trên mọi khía cạnh. Tôi sẽ đánh giá rất cao nếu bạn hướng dẫn tôi cách lấy văn bản chú thích chỉ trên một khía cạnh.


1
Tôi tin rằng điều này chưa được thực hiện , vì vậy tôi nghi ngờ bạn sẽ phải sử dụng phương pháp đã được thử và đúng để xây dựng khung dữ liệu với văn bản và một cột cho biến faceting.
joran

Câu trả lời:


143

Thông thường, bạn sẽ làm một cái gì đó như thế này:

ann_text <- data.frame(mpg = 15,wt = 5,lab = "Text",
                       cyl = factor(8,levels = c("4","6","8")))
p + geom_text(data = ann_text,label = "Text")

Nó sẽ hoạt động mà không chỉ định hoàn toàn biến nhân tố, nhưng có thể sẽ đưa ra một số cảnh báo:

nhập mô tả hình ảnh ở đây


2
Tôi dường như chạy vào một số nhãn mờ khi tôi cố gắng sử dụng geom lòng () trên cốt truyện của tôi. Đó là vấn đề tương tự được thảo luận ở đây ( Groups.google.com/forum/?fromgroups=#!topic/ggplot2/evsbeBT48M4 ) và đã được giải quyết bằng cách sử dụng chú thích ("văn bản", ...). Có ai khác nhận được nhãn mờ với geom lòng () không?
Margaret

6
@Margaret Thông thường, đó là vì bạn đã nhầm ggplot để vẽ một bản sao của mỗi nhãn cho mỗi hàng trong khung dữ liệu ban đầu của bạn (nhãn có các điểm, đường, v.v.). Lưu ý rằng tôi chuyển một khung dữ liệu riêng biệt geom_textchỉ với một hàng.
joran

3
Ok tôi hiểu rồi - Cảm ơn. Điều gì nếu bạn muốn đặt 3 nhãn khác nhau trên lô mặt của bạn? Tôi đã thử một khung dữ liệu với nhiều hàng như tôi có các mặt và các nhãn duy nhất trong mỗi hàng. Có lẽ tôi nên bắt đầu điều này như một câu hỏi riêng biệt.
Margaret

8
Cảm ơn giải pháp của bạn. Tôi đang tự hỏi nếu tôi cũng có thể làm điều này bằng cách sử dụng annotate()...?
phân cực

2
@ user3420448 Tương tự, bạn chỉ cần xác định giá trị cho từng biến faceting.
17:30

106

Đây là cốt truyện không có chú thích văn bản:

library(ggplot2)

p <- ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  facet_grid(. ~ cyl) +
  theme(panel.spacing = unit(1, "lines"))
p

cốt truyện không có chú thích văn bản

Hãy tạo một khung dữ liệu bổ sung để giữ các chú thích văn bản:

dat_text <- data.frame(
  label = c("4 cylinders", "6 cylinders", "8 cylinders"),
  cyl   = c(4, 6, 8)
)
p + geom_text(
  data    = dat_text,
  mapping = aes(x = -Inf, y = -Inf, label = label),
  hjust   = -0.1,
  vjust   = -1
)

vẽ với chú thích văn bản ở các cạnh

Ngoài ra, chúng tôi có thể chỉ định thủ công vị trí của từng nhãn:

dat_text <- data.frame(
  label = c("4 cylinders", "6 cylinders", "8 cylinders"),
  cyl   = c(4, 6, 8),
  x     = c(20, 27.5, 25),
  y     = c(4, 4, 4.5)
)

p + geom_text(
  data    = dat_text,
  mapping = aes(x = x, y = y, label = label)
)

vẽ với nhãn văn bản được định vị thủ công

Chúng tôi cũng có thể dán nhãn lô trên hai khía cạnh:

dat_text <- data.frame(
  cyl   = c(4, 6, 8, 4, 6, 8),
  am    = c(0, 0, 0, 1, 1, 1)
)
dat_text$label <- sprintf(
  "%s, %s cylinders",
  ifelse(dat_text$am == 0, "automatic", "manual"),
  dat_text$cyl
)
p +
  facet_grid(am ~ cyl) +
  geom_text(
    size    = 5,
    data    = dat_text,
    mapping = aes(x = Inf, y = Inf, label = label),
    hjust   = 1.05,
    vjust   = 1.5
  )

khía cạnh của hai biến

Ghi chú:

  • Bạn có thể sử dụng -InfInfđịnh vị văn bản ở các cạnh của bảng.
  • Bạn có thể sử dụng hjustvjustđể điều chỉnh văn bản biện minh.
  • Khung dữ liệu nhãn văn bản dat_textphải có một cột hoạt động với facet_grid()hoặc facet_wrap().

6
Câu trả lời này vượt trội hơn câu trả lời được chấp nhận (rõ ràng là sự khác biệt 5 năm giữa hai người) về cách rõ ràng bước qua từng bước. Cũng rõ ràng hơn và giải thích.
Brandon

1
Nếu bạn muốn thêm văn bản vào nhiều hàng, hãy đảm bảo rằng colnames()trong văn bản của bạn data.framekhớp với những dữ liệu bạn sắp vẽ.
Kots

Khi tôi thử làm điều này cho một trong những khía cạnh của mình, chú thích xuất hiện nhưng các điểm thực tế đã biến mất (hoặc bị che khuất?).
Ben G

Ben G, bạn có thể xem xét thực hiện một bài viết mới để chia sẻ mã và hình của bạn.
Kamil Slowikowski

35

Nếu bất cứ ai đang tìm kiếm một cách dễ dàng để gắn nhãn các khía cạnh cho các báo cáo hoặc ấn phẩm, gói egg( CRAN ) có các chức năng tag_facet()& tiện lợi tag_facet_outside().

library(ggplot2)

p <- ggplot(mtcars, aes(qsec, mpg)) + 
  geom_point() + 
  facet_grid(. ~ am) +
  theme_bw(base_size = 12)

# install.packages('egg', dependencies = TRUE)
library(egg)

Tag bên trong

Mặc định

tag_facet(p)

Lưu ý: nếu bạn muốn giữ văn bản dải và nền, hãy thử thêm strip.textstrip.background quay lại themehoặc xóa theme(strip.text = element_blank(), strip.background = element_blank())khỏi tag_facet()chức năng ban đầu .

tag_facet <- function(p, open = "(", close = ")", tag_pool = letters, x = -Inf, y = Inf, 
                      hjust = -0.5, vjust = 1.5, fontface = 2, family = "", ...) {

  gb <- ggplot_build(p)
  lay <- gb$layout$layout
  tags <- cbind(lay, label = paste0(open, tag_pool[lay$PANEL], close), x = x, y = y)
  p + geom_text(data = tags, aes_string(x = "x", y = "y", label = "label"), ..., hjust = hjust, 
                vjust = vjust, fontface = fontface, family = family, inherit.aes = FALSE) 
}

Căn chỉnh trên cùng bên phải và sử dụng chữ số La Mã

tag_facet(p, x = Inf, y = Inf, 
          hjust = 1.5,
          tag_pool = as.roman(1:nlevels(factor(mtcars$am))))

Căn lề dưới bên trái và sử dụng chữ in hoa

tag_facet(p, 
          x = -Inf, y = -Inf, 
          vjust = -1,
          open = "", close = ")",
          tag_pool = LETTERS)

Xác định thẻ của riêng bạn

my_tag <- c("i) 4 cylinders", "ii) 6 cyls")
tag_facet(p, 
          x = -Inf, y = -Inf, 
          vjust = -1, hjust = -0.25,
          open = "", close = "",
          fontface = 4,
          size = 5,
          family = "serif",
          tag_pool = my_tag)

Tag bên ngoài

p2 <- ggplot(mtcars, aes(qsec, mpg)) + 
  geom_point() + 
  facet_grid(cyl ~ am, switch = 'y') +
  theme_bw(base_size = 12) +
  theme(strip.placement = 'outside')

tag_facet_outside(p2)

Chỉnh sửa : thêm một lựa chọn khác bằng cách sử dụng gói stickylabeller

- `.n` numbers the facets numerically: `"1"`, `"2"`, `"3"`...
- `.l` numbers the facets using lowercase letters: `"a"`, `"b"`, `"c"`...
- `.L` numbers the facets using uppercase letters: `"A"`, `"B"`, `"C"`...
- `.r` numbers the facets using lowercase Roman numerals: `"i"`, `"ii"`, `"iii"`...
- `.R` numbers the facets using uppercase Roman numerals: `"I"`, `"II"`, `"III"`...

# devtools::install_github("rensa/stickylabeller")
library(stickylabeller)

ggplot(mtcars, aes(qsec, mpg)) + 
  geom_point() + 
  facet_wrap(. ~ am, 
             labeller = label_glue('({.l}) am = {am}')) +
  theme_bw(base_size = 12)

Được tạo bởi gói reprex (v0.2.1)


2
Nguồn cho biết "Thêm một lớp văn bản giả để một ggplot đến khía cạnh nhãn và bộ Facet dải để trống." Ergo, nếu bạn có tùy chỉnh nhãn khía cạnh dải bạn không muốn để mất, chỉnh sửa kịch bản cho tag_facetbởi nixingstrip.text = element_blank()
CrunchyTopping

@CrunchyTopping Đây thực sự là chiếc mũ mà tôi đang tìm kiếm, nhưng dường như nó không hoạt động với tôi:Warning: Ignoring unknown parameters: strip.text
efrem

Để trả lời các vấn đề của tôi ở trên ... bài đăng này giải thích độc đáo cách giữ các dải: stackoverflow.com/a/56064130/3609450
efrem

22

Tôi nghĩ rằng đối với câu trả lời ở trên lab = "Văn bản" là vô ích, mã bên dưới cũng ok.

ann_text <- data.frame(mpg = 15,wt = 5,
                       cyl = factor(8,levels = c("4","6","8")))
p + geom_text(data = ann_text,label = "Text" )

Tuy nhiên, nếu bạn muốn gắn nhãn khác nhau trong các biểu đồ con khác nhau, sẽ ổn thôi theo cách này:

ann_text <- data.frame(mpg = c(14,15),wt = c(4,5),lab=c("text1","text2"),
                       cyl = factor(c(6,8),levels = c("4","6","8")))
p + geom_text(data = ann_text,aes(label =lab) )

7
Bạn nên giải thích sâu sắc những gì giải pháp của bạn cung cấp so với câu trả lời đã được đưa ra và được chấp nhận.
Sói Sascha

3
Cảm ơn, điều này rất hữu ích cho việc ghi nhãn các biểu đồ con khác nhau.
Deathkill14

Vì một số lý do, khi tôi làm điều này, nó thêm các mặt (trống) cho các yếu tố xi lanh = 2 và xi lanh = 3.
emudrak

6

Mở rộng một chút về câu trả lời tuyệt vời của joran, để làm rõ cách thức hoạt động của khung dữ liệu nhãn.

Bạn có thể nghĩ "mpg" và "wt" tương ứng là tọa độ x và y (tôi thấy việc theo dõi tên biến ban đầu dễ dàng hơn so với đổi tên chúng, như trong câu trả lời cũng rất xuất sắc của Kamil). Bạn cần một hàng cho mỗi nhãn và cột "hình trụ" hiển thị khía cạnh mà mỗi hàng được liên kết với.

ann_text<-data.frame(mpg=c(25,15),wt=c(3,5),cyl=c(6,8),label=c("Label 1","Label 2"))

ann_text
>  mpg wt cyl  label
>  25  3   6   Label 1
>  15  5   8   Label 2

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ factor(cyl))
p + geom_text(data = ann_text,label=ann_text$label)

âm mưu với nhãn


2

Tôi không biết về egggói, vì vậy đây là một ggplot2giải pháp gói đơn giản

library(tidyverse)
library(magrittr)
Data1=data.frame(A=runif(20, min = 0, max = 100), B=runif(20, min = 0, max = 250), C=runif(20, min = 0, max = 300))
Data2=data.frame(A=runif(20, min = -10, max = 50), B=runif(20, min = -5, max = 150), C=runif(20, min = 5, max = 200))
bind_cols(
Data1 %>% gather("Vars","Data_1"),
Data2 %>% gather("Vars","Data_2")
) %>% select(-Vars1) -> Data_combined
Data_combined %>%
  group_by(Vars) %>%
  summarise(r=cor(Data_1,Data_2),
            r2=r^2,
            p=(pt(abs(r),nrow(.)-2)-pt(-abs(r),nrow(.)-2))) %>%
  mutate(rlabel=paste("r:",format(r,digits=3)),
         plabel=paste("p:",format(p,digits=3))) ->
  label_df 
label_df %<>% mutate(x=60,y=190)
Data_combined %>%
  ggplot(aes(x=Data_1,y=Data_2,color=Vars)) +
  geom_point() + 
  geom_smooth(method="lm",se=FALSE) +
  geom_text(data=label_df,aes(x=x,y=y,label=rlabel),inherit.aes = FALSE) + 
  geom_text(data=label_df,aes(x=x,y=y-10,label=plabel),inherit.aes = FALSE) + 
    facet_wrap(~ Vars)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.