在ggplot2中与背景PNG图像对齐点

4

我想创建一个点网格,对应于384孔板实验中的发光值。我将该板绘制为.png文件,并覆盖网格,以便每个点都应位于板的一个孔中。提供示例代码和数据。

使用 ggplot2 可以实现吗?

我正在使用以下代码(提供示例数据):

library(ggplot2)
library(png)
library(RCurl)
library(grid)

example.gg <- read.csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vRcX5aMZGCp9Bs3BRZSg8k4o-kbSjOO5z3LsRxgIv4qJHz1fG-Argruje32OuZ2Tt2qPaNGksGr4Jia/pub?output=csv",
            row.names = 1)
example.gg$Row <- factor(example.gg$Row, levels = rev(sort(unique(example.gg$Row))))

png.img <- readPNG(getURLContent("https://i.imgur.com/QeSO7d3.png"))
img.rg <- rasterGrob(png.img, interpolate=TRUE)

gp <- ggplot(example.gg,
             aes(x = Col, y = Row, col = Lum)) +
  annotation_custom(img.rg, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
  geom_point(shape = 15) + 
  theme_void()
gp

这是生成的图片:

在此输入图片描述

答案

感谢Dan Adams提供的原始答案。

gp <- ggplot(example.gg,
             aes(x = Col, y = Row, col = Lum)) +
  annotation_custom(img.rg, 
                    xmin = -2,
                    xmax = 27,
                    ymin = -1,
                    ymax = 18) +
  geom_point(shape = 15, size = 2.5) + 
  theme_void()
gp + coord_fixed(clip = "off") +
  theme(plot.margin = unit(c(3, 6, 5, 2), "lines"),
        legend.position = c(1.2, 0.5)) +
  scale_colour_gradientn(colours = pals::ocean.haline(100))

enter image description here


2
我会非常有冲动地在ggplot内完成这个任务。 - Allan Cameron
我的主要问题是我不知道如何正确地格式化geom_points()对象的边距,以控制形状的位置。 - Yuriy Grabovsky
1
一个可能有帮助的事情是使用coord_fixed()将X:Y比例设置为1。 - Dan Adams
2个回答

4
通过手动调整图像的位置,使用xmin/xmaxymin/ymax,使用coord_fixed(clip="off")固定行和列的间距,并在theme中扩展plot.margin,我成功地得到了一个看起来似乎可以工作的东西。
library(ggplot2)
library(png)
library(RCurl)
library(grid)

example.gg <- read.csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vRcX5aMZGCp9Bs3BRZSg8k4o-kbSjOO5z3LsRxgIv4qJHz1fG-Argruje32OuZ2Tt2qPaNGksGr4Jia/pub?output=csv",
            row.names = 1)
example.gg$Row <- factor(example.gg$Row, levels = sort(unique(example.gg$Row)))

png.img <- readPNG(getURLContent("https://i.imgur.com/QeSO7d3.png"))
img.rg <- rasterGrob(png.img, interpolate=TRUE)

gp <- ggplot(example.gg,
       aes(x = Col, y = Row, col = Lum)) +
  annotation_custom(
    img.rg,
    xmin = -2,
    xmax = 27,
    ymin = -1,
    ymax = 18
  ) +
  geom_point(shape = 15) +
  coord_fixed(clip = "off") +
  theme_void() +
  theme(plot.margin = unit(c(3, 2, 5, 2), "lines"))
  
gp

reprex package (v2.0.1)于2022-02-14创建


谢谢这个。它完美地运行了!我已经更新了原始评论以反映答案,并提供了最终图的示例。 - Yuriy Grabovsky
感谢您分享!作为一名湿实验生物学家,我一直在查看平板数据,因此我完全理解此处的需求。如果@Allan Cameron能够使用ggplot绘制出一个美观的384孔板图像,我会很高兴得到它,因为这将使每次调整以适应绘图变得更加容易,而不是一种hack。 - Dan Adams
如果整个过程可以作为单个自包含调用ggplot2,那将非常酷。 - Yuriy Grabovsky
1
我想我最好付诸行动。请看下面的答案,虽然我不认为它比现有的答案有任何改进,但很高兴能看到在ggplot中可以做些什么。 - Allan Cameron

4
我喜欢挑战,所以这里提供一个单独的ggplot调用的解决方案,而不需要依赖于任何png文件。
ggplot(example.gg, aes(factor(Col, levels = 1:24), Row, fill = Lum)) + 
  geom_tile(size = 6, color = "white") + 
  geom_label(label = "  ", fill = NA, label.padding = unit(0.3, "lines")) +
  annotation_custom(roundrectGrob(gp = gpar(fill = NA)), xmin = -2, 
                    xmax = 26, ymin = -1, ymax = 19) +
  annotation_custom(roundrectGrob(gp = gpar(fill = NA), r = unit(0.01, "npc")), 
                    xmin = 0.5, xmax = 24.5, ymin = 0.5, ymax = 16.5) +
  annotation_custom(polygonGrob(
    x = c(0.05, 0.99, 1, 1, 0.99, 0.05, 0, 0, 0.05), 
    y = c(0, 0, 0.01, 0.99, 1, 1, 0.9, 0.1, 0), gp = gpar(fill = NA)),
    xmin = -1.5, xmax = 25, ymin = 0, ymax = 18) +
  scale_fill_gradientn(colours = pals::ocean.haline(100)) +
  theme_void() + 
  coord_equal(clip = "off") +
  scale_x_discrete(expand = c(0.03, 0)) +
  guides(x = guide_axis(position = "top")) +
  theme(axis.text = element_text(size = 18),
        axis.text.x.top = element_text(size = 12),
        plot.margin = margin(20, 20, 20, 40),
        legend.box.margin =  margin(20, 20, 20, 40))

enter image description here


太棒了,这非常令人印象深刻!我会计划在未来使用它(并注明出处)!只是注意到y轴与OP所显示的相反。 - Dan Adams
哦,是的,我忘记在绘图之前颠倒了y变量的因子水平。 - Allan Cameron
经过重新检查,我认为你的是正确的。不确定为什么 OP 想要翻转它,以便 png 中的标签与原始数据不匹配。 - Dan Adams
我犯了一个错误,忘记修复因子水平 - 现在已经在问题代码中进行了修改。 - Yuriy Grabovsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接