R에서 지능형 포인트 라벨 배치


102

1) R 플롯에서 INTELLIGENT 라벨 배치를 구현하는 R 라이브러리 / 기능이 있습니까? 몇 가지를 시도했지만 모두 문제가 있습니다. 많은 레이블이 서로 겹치거나 다른 점 (또는 플롯의 다른 개체)이 겹칩니다. 그러나 이것이 처리하기가 훨씬 더 어렵다는 것을 알았습니다.

2) 그렇지 않은 경우 특정 문제 지점에 대한 레이블 배치와 함께 알고리즘을 편안하게 도울 수있는 방법이 있습니까? 가장 편안하고 효율적인 솔루션을 원했습니다.

재현 가능한 예제를 사용 하여 다른 가능성을 테스트하고 테스트 할 수 있으며 내가 가진 것보다 더 나은 결과를 얻을 수 있는지 확인할 수 있습니다.

# data
x = c(0.8846, 1.1554, 0.9317, 0.9703, 0.9053, 0.9454, 1.0146, 0.9012, 
0.9055, 1.3307)
y = c(0.9828, 1.0329, 0.931, 1.3794, 0.9273, 0.9605, 1.0259, 0.9542, 
0.9717, 0.9357)
ShortSci = c("MotAlb", "PruMod", "EriRub", "LusMeg", "PhoOch", "PhoPho", 
"SaxRub", "TurMer", "TurPil", "TurPhi")

# basic plot
plot(x, y, asp=1)
abline(h = 1, col = "green")
abline(v = 1, col = "green")

라벨링을 위해 다음 가능성을 시도했지만 아무도 정말 좋지 않습니다.

1) 이것은 끔찍합니다.

text(x, y, labels = ShortSci, cex= 0.7, offset = 10)

2) 모든 점에 레이블을 배치하지 않고 특이 치에 대해서만 레이블을 배치하는 것이 좋지만 여전히 레이블이 잘못 배치되는 경우가 많습니다.

identify(x, y, labels = ShortSci, cex = 0.7)

3) 이것은 유망 해 보이지만 레이블이 포인트에 너무 가깝다는 문제가 있습니다. 나는 그들을 공백으로 채워야했지만 이것은별로 도움이되지 않습니다.

require(maptools)
pointLabel(x, y, labels = paste("  ", ShortSci, "  ", sep=""), cex=0.7)

4)

require(plotrix)
thigmophobe.labels(x, y, labels = ShortSci, cex=0.7, offset=0.5)

5)

require(calibrate)
textxy(x, y, labs=ShortSci, cx=0.7)

미리 감사드립니다!

편집 : 할 일 : labcurve {Hmisc} 시도 하십시오 .


2
R 질문에 대한 답변은 불행히도 StackOverflow와 CrossValidated간에 균등하게 분할되는 것 같습니다. 이 경우 질문은 저기 4 일 전의 질문입니다 .
Ed Staub 2011 년

3
비슷한 문제가 발생하여 역장 시뮬레이션을 사용하여 물체 위치를 조정하는 기본 패키지를 작성했습니다. ggplot과의 통합 등 많은 개선이 가능하지만 작업을 완수하는 것 같습니다. 다음은 기능을 설명합니다. 누군가 문제가 발생하여 답변을 검색하면 도움이 될 것입니다.install.packages("FField") library(FField) FFieldPtRepDemo()
gregk

그그 레펠 을 시도해 시겠습니까?
Kamil Slowikowski

@Joran에게, "6) ggplot2 그래프의 경우 많은 사람들이 좋아하는 ggrepel이라는 새로운 옵션이 있습니다." 댓글이나 답변에서. 여기에 내가 시도한 옵션 목록 만 포함했지만 만족스럽지 않습니다 . 잘 작동하는 것이 있다면 답에 있어야합니다.
TMS

답변:


49

첫째,이 문제에 대한 내 솔루션의 결과는 다음과 같습니다.

