使用 PNG/JPEG 张图片创建多面板图形
Create multi-panel figure using PNG/JPEG images
问题:
我想使用 PNG 或 JPEG 图像制作多面板图形。这些图像不是在 R 中创建的,但我想在 R 中将它们拼接在一起以形成一个图形。所有图片都一样size/dimensions.
我试过的:
library(png)
img1 <- readPNG("filepath/img1.png")
img2 <- readPNG("filepath/img2.png")
library(patchwork)
patch <- img1 + img2
patch
当我 运行 这样做时,出现以下错误:
[ reached getOption("max.print") -- omitted 3 matrix slice(s) ]
我多次增加了最大打印量(高得离谱):
options(maxprint = 1000000000000)
但还是报同样的错误
然后我尝试使用以下方法将每个图像制作成一个 ggplot(没有点):
library(ggplot2)
img1plot <- ggplot() +
background_image(img1) +
theme(plot.margin = margin(t=1, l=1, r=1, b=1, unit = "cm"))
其中returns出现以下错误:
Error in background_image(d311) :
could not find function "background_image"
有没有其他方法可以在 R 中将图像拼接在一起以制作图形?
编辑:
根据@davidnortes 的评论,我尝试了以下操作:
p1 <- ggplot2::annotation_custom(grid::rasterGrob(img1,
width=ggplot2::unit(1,"npc"),
height=ggplot2::unit(1,"npc")),
-Inf, Inf, -Inf, Inf)
p2 <- ggplot2::annotation_custom(grid::rasterGrob(img2,
width=ggplot2::unit(1,"npc"),
height=ggplot2::unit(1,"npc")),
-Inf, Inf, -Inf, Inf)
library(cowplot)
plots <- plot_grid(
p1, p2,
labels = c('A', 'B'),
align="hv"
)
plots
我收到以下警告消息,但情节没有形成:
Warning messages:
1: In as_grob.default(plot) :
Cannot convert object of class LayerInstanceLayerggprotogg into a grob.
2: In as_grob.default(plot) :
Cannot convert object of class LayerInstanceLayerggprotogg into a grob.
我给你几个我最常用的选择:
备选方案 1:ggplot2、网格和 cowplot.
的组合
您的每个 PNG 图像都可以使用以下方法嵌入到 ggplot 对象中:
ggplot2::ggplot() + ggplot2::annotation_custom(grid::rasterGrob(YourPNGimage,
width=ggplot2::unit(1,"npc"),
height=ggplot2::unit(1,"npc")),
-Inf, Inf, -Inf, Inf)
然后你可以使用cowplot::plot_grid()
来安排你的地块。
备选方案 2: 使用 magick 包。
该包依赖其自身的函数来读取图像,因此我们需要稍微调整一下您的代码:
img1 <- magick::image_read("filepath/img1.png")
img2 <- magick::image_read("filepath/img2.png")
然后使用像 magick::image_append(c(img1, img2))
这样的函数,您可以将它们组合起来。有关详细信息,请参阅 magick package documentation。
您还可以 rbind
图像数组。但由于它们是 3D (x,y,RGB),您必须使用 abind
包中的 abind
函数。 along=1 垂直绑定,2 水平绑定。
有效,因为图像大小相同。
img1 <- readPNG("filepath/img1.png")
img2 <- readPNG("filepath/img2.png")
img12 <- abind::abind(img1,img2,along=1)
png::writePNG(img12,"filepath/img12.png")
您可以使用 R 中的 magick 包来制作拼贴画。
# read the the png files into a list
pngfiles <-
list.files(
path = here::here("png_ouput_folder"),
recursive = TRUE,
pattern = "\.png$",
full.names = T
)
# read images and then create a montage
# tile =2 , means arrange the images in 2 columns
# geometry controls the pixel sixe, spacing between each image in the collage output.
magick::image_read(pngfiles) %>%
magick::image_montage(tile = "2", geometry = "x500+10+5") %>%
magick::image_convert("jpg") %>%
magick::image_write(
format = ".jpg", path = here::here(paste(name,"_collage.jpg",sep="")),
quality = 100
)
正如其他人所建议的那样,magick 包比使用 grobs 和相关的低级解决方案简单得多。 magick 很强大,但恕我直言,文档很差而且很循环。
但是,image_montage()
的页面中有一个简单的解决方案可以解决您的问题。最重要的参数是 geometry
规范,它控制“tiles”之间的间距。
library(magick)
input <- rep(logo, 12)
image_montage(input, geometry = 'x100+10+10', tile = '4x3', bg = 'pink', shadow = TRUE)
要完全没有间距,请使用 geometry = '0x100+0+0', shadow = FALSE"
。
问题:
我想使用 PNG 或 JPEG 图像制作多面板图形。这些图像不是在 R 中创建的,但我想在 R 中将它们拼接在一起以形成一个图形。所有图片都一样size/dimensions.
我试过的:
library(png)
img1 <- readPNG("filepath/img1.png")
img2 <- readPNG("filepath/img2.png")
library(patchwork)
patch <- img1 + img2
patch
当我 运行 这样做时,出现以下错误:
[ reached getOption("max.print") -- omitted 3 matrix slice(s) ]
我多次增加了最大打印量(高得离谱):
options(maxprint = 1000000000000)
但还是报同样的错误
然后我尝试使用以下方法将每个图像制作成一个 ggplot(没有点):
library(ggplot2)
img1plot <- ggplot() +
background_image(img1) +
theme(plot.margin = margin(t=1, l=1, r=1, b=1, unit = "cm"))
其中returns出现以下错误:
Error in background_image(d311) :
could not find function "background_image"
有没有其他方法可以在 R 中将图像拼接在一起以制作图形?
编辑:
根据@davidnortes 的评论,我尝试了以下操作:
p1 <- ggplot2::annotation_custom(grid::rasterGrob(img1,
width=ggplot2::unit(1,"npc"),
height=ggplot2::unit(1,"npc")),
-Inf, Inf, -Inf, Inf)
p2 <- ggplot2::annotation_custom(grid::rasterGrob(img2,
width=ggplot2::unit(1,"npc"),
height=ggplot2::unit(1,"npc")),
-Inf, Inf, -Inf, Inf)
library(cowplot)
plots <- plot_grid(
p1, p2,
labels = c('A', 'B'),
align="hv"
)
plots
我收到以下警告消息,但情节没有形成:
Warning messages:
1: In as_grob.default(plot) :
Cannot convert object of class LayerInstanceLayerggprotogg into a grob.
2: In as_grob.default(plot) :
Cannot convert object of class LayerInstanceLayerggprotogg into a grob.
我给你几个我最常用的选择:
备选方案 1:ggplot2、网格和 cowplot.
的组合您的每个 PNG 图像都可以使用以下方法嵌入到 ggplot 对象中:
ggplot2::ggplot() + ggplot2::annotation_custom(grid::rasterGrob(YourPNGimage,
width=ggplot2::unit(1,"npc"),
height=ggplot2::unit(1,"npc")),
-Inf, Inf, -Inf, Inf)
然后你可以使用cowplot::plot_grid()
来安排你的地块。
备选方案 2: 使用 magick 包。
该包依赖其自身的函数来读取图像,因此我们需要稍微调整一下您的代码:
img1 <- magick::image_read("filepath/img1.png")
img2 <- magick::image_read("filepath/img2.png")
然后使用像 magick::image_append(c(img1, img2))
这样的函数,您可以将它们组合起来。有关详细信息,请参阅 magick package documentation。
您还可以 rbind
图像数组。但由于它们是 3D (x,y,RGB),您必须使用 abind
包中的 abind
函数。 along=1 垂直绑定,2 水平绑定。
有效,因为图像大小相同。
img1 <- readPNG("filepath/img1.png")
img2 <- readPNG("filepath/img2.png")
img12 <- abind::abind(img1,img2,along=1)
png::writePNG(img12,"filepath/img12.png")
您可以使用 R 中的 magick 包来制作拼贴画。
# read the the png files into a list
pngfiles <-
list.files(
path = here::here("png_ouput_folder"),
recursive = TRUE,
pattern = "\.png$",
full.names = T
)
# read images and then create a montage
# tile =2 , means arrange the images in 2 columns
# geometry controls the pixel sixe, spacing between each image in the collage output.
magick::image_read(pngfiles) %>%
magick::image_montage(tile = "2", geometry = "x500+10+5") %>%
magick::image_convert("jpg") %>%
magick::image_write(
format = ".jpg", path = here::here(paste(name,"_collage.jpg",sep="")),
quality = 100
)
正如其他人所建议的那样,magick 包比使用 grobs 和相关的低级解决方案简单得多。 magick 很强大,但恕我直言,文档很差而且很循环。
但是,image_montage()
的页面中有一个简单的解决方案可以解决您的问题。最重要的参数是 geometry
规范,它控制“tiles”之间的间距。
library(magick)
input <- rep(logo, 12)
image_montage(input, geometry = 'x100+10+10', tile = '4x3', bg = 'pink', shadow = TRUE)
要完全没有间距,请使用 geometry = '0x100+0+0', shadow = FALSE"
。