Membubuhi keterangan teks pada setiap aspek di ggplot2

150

Saya ingin membuat anotasi beberapa teks pada aspek terakhir plot dengan kode berikut:

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)

masukkan deskripsi gambar di sini

Tetapi kode ini membubuhi keterangan teks pada setiap sisi. Saya akan sangat menghargai jika Anda membimbing saya cara mendapatkan teks beranotasi hanya pada satu sisi.

MYaseen208
sumber
1
Saya percaya ini belum diimplementasikan , jadi saya curiga Anda harus menggunakan metode yang benar dan benar untuk membangun kerangka data dengan teks, dan kolom untuk variabel faceting.
joran

Jawaban:

144

Biasanya Anda akan melakukan sesuatu seperti ini:

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

Ini harus bekerja tanpa menentukan variabel faktor sepenuhnya, tetapi mungkin akan memberikan beberapa peringatan:

masukkan deskripsi gambar di sini

joran
sumber
2
Saya sepertinya menemukan beberapa label buram ketika saya mencoba menggunakan geom_text () pada plot faceted saya. Ini masalah yang sama yang dibahas di sini ( groups.google.com/forum/?fromgroups=#!topic/ggplot2/evsbeBT48M4 ), dan diselesaikan dengan menggunakan anotasi ("teks", ...). Apakah ada orang lain yang mendapatkan label buram dengan geom_text ()?
Margaret
6
@Margaret Biasanya, itu karena Anda keliru menyuruh ggplot untuk memplot setiap label pada setiap baris dalam bingkai data asli Anda (yang berisi titik, garis, dll.). Perhatikan bahwa saya meneruskan frame data terpisah geom_textdengan hanya satu baris.
joran
3
Ok, saya mengerti. Terima kasih. Bagaimana jika Anda ingin menempatkan 3 label berbeda pada plot faceted Anda? Saya mencoba bingkai data dengan baris sebanyak yang saya miliki, dan label unik di setiap baris. Mungkin saya harus memulai ini sebagai pertanyaan terpisah.
Margaret
8
Terima kasih atas solusinya. Saya ingin tahu apakah saya juga dapat melakukan ini menggunakan annotate()...?
mempolarisasi
2
@ user3420448 Hal yang sama, Anda hanya perlu menentukan nilai untuk setiap variabel faceting.
joran
106

Inilah plot tanpa anotasi teks:

library(ggplot2)

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

plot tanpa anotasi teks

Mari kita buat bingkai data tambahan untuk menahan anotasi teks:

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
)

plot dengan anotasi teks di tepinya

Atau, kita dapat menentukan posisi masing-masing label secara manual:

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

plot dengan label teks yang diposisikan secara manual

Kami juga dapat memberi label plot di dua sisi:

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
  )

segi oleh dua variabel

Catatan:

  • Anda dapat menggunakan -Infdan Infmemposisikan teks di tepi panel.
  • Anda dapat menggunakan hjustdan vjustuntuk menyesuaikan pembenaran teks.
  • Bingkai data label teks dat_textharus memiliki kolom yang berfungsi dengan Anda facet_grid()atau facet_wrap().
Kamil Slowikowski
sumber
6
Jawaban ini lebih unggul daripada jawaban yang diterima (jelas perbedaan 5 tahun antara keduanya) untuk seberapa jelas langkah itu melalui setiap langkah. Juga kejelasan dan penjelasan yang lebih besar.
Brandon
1
Jika Anda ingin menambahkan teks ke beberapa baris, pastikan colnames()teks Anda data.framecocok dengan data yang akan Anda plot.
Kots
Ketika saya mencoba melakukan ini untuk satu aspek saya, penjelasannya muncul tetapi poin yang sebenarnya hilang (atau dikaburkan?).
Ben G
Ben G, Anda mungkin mempertimbangkan untuk membuat posting baru untuk membagikan kode dan angka Anda.
Kamil Slowikowski
36

Jika ada yang mencari cara mudah untuk memberi label aspek untuk laporan atau publikasi, paket egg( CRAN ) cukup bagus tag_facet()& tag_facet_outside()fungsinya.

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)

Beri tag di dalam

Default

tag_facet(p)

Catatan: jika Anda ingin menyimpan teks strip dan latar belakang, coba tambahkan strip.textdanstrip.background kembali themeatau hapus theme(strip.text = element_blank(), strip.background = element_blank())dari tag_facet()fungsi aslinya .

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

Sejajarkan kanan atas & gunakan angka Romawi

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

Sejajarkan kiri bawah & gunakan huruf kapital

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

Tentukan tag Anda sendiri

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)

Tandai di luar

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)

Sunting : menambahkan alternatif lain menggunakan paket 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)

Dibuat oleh paket reprex (v0.2.1)

Tung
sumber
2
Sumber mengatakan "Menambahkan lapisan bodoh teks ke ggplot untuk aspek label dan set segi strip ke kosong." Ergo, jika Anda memiliki label segi kustom strip Anda tidak ingin kehilangan, mengedit naskah untuk tag_facetoleh nixingstrip.text = element_blank()
CrunchyTopping
@ CrunchyTopping Ini sebenarnya topi yang saya cari, tapi sepertinya tidak berfungsi untuk saya:Warning: Ignoring unknown parameters: strip.text
efrem
Untuk menjawab masalah saya di atas ... pos ini menjelaskan cara menjaga strip: stackoverflow.com/a/56064130/3609450
efrem
22

Saya pikir jawaban di atas lab = "Teks" tidak berguna, kode di bawah ini juga 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" )

Namun jika Anda ingin memberi label berbeda di berbagai sub-grafik, ini akan baik-baik saja dengan cara ini:

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) )
kdyhl
sumber
7
Anda harus menjelaskan secara mendalam apa yang ditawarkan solusi Anda sebagai perbandingan dengan jawaban yang sudah diberikan dan diterima.
Sascha Wolf
3
Terima kasih, ini berguna untuk memberi label berbagai sub-grafik.
Deathkill14
Untuk beberapa alasan, ketika saya melakukan ini, ia menambahkan aspek (kosong) untuk faktor cyl = 2 dan cyl = 3.
emudrak
6

Memperluas sedikit jawaban joran yang sangat baik, untuk memperjelas cara kerja label dataframe.

Anda dapat menganggap "mpg" dan "wt" masing-masing sebagai koordinat x dan y (saya merasa lebih mudah untuk melacak nama variabel asli daripada mengganti nama mereka, seperti dalam jawaban Kamil yang juga sangat bagus). Anda memerlukan satu baris per label, dan kolom "cyl" menunjukkan sisi mana yang dikaitkan dengan setiap baris.

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)

plot dengan label

John
sumber
2

Saya tidak tahu tentang eggpaket, jadi di sini adalah ggplot2solusi paket sederhana

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)
Erich Neuwirth
sumber