여기에 이미지 설명 입력

미리보기 (OS X의 매우 기본적인 PDF / 이미지 뷰어)에서 몇 분만에이 작업을 수행했습니다. ( 편집 : 워크 플로는 예상했던 그대로였습니다. 플롯을 R에서 PDF로 저장하고 미리보기에서 열고 원하는 레이블 (9pt Helvetica)이있는 텍스트 상자를 만든 다음보기까지 마우스로 끌어다 놓았습니다. 좋아요. 그런 다음 업로드를 위해 PNG로 내보냈습니다.)

자, 당신이 이것을 망각으로 투표 하고이 과정을 자동화하는 방법에 대한 은밀한 의견을 남기려는 강한 충동에 굴복하기 전에 제 말을 들어주세요!

알고리즘 솔루션을 찾는 것은 완전히 괜찮고 (IMHO) 정말 흥미 롭습니다. 그러나 나에게 포인트 라벨링 상황은 대략 세 가지 범주로 나뉩니다.

  1. 당신은 적은 수의 포인트를 가지고 있지만 서로 매우 가깝습니다 . 이 경우 질문에 나열된 솔루션 중 하나는 최소한의 조정으로 작동 할 가능성이 높습니다.
  2. 적은 수의 포인트가 있으며, 그중 일부는 일반적인 알고리즘 솔루션이 좋은 결과를 제공하기에는 너무 밀집되어 있습니다. 이 경우 포인트 수가 적기 때문에 이미지 편집기를 사용하거나에 대한 호출을 미세 조정하여 수동으로 레이블을 지정하는 것은 그다지 힘들지 text않습니다 .
  3. 당신은 상당히 많은 포인트를 가지고 있습니다. 이 경우에는 많은 수의 레이블을 시각적으로 처리하기가 어렵 기 때문에 레이블을 지정하면 안됩니다.

: 비누 상자에 오르기 :

우리 같은 사람들이 있기 때문에 사랑 자동화, 나는 거의 좋은 통계 그래픽을 생산의 모든 측면을 자동화되어야한다 우리는 종종 사고의 함정에 빠지지 생각합니다. 나는 정중하게 (겸손하게!) 동의하지 않습니다.

머릿속에있는 그림을 자동으로 생성하는 완벽하게 일반적인 통계 플로팅 환경은 없습니다. R, ggplot2, lattice 등과 같은 것이 대부분 의 작업을 수행합니다. 하지만 약간의 조정, 여기에 선 추가, 여백 조정은 아마도 다른 도구에 더 적합 할 것입니다.

: 비누 박스에서 내려 오기 :

나는 또한 우리 모두가 손으로도 깔끔하게 레이블을 지정하는 것이 거의 불가능한 10-15 점 미만의 산점도를 생각 해낼 수 있다고 생각하며, 이는 누군가가 제시하는 자동 솔루션을 깨뜨릴 가능성이 높습니다.

마지막으로, 나는 것을 반복 할 알고 이것이 당신이 찾고있는 해답이 아니다. 그리고 알고리즘 시도가 쓸모 없거나 멍청하다는 말은 아닙니다 . 나는이 질문에 찬성 투표를했고, 흥미로운 알고리즘 솔루션을 기쁘게 찬성 할 것입니다!

이 답변을 게시 한 이유는이 질문이 향후 중복에 대한 표준 "R의 포인트 라벨링"질문이어야한다고 생각하기 때문이며 핸드 라벨링과 관련된 솔루션이 테이블에 앉을 자격이 있다고 생각합니다. 그게 전부입니다.


10
또 다른 수동 방법은 플롯을 SVG로 저장하고 Inkscape를 사용하여 편집 한 다음 그로부터 PDF를 생성하는 것입니다.
Spacedman 2011 년

