2012-05-10 24 views
8

Tôi đang cố gắng tìm ra cách sử dụng grconvertX/grconvertX trong ggplot. Mục tiêu cuối cùng của tôi là thêm chú thích vào một hình ảnh ggplot2 (và có thể là mạng) với grid.textgrid.lines bằng cách chuyển từ tọa độ của người dùng sang tọa độ thiết bị. Tôi biết nó có thể được thực hiện với grobs nhưng tôi tự hỏi nếu có một cách dễ dàng hơn.Sử dụng grconvertX/grconvertY trong ggplot2

Đoạn mã sau cho phép tôi chuyển các giá trị từ tọa độ người dùng đến tọa độ thứ hai và sử dụng các giá trị đó để chú thích cốt truyện với grid.text.

graphics.off()  # close graphics windows 

library(grid) 
library(gridBase) 


test= data.frame(
    x = c(1,2,3), 
    y = c(12,10,3), 
    n = c(75,76,73) 
) 

par(mar = c(13,5,2,3)) 

plot(test$y ~ test$x,type="b", ann=F) 

for (i in 1:nrow(test)) 

{ 
    X=grconvertX(i , from="user", to="ndc") 
    grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif(X, 5)) )) 
    grid.lines(x=c(X, X), y = c(0.28, 0.33)) 
} 
#add some code to save as PDF ... 

enter image description here

Mã này được dựa trên các giải pháp từ một trong những bài viết trước đây của tôi: Mixing X and Y coordinate systems. Bạn có thể thấy cách x tọa độ từ cốt truyện ban đầu được chuyển thành ndc. Ưu điểm của phương pháp này là tôi có thể sử dụng thiết bị phối cho Y.

tôi cho rằng tôi có thể dễ dàng làm điều tương tự trong ggplot2 (và có thể trong lưới).

library(ggplot2) 
graphics.off()  # close graphics windows 

qplot(x=x, y=y, data=test)+geom_line()+ opts(plot.margin = unit(c(1,3,8,1), "lines")) 

for (i in 1:nrow(test)) 

{ 
    X=grconvertX(i , from="user", to="ndc") 
    grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif(X, 5)) )) 
    grid.lines(x=c(X, X), y = c(0.28, 0.33)) 
} 

#add some code to save as PDF... 

Tuy nhiên, nó không hoạt động chính xác. Các tọa độ dường như hơi lệch. Các đường thẳng đứng và văn bản không tương ứng với các nhãn đánh dấu trên ô. Ai có thể cho tôi biết làm thế nào để sửa chữa nó? Cảm ơn rất nhiều trước.

enter image description here

+0

Chỉ cần cập nhật, tôi đã chỉnh sửa một số định dạng trong câu hỏi của bạn để chúng phù hợp hơn với việc sử dụng đánh dấu "tiêu chuẩn" để đánh dấu mã.Ngoài ra, tốt nhất là không bao gồm các dòng xóa tất cả các đối tượng khỏi không gian làm việc của người dùng trong mã mà mọi người có khả năng nhanh chóng sao chép + dán. Để lại cho người đọc để đảm bảo rằng họ đang ở trong một phiên R sạch. – joran

+0

Cảm ơn! Tôi nghĩ sẽ dễ dàng hơn khi làm việc trong một buổi học sạch sẽ. Tôi sẽ không thêm mã này nữa. –

Trả lời

11

Các grconvertXgrconvertY chức năng làm việc với đồ họa cơ sở trong khi ggplot2 sử dụng đồ họa lưới. Nói chung, 2 công cụ đồ họa khác nhau không chơi độc đáo với nhau (mặc dù bạn đã chứng minh bằng cách sử dụng gridBase để trợ giúp). Ví dụ đầu tiên của bạn hoạt động vì bạn bắt đầu với một đồ họa cơ sở để hệ thống tọa độ người dùng tồn tại với biểu đồ cơ sở và grconvertX chuyển đổi từ nó. Trong trường hợp thứ hai hệ thống tọa độ người dùng không bao giờ được đặt trong đồ họa cơ sở, vì vậy có vẻ như nó có thể sử dụng các tọa độ mặc định là 0,1 tương tự nhưng không giống với tọa độ khung nhìn đầu để bạn có được một thứ tương tự nhưng không chính xác (Tôi thực sự ngạc nhiên khi bạn không nhận được lỗi hoặc cảnh báo

Thông thường đối với đồ họa lưới tương đương để chuyển đổi giữa các tọa độ là chỉ cần tạo chế độ xem mới với hệ tọa độ quan tâm (hoặc đẩy/bật đến chế độ xem hiện tại

Dưới đây là ví dụ tạo ra cốt truyện của bạn, sau đó chuyển xuống chế độ xem có chứa cốt truyện chính, tạo ra một chế độ xem mới có cùng kích thước nhưng với clipping tắt, quy mô x được dựa trên dữ liệu và quy mô y là 0,1, sau đó thêm một số văn bản cho phù hợp:

library(ggplot2) 
library(grid) 

test= data.frame( x = c(1,2,3), y = c(12,10,3), n = c(75,76,73) ) 

qplot(x=x, y=y, data=test)+geom_line()+ opts(plot.margin = unit(c(1,3,8,1), "lines")) 

current.vpTree() 
downViewport('panel-3-4') 
pushViewport(dataViewport(test$x, clip='off',yscale=c(0,1))) 

for (i in 1:nrow(test)) { 
    grid.text(x=i, y = -0.2, default.units='native', 
     label=paste("GRID.text at\nuser.x=", i, "\n" )) 
     grid.lines(x=c(i, i), y = c(-0.1, 0), default.units='native') 
} 

Một trong những điều khó khăn ở đây là ggplot2 không thiết lập quy mô viewport để phù hợp với dữ liệu được vẽ, nhưng chính bản thân các chuyển đổi. Trong trường hợp này, thiết lập quy mô dựa trên dữ liệu x đã làm việc, nhưng nếu ggplot2 làm điều gì đó huyền ảo thì điều này có thể không hoạt động. Những gì chúng tôi cần là một số cách để có được các tọa độ biến dạng ngược từ ggplot2 để sử dụng trong cuộc gọi đến grid.text.

+0

Greg: Cảm ơn bạn rất nhiều! Đây là một giải pháp tuyệt vời. Tôi đã áp dụng mã của bạn cho một biểu đồ khác và có vẻ như hoạt động tốt: http://stackoverflow.com/questions/10525957/how-to-draw-lines-outside-of-plot-area-in-ggplot2 –

+1

+ 1 'tikzDevice' đã đưa ra một số ý tưởng ban đầu để giải quyết khó khăn này. Họ đã định nghĩa các rãnh "giả" mới và geom_s liên quan với mục đích duy nhất để cung cấp một vị trí chính xác cho các đối tượng bên ngoài (các nút tikz). Tôi tự hỏi liệu ý tưởng này có thể được khái quát hóa hay không. – baptiste

Các vấn đề liên quan