2012-05-10 12 views
8

Estoy tratando de averiguar cómo usar grconvertX/grconvertX en ggplot. Mi objetivo final es añadir anotaciones a una figura ggplot2 (y posiblemente celosía) con grid.text y grid.lines yendo de usuario en coordenadas del dispositivo. Sé que se puede hacer con grobs, pero me pregunto si hay una manera más fácil.Uso de grconvertX/grconvertY en ggplot2

El siguiente código me permite pasar valores de usuario en coordenadas NDC y utilizar dichos valores para anotar la parcela con 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

El código se basa en la solución de uno de mis mensajes anteriores: Mixing X and Y coordinate systems. Puede ver cómo las coordenadas x del diagrama original se convirtieron a ndc. La ventaja de este enfoque es que puedo usar dispositivo coordenadas de Y.

asumí que fácilmente podría hacer lo mismo en ggplot2 (y posiblemente en celosía).

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

Sin embargo, no funciona correctamente. Las coordenadas parecen estar un poco desconectadas. Las líneas verticales y el texto no se corresponden con las etiquetas de tic en la gráfica. ¿Alguien puede decirme cómo solucionarlo? Muchas gracias por adelantado.

enter image description here

+0

Solo un aviso, he estado editando algunos formatos en sus preguntas para que quepan mejor con el uso "estándar" de marcado para resaltar el código.Además, es mejor no incluir líneas que eliminen todos los objetos del área de trabajo de un usuario en un código que las personas puedan copiar o pegar rápidamente. Deje que el lector se asegure de que estén en una sesión R limpia. – joran

+0

Gracias! Pensé que sería más fácil trabajar en una sesión limpia. No añadiré este código nunca más. –

Respuesta

11

Los grconvertX y grconvertY funciones trabajan con gráficos base mientras ggplot2 utiliza gráficos de rejilla. En general, los 2 motores gráficos diferentes no funcionan bien juntos (aunque usted ha demostrado que usa gridBase para ayudar). Su primer ejemplo funciona porque comenzó con un gráfico base, por lo que el sistema de coordenadas del usuario existe con el gráfico base y grconvertX lo convierte. En el segundo caso, el sistema de coordenadas del usuario nunca se estableció en los gráficos base, por lo que parece que podría usar las coordenadas predeterminadas de 0,1 que son similares pero no idénticas a las coordenadas de la vista superior para que pueda obtener algo similar pero no exactamente correcto (En realidad, me sorprende que no haya recibido un error o una advertencia

Generalmente, para gráficos en cuadrícula, el equivalente para convertir coordenadas es simplemente crear una nueva ventana gráfica con el sistema de coordenadas de interés (o pulsar/mostrar en una ventana gráfica existente) con el sistema de coordenadas correcto), luego agregue sus anotaciones en esa ventana.

Aquí hay un ejemplo que crea su trazado, luego se mueve hacia la ventana gráfica que contiene el trazado principal, crea una nueva ventana con las mismas dimensiones pero con recorte desactivado, la escala x se basa en los datos y la escala y es 0,1, a continuación, agrega un poco de texto en consecuencia:

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

Una de las cosas difíciles aquí es que ggplot2 no fija las escalas de ventana gráfica a coincide con los datos que se trazan, pero realiza las conversiones en sí. En este caso, establezca la escala en función de los datos x trabajados, pero si ggplot2 hace algo más elegante, es posible que esto no funcione. Lo que necesitaríamos es una forma de obtener las coordenadas transversales traseras de ggplot2 para usar en la llamada a grid.text.

+0

Greg: ¡Muchas gracias! Esta es una gran solución. Apliqué su código a un gráfico diferente y parece funcionar bien: http://stackoverflow.com/questions/10525957/how-to-draw-lines-outside-of-plot-area-in-ggplot2 –

+1

+ 1 'tikzDevice' ha presentado algunas ideas originales para sortear esta dificultad. Definieron nuevos grobs "ficticios" y geom_s asociados con el único propósito de proporcionar un posicionamiento exacto para los objetos externos (nodos tikz). Me pregunto si esta idea podría generalizarse. – baptiste