Vị trí nhãn điểm thông minh trong R


102

1) Có thư viện / chức năng R nào sẽ triển khai vị trí nhãn THÔNG MINH trong biểu đồ R không? Tôi đã thử một số nhưng chúng đều có vấn đề - nhiều nhãn đang chồng lên nhau hoặc các điểm khác (hoặc các đối tượng khác trong cốt truyện, nhưng tôi thấy rằng điều này khó xử lý hơn nhiều).

2) Nếu không, có cách nào để GIẢI ĐÁP giúp thuật toán sắp xếp nhãn cho các điểm có vấn đề cụ thể không? Giải pháp thoải mái và hiệu quả nhất mong muốn.

Bạn có thể chơi và kiểm tra các khả năng khác với ví dụ có thể tái tạo của tôi và xem liệu bạn có thể đạt được kết quả tốt hơn tôi có không:

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

Đối với việc dán nhãn, sau đó tôi đã thử những khả năng này, không có cái nào thực sự tốt:

1) cái này thật khủng khiếp:

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

2) Điều này là tốt nếu bạn không muốn đặt nhãn cho tất cả các điểm, mà chỉ cho các điểm ngoại lệ, tuy nhiên, các nhãn thường được đặt sai:

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

3) cái này trông có vẻ dễ chịu nhưng có vấn đề là các nhãn quá gần với các điểm; Tôi đã phải đệm chúng bằng khoảng trắng nhưng điều này không giúp được gì nhiều:

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)

Cảm ơn bạn trước!

CHỈNH SỬA: todo: thử labcurve {Hmisc} .


2
Rất tiếc, câu trả lời cho các câu hỏi R dường như được chia đều giữa StackOverflow và CrossValidated. Trong trường hợp này, câu hỏi là bản sao của một câu hỏi từ 4 ngày trước ở đó .
Ed Staub

3
Tôi gặp phải một vấn đề tương tự và đã viết một gói cơ bản sử dụng mô phỏng trường lực để điều chỉnh vị trí đối tượng. Mặc dù có thể cải thiện nhiều, bao gồm cả tích hợp với ggplot, v.v. thì nó dường như đã hoàn thành nhiệm vụ. Sau đây minh họa các chức năng. Nếu ai đó chạy vào vấn đề và tìm kiếm một câu trả lời, hy vọng đây sẽ là một số hỗ trợ:install.packages("FField") library(FField) FFieldPtRepDemo()
gregk

Tôi có thể yêu cầu bạn thử ggrepel ?
Kamil Slowikowski

@Joran thân mến, vui lòng đặt nhận xét của bạn "6) Đối với đồ thị ggplot2, có một tùy chọn mới gọi là ggrepel mà nhiều người có vẻ thích." trong một bình luận hoặc một câu trả lời. Ở đây tôi chỉ đưa vào danh sách các tùy chọn tôi đã thử nhưng không khả quan . Nếu nó là một cái gì đó hoạt động tốt thì nó phải là một câu trả lời.
TMS

Câu trả lời:


49

Đầu tiên, đây là kết quả của giải pháp của tôi cho vấn đề này:

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

Tôi đã làm điều này bằng tay trong Xem trước (trình xem PDF / hình ảnh rất cơ bản trên OS X) chỉ trong vài phút. ( Chỉnh sửa: Quy trình làm việc chính xác như những gì bạn mong đợi: Tôi đã lưu cốt truyện dưới dạng PDF từ R, mở nó trong Xem trước và tạo các hộp văn bản với các nhãn mong muốn (9pt Helvetica) và sau đó chỉ cần kéo chúng xung quanh bằng chuột cho đến khi chúng nhìn tốt. Sau đó, tôi đã xuất sang PNG để tải lên SO.)

Bây giờ, trước khi bạn chống lại sự thôi thúc mạnh mẽ để bỏ phiếu này vào quên lãng và để lại những bình luận gay gắt về cách quan điểm để tự động hóa quá trình này, hãy nghe tôi nói!

