ggplot2의 개별 패싯에 텍스트 주석 달기


150

플롯의 마지막 패싯에 다음 코드를 사용하여 텍스트에 주석을 달고 싶습니다.

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)

여기에 이미지 설명을 입력하십시오

그러나이 코드는 모든 패싯의 텍스트에 주석을 답니다. 주석이 달린 텍스트를 한 패싯에만 얻는 방법을 안내해 주시면 대단히 감사하겠습니다.


1
나는 이것이 아직 구현되지 않았다고 생각하므로 텍스트가있는 데이터 프레임과 패싯 변수의 열을 구성하는 시도되고 진정한 방법에 의지해야한다고 생각합니다.
joran

답변:


144

일반적으로 다음과 같은 작업을 수행합니다.

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

factor 변수를 완전히 지정하지 않아도 작동하지만 경고가 발생할 수 있습니다.

여기에 이미지 설명을 입력하십시오


2
패싯 플롯에서 geom_text ()를 사용하려고 할 때 흐릿한 레이블이 표시되는 것 같습니다. 여기서 논의 된 것과 동일한 문제 ( groups.google.com/forum/?fromgroups=#!topic/ggplot2/evsbeBT48M4 )이며 annotate ( "text", ...)를 사용하여 해결되었습니다. 다른 사람이 geom_text ()로 흐릿한 레이블을 얻습니까?
Margaret

6
@Margaret 일반적으로, ggplot에게 원래 데이터 프레임의 모든 행 (점, 선 등이있는 행)마다 각 레이블의 복사본을 플로팅하도록 실수로 지시했기 때문입니다. geom_text단 하나의 행 으로 별도의 데이터 프레임을 전달합니다 .
joran February

3
그래, 고마워 패싯 플롯에 3 개의 다른 레이블을 붙이려면 어떻게해야합니까? 필자는 패싯 수만큼 행과 각 행에 고유 레이블이있는 데이터 프레임을 시도했습니다. 어쩌면 나는 이것을 별도의 질문으로 시작해야 할 것입니다.
Margaret

8
솔루션 주셔서 감사합니다. annotate()...을 사용 하여이 작업을 수행 할 수 있는지 궁금합니다 .
편광

2
@ user3420448 마찬가지로 각 패싯 변수의 값을 지정하기 만하면됩니다.
joran

107

텍스트 주석이없는 플롯은 다음과 같습니다.

library(ggplot2)

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

텍스트 주석이없는 플롯

텍스트 주석을 담을 추가 데이터 프레임을 만들어 봅시다 :

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
)

모서리에 텍스트 주석이있는 플롯

또는 각 라벨의 위치를 ​​수동으로 지정할 수 있습니다.

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

수동으로 배치 된 문자 레이블이있는 플롯

또한 두 패싯에 걸쳐 플롯에 레이블을 지정할 수도 있습니다.

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
  )

두 변수에 의한 패싯

노트:

  • 당신은 사용할 수 있습니다 -InfInf패널의 가장자리에 텍스트를 배치합니다.
  • 텍스트 자리 맞추기를 사용 hjust하고 vjust조정할 수 있습니다 .
  • 텍스트 레이블 데이터 프레임은 dat_text당신과 함께 작동하는 열이 있어야 facet_grid()또는 facet_wrap().

6
이 답변은 각 단계를 얼마나 명확하게 진행하는지에 대한 허용 된 답변 (두 개 사이의 5 년 차이)보다 우수합니다. 또한 더 명확하고 설명합니다.
Brandon

1
당신이 여러 행에 텍스트를 추가 할 경우, 반드시 당신의 것을 확인 colnames()텍스트의는 data.frame당신이 음모에 대해있는 데이터의 일치.
Kots

패싯 중 하나에 대해이 작업을 시도하면 주석이 표시되지만 실제 포인트는 사라집니다 (또는 가려져 있습니까?).
Ben G

벤 G, 당신은 당신의 코드와 그림을 공유하기 위해 새로운 게시물을 만드는 것을 고려할 수 있습니다.
Kamil Slowikowski

36

누군가가 보고서 나 출판물에 대한 라벨면에 쉬운 방법을 찾고있는 경우, egg( CRAN ) 패키지는 꽤 멋진있다 tag_facet()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_facet(p)

참고 : 스트립 텍스트와 배경을 유지 하려면 원래 기능을 다시 추가 strip.text하거나strip.background 다시 theme제거하십시오 .theme(strip.text = element_blank(), strip.background = element_blank())tag_facet()

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

오른쪽 상단 정렬 및 로마 숫자 사용

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

왼쪽 아래 정렬 및 대문자 사용

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

나만의 태그 정의

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)

외부 태그

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)

편집 : 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)

에 의해 생성 reprex 패키지 (v0.2.1)


2
소스 "를 추가 라벨면에 ggplot에 더미 텍스트 레이어와 세트 빈에 스트립을 패싯."라고 당신이있는 경우에 인체 공학적는, 사용자 정의면 레이블을 편집, 당신은 잃고 싶지 않아위한 스크립트를 제거합니다 tag_facetnixing에 의해strip.text = element_blank()
CrunchyTopping

@CrunchyTopping 이것은 실제로 내가 찾고있는 모자 였지만 나를 위해 작동하지 않는 것 같습니다 :Warning: Ignoring unknown parameters: strip.text
efrem

1
: 위의 내 문제에 대답하기 위해 ...이 게시물은 멋지게 스트립을 유지하는 방법에 대해 설명합니다 stackoverflow.com/a/56064130/3609450
에프 렘

22

lab = "Text"위의 대답은 쓸모 없다고 생각합니다. 아래 코드도 괜찮습니다.

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

그러나 다른 하위 그래프에서 다르게 레이블을 지정하려면 다음과 같이 확인하십시오.

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
이미 제공되고 수락 된 답변과 비교하여 솔루션이 제공하는 것을 깊이 설명해야합니다.
Sascha Wolf

3
감사합니다. 이것은 다른 하위 그래프에 레이블을 지정하는 데 유용했습니다.
Deathkill14

어떤 이유로, 내가 이것을 할 때, 요소 cyl = 2 및 cyl = 3에 대한 (빈) 패싯을 추가합니다.
emudrak

6

joran의 탁월한 답변을 약간 확장하여 레이블 데이터 프레임의 작동 방식을 명확히합니다.

"mpg"와 "wt"를 각각 x와 y 좌표로 생각할 수 있습니다 (Kamil의 탁월한 답변에서와 같이 이름을 바꾸는 것보다 원래 변수 이름을 추적하는 것이 더 쉽다는 것을 알았습니다). 라벨 당 하나의 행이 필요하며 "사이클"열에는 각 행이 연결된 패싯이 표시됩니다.

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)

레이블이있는 플롯


2

egg패키지 에 대해 몰랐 으므로 여기에 일반 ggplot2패키지 솔루션이 있습니다.

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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.