2014-01-26 3 views
17

Иногда полезно использовать технику добавления серого полупрозрачного слоя к изображению, а затем разрезать замочную скважину на этот слой, чтобы выделить определенную часть изображения ниже. Вот пример из youtube vide:Добавить прозрачное окно/замочную скважину ggplot2 (сетка)

enter image description here

Я делаю это с сюжетами, но иногда использовать Inkscape для добавления полупрозрачный слой, а затем использовать резинку, чтобы вырезать отверстие в этом слое. Это (а) выглядит менее профессиональным (б) требует дополнительного времени и отдельной программы и (в) возможной потери качества.

Я хочу сделать это в R. Я спрашиваю о ggplot2, потому что это мой инструмент выбора, но я думаю, что любой ответ на сетку был бы хорошим (я знаю, что база, вероятно, имеет совсем другой подход).

Так вот MWE, где я добавил geom_rect, чтобы показать, где мы хотим, чтобы сократить замочную скважину/окно:

ggplot(mtcars, aes(mpg, wt)) + 
    geom_point(size=3) +  
    geom_rect(mapping=aes(xmin=20, xmax=25, 
     ymin=3, ymax=3.3), color="black", alpha=.01) 

Как я могу использовать R, чтобы сделать сюжет, который выглядит примерно так это:

enter image description here

+0

Я не уверен, прямой-путь, но косвенным образом будет построить четыре прямоугольника вокруг отверстия. –

+0

Было бы здорово, если бы он вышел за пределы участка, иначе глаз был бы нарисован там –

+0

Вам не хотелось бы, чтобы ось была удобочитаемой? –

ответ

18

Оказывается, вы можете сделать это с помощью grid.path(...) в grid пакете. Прочитайте documentation, чтобы узнать, как создать путь с отверстием в нем.

library(gridExtra) 
library(ggplot2) 

ggp <- ggplot(mtcars, aes(mpg, wt)) + geom_point(size=3) 
grid.newpage() 
grid.draw(arrangeGrob(ggp)) 
grid.path(c(0,0,1,1,.48,.48,.62,.62), 
        c(0,1,1,0,.43,.50,.50,.43), 
        id=rep(1:2, each=4), 
        rule="evenodd",gp=gpar(fill="black", alpha=0.6)) 

NB: grid.draw(...) и grid.path(...) находятся в grid пакете; arrangeGrob(...) находится в пакете gridExtra. Загрузка gridExtra вызывает загрузку grid. Спасибо @MartinBel за предложение редактирования.

В ответ на комментарий @BrandonBertelsen: grid.path(...) агностик относительно формы; вам просто нужно предоставить координаты.

center <- c(x=0.55,y=0.48) 
r  <- 0.1 
circle <- do.call(rbind,lapply(seq(0,2*pi,length=36), 
           function(th)c(x=r*cos(th),y=r*sin(th)))) 
circle <- data.frame(circle) 
circle$x <- circle$x + center["x"] 
circle$y <- circle$y + center["y"] 

ggp <- ggplot(mtcars, aes(mpg, wt)) + geom_point(size=3) 
grid.newpage() 
grid.draw(arrangeGrob(ggp)) 
grid.path(c(0,0,1,1,circle[,1]), 
      c(0,1,1,0,circle[,2]), 
      id=c(1,1,1,1,rep(2,nrow(circle))), 
      rule="evenodd",gp=gpar(fill="black", alpha=0.6)) 

"круг" представляет собой эллипс из-за соотношения сторон окна Plot в.


Дальнейшее чтение: It’s Not What You Draw, It’s What You Don’t Draw Пол Murrell в R Journal

+2

+1, очень приятно найти –

+2

Все потрясающие отзывы. Я думаю, что этот был самым прямым. +1 –

+0

@MartinBel - Спасибо за предложение отредактировать. – jlhoward

7

Как насчет следующего?

P <- ggplot(mtcars, aes(mpg, wt)) + geom_point(size=3) 

## Set the limits for x & y 
xlims <- c(20, 25) 
ylims <- c(3, 3.3) 


# Where P is the original plot 
P + geom_rect(mapping=aes(xmin=-Inf, xmax=min(xlims), ymin=-Inf, ymax=+Inf), fill="black", alpha=.01) + 
    geom_rect(mapping=aes(xmin=min(xlims), xmax=+Inf, ymin=max(ylims), ymax=+Inf), fill="black", alpha=.01) + 
    geom_rect(mapping=aes(xmin=min(xlims), xmax=+Inf, ymin=-Inf, ymax=min(ylims)), fill="black", alpha=.01) + 
    geom_rect(mapping=aes(xmin=max(xlims), xmax=+Inf, ymin=min(ylims), ymax=max(ylims)), fill="black", alpha=.01) 

enter image description here

+2

Благодарим за отзыв. Это заставило мяч прокатиться. Для других поисковиков этот подход может быть именно тем, что им нужно. +1 –

5
require(ggplot2) 

#represent some tiles based on your axes (10 x 10, by 1) deoending on resolution you want 
alpha_tiles<-expand.grid(x=0:10,y=0:10,a=0.6) 

#set alpha to 0 for the coordinate 
alpha_tiles[alpha_tiles$x %in% 7:9 & alpha_tiles$y==7,]$a<-0 

qplot(0:10,0:10, size=10, color="red") + theme_bw() + 
    geom_raster(data=alpha_tiles,aes(x=x,y=y), alpha=alpha_tiles$a, fill="grey") 

enter image description here

или это для более полного ответа, который гасит весь сюжет:

require(ggplot2) 

#represent some tiles based on your axes (here 100 x 100, by 1) depending on resolution you want 
resolution<-100 
alpha_tiles<-expand.grid(x=0:resolution,y=0:resolution,a=0.6) 

#set alpha to 0 for the coordinates to highlight 
alpha_tiles[alpha_tiles$x %in% 40:70 & alpha_tiles$y %in% 70:80,]$a<-0 
alpha_tiles[alpha_tiles$x %in% 10:30 & alpha_tiles$y %in% 10:25,]$a<-0 

p<-qplot(0:10,0:10, size=10, color="red") + theme_bw() # background plot 


qplot(0:resolution,0:resolution,geom="blank") + theme(axis.line=element_blank(), 
            axis.text.x=element_blank(), 
            axis.text.y=element_blank(), 
            axis.ticks=element_blank(), 
            axis.title.x=element_blank(), 
            axis.title.y=element_blank(), 
            legend.position="none", 
            panel.background=element_blank(), 
            panel.border=element_blank(), 
            panel.grid.major=element_blank(), 
            panel.grid.minor=element_blank(), 
            plot.background=element_blank()) + 
    annotation_custom(ggplotGrob(p),0,resolution,0,resolution) + 
geom_raster(data=alpha_tiles,aes(x=x,y=y), alpha=alpha_tiles$a, fill="grey") 

enter image description here

+0

Спасибо за ваши идеи. Я собирался проверить это, когда увидел ответ на основе координаты от jlhoward. +1 –

Смежные вопросы