Tìm kiếm các giải pháp thuật toán là hoàn toàn ổn và (IMHO) thực sự thú vị. Tuy nhiên, đối với tôi, các tình huống gắn nhãn điểm rơi vào khoảng ba loại:

  1. Bạn có một số điểm nhỏ, không có điểm nào quá gần nhau . Trong trường hợp này, một trong những giải pháp bạn liệt kê trong câu hỏi có thể hoạt động với một số điều chỉnh khá nhỏ.
  2. Bạn có một số điểm nhỏ, một số điểm được đóng gói quá chặt chẽ để các giải pháp thuật toán điển hình đưa ra kết quả tốt . Trong trường hợp này, vì bạn chỉ có một số điểm nhỏ, việc gắn nhãn chúng bằng tay (bằng trình chỉnh sửa hình ảnh hoặc tinh chỉnh lệnh gọi của bạn text) không phải quá nhiều nỗ lực.
  3. Bạn có một số điểm khá lớn . Trong trường hợp này, bạn thực sự không nên dán nhãn chúng, vì rất khó để xử lý số lượng lớn các nhãn một cách trực quan.

: trèo lên hộp xà phòng:

Vì những người như chúng ta yêu thích tự động hóa, tôi nghĩ chúng ta thường rơi vào bẫy khi nghĩ rằng gần như mọi khía cạnh của việc tạo ra một đồ họa thống kê tốt đều phải được tự động hóa. Tôi kính cẩn (khiêm tốn!) Không đồng ý.

Không có môi trường lập biểu đồ thống kê tổng quát hoàn hảo nào có thể tự động tạo ra bức tranh mà bạn có trong đầu. Những thứ như R, ggplot2, lattice, v.v. thực hiện hầu hết công việc; nhưng một chút tinh chỉnh bổ sung, thêm một dòng ở đây, điều chỉnh một lề ở đó, có lẽ phù hợp hơn với một công cụ khác.

: trèo xuống từ hộp xà phòng:

Tôi cũng lưu ý rằng tôi nghĩ rằng tất cả chúng ta đều có thể tạo ra các biểu đồ phân tán với <10-15 điểm mà gần như không thể gắn nhãn rõ ràng, ngay cả bằng tay, và những điều này có thể sẽ phá vỡ bất kỳ giải pháp tự động nào mà ai đó đưa ra.

Cuối cùng, tôi muốn nhắc lại rằng tôi biết đây không phải là câu trả lời mà bạn đang tìm kiếm. Và tôi không nói rằng các nỗ lực thuật toán là vô ích hay ngu ngốc. Tôi đã bỏ phiếu cho câu hỏi này và sẽ vui vẻ tán thành các giải pháp thuật toán thú vị!

Lý do tôi đăng câu trả lời này là vì tôi nghĩ câu hỏi này phải là câu hỏi "ghi nhãn điểm trong R" chuẩn cho các bản sao trong tương lai và tôi nghĩ các giải pháp liên quan đến việc dán nhãn bằng tay xứng đáng có một chỗ ngồi trên bàn, vậy thôi.


10
Một cách thủ công khác là lưu âm mưu dưới dạng SVG và chỉnh sửa nó bằng Inkscape, sau đó tạo PDF từ đó.
Spacedman

Chào joran, cảm ơn câu trả lời của bạn. OK, tôi chấp nhận giải pháp này, mặc dù tôi nghĩ máy tính nên thực hiện điều này tốt nhất trước tiên VÀ SAU ĐÓ yêu cầu can thiệp thủ công. Ở đây tôi đang tìm kiếm giải pháp thoải mái và nhanh chóng nhất. Bạn có thể vui lòng mô tả cách bạn thực hiện âm mưu, từng bước? Những gì bạn đã tạo trong R, xuất, di chuyển nhãn trong Xem trước, v.v.?
TMS

1
@TomasT. Ồ, tôi hiểu rồi. Trong trường hợp đó tôi đã "lừa dối", đại loại. Tôi đã tạo một bản pdf có nhãn bằng một trong các phương pháp của bạn ở trên và một bản không có và sử dụng một bản có nhãn làm hướng dẫn.
joran

1
+1 Đây là một câu trả lời tuyệt vời. Một số giải thích về lý do tại sao xuất hiện trên meta-CV : xem các nhận xét ở đó.
whuber

1
Di chuyển một nhóm nhỏ các nhãn bằng tay có vẻ hợp lý, nhưng bạn cũng có thể tạo chúng tự động trước , sau đó di chuyển chúng. Bằng cách đó bạn đang tiết kiệm cho mình rất nhiều công việc, và cũng có thể làm giảm khả năng của mis-dán nhãn ...
naught101

42

ggrepelcó vẻ hứa hẹn khi được áp dụng cho các biểu ggplot2đồ phân tán.

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

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


10

Bạn đã thử gói directlabels chưa?

Và, BTW, các đối số pos và offset có thể lấy vectơ để cho phép bạn đưa chúng vào đúng vị trí khi có một số điểm hợp lý chỉ trong một vài lần chạy biểu đồ.


