【问题标题】:Add a transparent window/keyhole ggplot2 (grid)添加透明窗口/锁孔 ggplot2(网格)
【发布时间】:2014-02-17 14:58:33
【问题描述】:

有时使用在图像中添加灰色半透明层然后在该层中切割一个锁孔以突出显示下面图像的特定部分的技术会很有帮助。这是来自youtube vide 的示例:

我有时会使用绘图来执行此操作,但使用 Inkscape 添加一个半透明图层,然后使用橡皮擦在该图层上切一个洞。这 (a) 看起来不够专业 (b) 需要额外的时间和单独的程序,以及 (c) 可能会降低质量。

我想在 R 中做。我在询问 ggplot2,因为这是我选择的工具,但我认为任何网格答案都会很好(我知道 base 可能有一个非常不同的方法)。

所以这是一个 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 绘制如下图:

【问题讨论】:

  • 我不确定直接方式,但间接方式是在孔周围绘制四个矩形。
  • 如果它也能走出情节区域就好了,否则眼睛会被吸引到那里
  • 您不希望轴可读吗?
  • 在我使用它的情况下不是。
  • 或许你可以使用annote_cusotmsimilar to here

标签: r ggplot2 r-grid


【解决方案1】:

事实证明,您可以使用 grid 包中的 grid.path(...) 执行此操作。阅读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))

注意: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))

由于绘图窗口的纵横比,“圆”是一个椭圆。


进一步阅读:It’s Not What You Draw, It’s What You Don’t Draw Paul Murrell 在 R 期刊中

【讨论】:

  • 所有很棒的回复。我认为这是最直接的。 +1
  • 这个grid.draw(arrangeGrob()) 习惯从何而来?一个简单的print() 似乎更适合绘制单个图。
  • 我很抱歉我从来没有给这个绿色支票。
【解决方案2】:

下面的呢?

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) 

【讨论】:

  • 感谢您的回复。这让球滚动起来。对于其他搜索者来说,这种方法可能正是他们所追求的。 +1
【解决方案3】:
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")

或者这个以获得更完整的答案,使整个情节空白:

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

【讨论】:

  • 感谢您的想法。当我看到来自 jlhoward 的基于坐标的响应时,我正要检查这一点。 +1
猜你喜欢
  • 1970-01-01
  • 2013-02-21
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
相关资源
最近更新 更多