안녕 조란, 답변 주셔서 감사합니다. 좋습니다. 컴퓨터가이 작업을 먼저 수행하고 수동 개입을 요청해야한다고 생각하지만이 솔루션을 수락합니다. 여기서는 가장 편안하고 빠른 솔루션을 찾고 있습니다. 어떻게 플롯을 만들 었는지 단계별로 설명해 주시겠습니까? R에서 생성 한 내용, 내보내기, 미리보기에서 레이블 이동 등?
TMS

1
@TomasT. 아, 알겠습니다. 그 경우에 나는 일종의 속임수를 쓴다. 위의 방법 중 하나를 사용하여 레이블이있는 PDF 하나를 생성하고 레이블이있는 PDF를 가이드로 사용했습니다.
joran

1
+1 이것은 훌륭한 답변입니다. meta-CV 에 나타나는 이유에 대한 설명 : 거기에있는 주석을 참조하십시오.
whuber 2011 년

1
작은 레이블 세트를 손으로 이동하는 것이 합리적으로 보이지만 먼저 자동으로 만든 다음 이동하는 것이 좋습니다. 이렇게하면 많은 작업을 절약 할 수 있고 라벨이 잘못 지정 될 가능성도 줄일 수 있습니다.
naught101

42

ggrepelggplot2산점도에 적용될 때 유망 해 보입니다 .

# data
x = c(0.8846, 1.1554, 0.9317, 0.9703, 0.9053, 0.9454, 1.0146, 0.9012, 
0.9055, 1.3307)
y = c(0.9828, 1.0329, 0.931, 1.3794, 0.9273, 0.9605, 1.0259, 0.9542, 
0.9717, 0.9357)
ShortSci = c("MotAlb", "PruMod", "EriRub", "LusMeg", "PhoOch", "PhoPho", 
"SaxRub", "TurMer", "TurPil", "TurPhi")


df <- data.frame(x = x, y = y, z = ShortSci)
library(ggplot2)
library(ggrepel)

ggplot(data = df, aes(x = x, y = y)) + theme_bw() + 

    geom_text_repel(aes(label = z), 
       box.padding = unit(0.45, "lines")) +

    geom_point(colour = "green", size = 3)

여기에 이미지 설명 입력


10

directlabels 패키지 를 사용해 보셨습니까 ?

그리고 BTW, pos 및 offset 인수는 벡터를 사용하여 몇 번의 플롯 실행에 합리적인 수의 점이있을 때 올바른 위치에 배치 할 수 있습니다.


directlabels 패키지를 정규 plot()플롯 과 함께 사용할 수 있습니까 ? 그렇게 시도하는데 성공하지 못했습니다 ... 감사합니다! 추신 : @SpacedMan & Ben, R 업데이트에 관한 내 댓글은별로 흥미롭지 않기 때문에 정리했습니다. 똑같이 할 수 있습니다.
TMS

6

해결책을 찾았습니다! 그것은 궁극적이고 이상적이지 않지만, 지금 나에게 가장 잘 작동하는 것입니다. 반 알고리즘, 반 수동이므로 joran이 스케치 한 순수한 수동 솔루션에 비해 시간이 절약됩니다.

나는 도움 매우 중요한 부분을 간과했습니다 !?identify

레이블을 배치하는 데 사용되는 알고리즘은 pos가 지정된 경우 텍스트에서 사용하는 것과 동일합니다. 차이점은 식별 된 지점과 관련된 포인터의 위치가 식별에서 pos를 결정한다는 것입니다.

따라서 identify()내 질문에서 작성한 솔루션 을 사용하면 해당 지점을 직접 클릭하지 않고 원하는 방향으로 상대적으로 해당 지점 옆을 클릭 하여 레이블 위치에 영향줄 수 있습니다 !!! 잘 작동합니다!

단점은 4 개의 위치 (위, 왼쪽, 아래, 오른쪽) 만 있다는 것입니다.하지만 나머지 4 개 (왼쪽 위, 오른쪽 위, 왼쪽 아래, 오른쪽 아래)는 더 감사하겠습니다. Joran이 제안한 것처럼 저와 Powerpoint 프레젠테이션에서 직접 레이블을 지정하는 나머지 포인트를 방해하지 않는 지점에 레이블을 지정하는 데 사용합니다. :-)