Có thể sử dụng gói directlabels với plot()cốt truyện bình thường không? Tôi đã không thành công khi cố gắng ... Cảm ơn! Tái bút: @SpacedMan & Ben, tôi đã xóa các bình luận của mình về bản cập nhật R, vì chúng không thú vị lắm - bạn cũng có thể làm như vậy.
TMS

6

Tôi đã tìm thấy một số giải pháp! Nó không phải là cuối cùng và lý tưởng không may, nhưng nó là thứ phù hợp nhất với tôi bây giờ. Nó là một nửa algoritmic, một nửa thủ công, vì vậy nó tiết kiệm thời gian so với giải pháp thủ công thuần túy được phác thảo bởi joran.

Tôi đã bỏ qua một phần rất quan trọng của sự ?identifytrợ giúp!

Thuật toán được sử dụng để đặt nhãn cũng giống như được sử dụng bởi văn bản nếu pos được chỉ định ở đó, sự khác biệt là vị trí của con trỏ so với điểm được xác định sẽ xác định pos trong nhận dạng.

Vì vậy, nếu bạn sử dụng identify()giải pháp như tôi đã viết trong câu hỏi của mình, thì bạn có thể tác động đến vị trí của nhãn bằng cách không nhấp trực tiếp vào điểm đó, mà bằng cách nhấp vào cạnh điểm đó tương đối theo hướng mong muốn !!! Hoạt động tuyệt vời!

Nhược điểm là chỉ có 4 vị trí (trên, trái, dưới, phải), nhưng tôi đánh giá cao hơn 4 vị trí còn lại (trên cùng bên trái, trên cùng bên phải, dưới cùng bên trái, dưới cùng bên phải) ... Vì vậy tôi sử dụng điều này để gắn nhãn các điểm mà nó không làm phiền tôi và phần còn lại của các điểm mà tôi gắn nhãn trực tiếp trong bản trình bày Powerpoint của mình, như joran đã đề xuất :-)

Tái bút: Tôi vẫn chưa thử giải pháp directlabels lattice / ggplot, tôi vẫn thích sử dụng thư viện cốt truyện cơ bản hơn.


4

Tôi khuyên bạn nên xem qua wordcloudgói. Tôi biết gói này tập trung không chính xác vào các điểm mà vào chính các nhãn, và phong cách cũng có vẻ khá cố định. Tuy nhiên, kết quả tôi nhận được từ việc sử dụng nó là khá tuyệt vời. Cũng lưu ý rằng phiên bản gói được đề cập đã được phát hành vào thời điểm bạn đặt câu hỏi, vì vậy nó vẫn còn rất mới.

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


3

Tôi đã viết một hàm R được gọi addTextLabels()trong một gói plotteR. Gói có thể được cài đặt trực tiếp vào thư viện R của bạn bằng đoạn mã sau:

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

Đối với ví dụ được cung cấp, tôi đã sử dụng mã sau để tạo hình ví dụ được liên kết bên dưới.

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

Nó hoạt động bằng cách tự động chọn một vị trí thay thế từ một lưới các điểm nhỏ. Các điểm gần nhất trên lưới được truy cập đầu tiên và được chọn nếu chúng không trùng lặp với bất kỳ điểm hoặc nhãn nào được vẽ trên đồ thị. Hãy nhìn vào các nguồn đang , nếu bạn quan tâm.

Hình ví dụ


2

Không phải là một câu trả lời, nhưng quá dài cho một bình luận. Một cách tiếp cận rất đơn giản có thể hoạt động trên các trường hợp đơn giản, ở đâu đó giữa quá trình xử lý hậu kỳ của joran và các thuật toán phức tạp hơn đã được trình bày là thực hiện in-placecác phép biến đổi đơn giản đối với khung dữ liệu.

Tôi minh họa điều này ggplot2bởi vì tôi quen thuộc với cú pháp đó hơn là các lô R cơ sở.

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)

Như bạn có thể thấy, trong trường hợp này, kết quả không phải là lý tưởng, nhưng nó có thể đủ tốt cho một số mục đích. Và nó khá dễ dàng, điển hình như thế này là đủwithin(df, y <- y+.01)

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


2
Thay vì sửa đổi dfcách sử dụng within, tôi thường làm điều này bằng cách điều chỉnh tính thẩm mỹ: geom_text(aes(x = x - .01, y = y + .01), hjust = 0, vjust = 0)có vẻ sạch hơn.
Gregor Thomas
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.