추신 : 아직 directlabels lattice / ggplot 솔루션을 사용 해보지 않았지만 여전히 기본 플롯 라이브러리를 사용하는 것을 선호합니다.


4

wordcloud패키지를 살펴 보시길 권합니다 . 이 패키지는 포인트가 아니라 라벨 자체에 초점을 맞추고 있으며 스타일도 다소 고정 된 것 같습니다. 그러나 여전히 그것을 사용하여 얻은 결과는 꽤 놀랍습니다. 또한 문제의 패키지 버전은 질문을했을 때 출시되었으므로 여전히 새로운 버전입니다.

http://blog.fellstat.com/?cat=11


3

addTextLabels()패키지 내에서 호출되는 R 함수를 작성했습니다 plotteR. 다음 코드를 사용하여 패키지를 R 라이브러리에 직접 설치할 수 있습니다.

install.packages("devtools")
library("devtools")
install_github("JosephCrispell/basicPlotteR")

제공된 예제의 경우 다음 코드를 사용하여 아래 링크 된 예제 그림을 생성했습니다.

# Load the plotteR library
library(plotteR)

# Create vectors storing the X and Y coordinates
x = c(0.8846, 1.1554, 0.9317, 0.9703, 0.9053, 0.9454, 1.0146, 0.9012, 
      0.9055, 1.3307)
y = c(0.9828, 1.0329, 0.931, 1.3794, 0.9273, 0.9605, 1.0259, 0.9542, 
      0.9717, 0.9357)

# Store the labels to be plotted in a vector
ShortSci = c("MotAlb", "PruMod", "EriRub", "LusMeg", "PhoOch", "PhoPho", 
             "SaxRub", "TurMer", "TurPil", "TurPhi")

# Plot the X and Y coordinates without labels
plot(x, y, asp=1)
abline(h = 1, col = "green")
abline(v = 1, col = "green")

# Add non-overlapping text labels
addTextLabels(x, y, ShortSci, cex=0.9, col.background=rgb(0,0,0, 0.75), 
              col.label="white")

미세한 포인트 그리드에서 대체 위치를 자동으로 선택하여 작동합니다. 그리드에서 가장 가까운 지점을 먼저 방문하고 플로팅 된 지점 또는 레이블과 겹치지 않는 경우 선택합니다. 관심이 있으시면 소스 코드를 살펴보십시오 .

예제 그림


2

답변은 아니지만 댓글이 너무 깁니다. joran의 사후 처리와 제시된보다 정교한 알고리즘 사이의 간단한 사례에서 작동 할 수있는 매우 간단한 접근 방식 in-place은 데이터 프레임에 대한 간단한 변환을 만드는 것 입니다.

ggplot2기본 R 플롯보다 해당 구문에 더 익숙하기 때문에 이것을 설명합니다 .

df <- data.frame(x = x, y = y, z = ShortSci)
library("ggplot2")
ggplot(data = df, aes(x = x, y = y, label = z)) + theme_bw() + 
    geom_point(shape = 1, colour = "green", size = 5) + 
    geom_text(data = within(df, c(y <- y+.01, x <- x-.01)), hjust = 0, vjust = 0)

보시다시피이 경우 결과는 이상적이지는 않지만 일부 목적에는 충분할 수 있습니다. 그리고 그것은 아주 쉽게, 일반적으로 이것과 같은 것으로 충분합니다within(df, y <- y+.01)

여기에 이미지 설명 입력


2
dfusing을 수정하는 대신 within미학을 조정하여이 작업을 수행하는 경우가 많습니다 geom_text(aes(x = x - .01, y = y + .01), hjust = 0, vjust = 0). 더 깔끔해 보입니다.
Gregor Thomas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.