Problème:
Je souhaite créer une figure multi-panneaux à l'aide d'images PNG ou JPEG. Les images n'ont pas été créées en R mais je souhaite les assembler en R pour former une seule figure. Toutes les images sont de la même taille / dimensions.
Ce que j'ai essayé:
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.
Lorsque je lance ceci, j'obtiens l'erreur suivante:
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
J'ai augmenté l'impression maximale plusieurs fois (à des nombres ridiculement élevés):
Error in background_image(d311) : could not find function "background_image"
Mais obtenez toujours la même erreur.
J'ai ensuite essayé de transformer chaque image en un ggplot (sans les points) en utilisant:
library(ggplot2) img1plot <- ggplot() + background_image(img1) + theme(plot.margin = margin(t=1, l=1, r=1, b=1, unit = "cm"))
Ce qui renvoie l'erreur suivante:
options(maxprint = 1000000000000)
Existe-t-il un autre moyen d'assembler des images dans R pour créer une figure?
Éditer:
Sur la base du commentaire de @davidnortes, j'ai essayé ce qui suit:
[ reached getOption("max.print") -- omitted 3 matrix slice(s) ]
Je reçois les messages d'avertissement suivants et l'intrigue ne se forme pas:
library(png) img1 <- readPNG("filepath/img1.png") img2 <- readPNG("filepath/img2.png") library(patchwork) patch <- img1 + img2 patch
3 Réponses :
Je vous donne les deux alternatives que j'utilise le plus:
Alternative 1 : combinaison de ggplot2, grid et cowplot .
Chacune de vos images PNG peut être intégrée dans un objet ggplot en utilisant:
img1 <- magick::image_read("filepath/img1.png") img2 <- magick::image_read("filepath/img2.png")
Ensuite, vous pouvez utiliser cowplot::plot_grid()
pour organiser vos parcelles.
Alternative 2: utiliser le package magick .
Le paquet compte sur ses propres fonctions pour lire les images, nous devons donc modifier un peu votre code:
ggplot2::ggplot() + ggplot2::annotation_custom(grid::rasterGrob(YourPNGimage, width=ggplot2::unit(1,"npc"), height=ggplot2::unit(1,"npc")), -Inf, Inf, -Inf, Inf)
Ensuite, en utilisant des fonctions comme magick::image_append(c(img1, img2))
vous pouvez les combiner. Consultez la documentation du package magick pour plus d'informations.
Merci, la deuxième option utilisant la magie a fonctionné! Cependant, la résolution est assez faible (96 dpi). Existe-t-il un moyen de spécifier la résolution (par exemple 300 dpi) comme dans ggsave?
Dans magick::image_write
vous avez des paramètres comme la density
et la quality
qui aident à spécifier les qualités de sortie. Bien qu'il soit possible que vous ne puissiez pas effectuer de rendus haute résolution à partir de fichiers PNG basse résolution. La qualité de l'entrée va configurer la qualité de la sortie; Voyons si quelqu'un sait mieux que moi à ce sujet :)
@ jl748795 regardez: stackoverflow.com/questions/56060625/...
Merci @davidnortes! J'ai importé des fichiers PNG de 300 dpi, donc théoriquement, la taille du fichier doit être supérieure à 96 dpi lorsqu'ils sont combinés. Mais utiliser "densité =" me permet de rendre compte de cela.
Encore une question, est-il possible de choisir le nombre de colonnes en utilisant cette fonction? Je ne peux trouver des informations que sur stack = TRUE, qui empile les photos verticalement plutôt qu'horizontalement, mais je veux avoir 3 colonnes
@ jl748795 vous allez probablement devoir définir autant d'objets que de colonnes (en utilisant image_append ), puis les ajouter complètement
Désolé, je voulais dire plusieurs lignes et colonnes (j'ai 7 photos au total), ce que je ne pense pas possible en fonction de mes recherches, alors je devrai peut-être trouver une autre solution
Je ne me suis pas expliqué alors. Je voulais dire que, comme solution de contournement, vous pouvez créer, par exemple, vos lignes en utilisant image_append () en les stockant en tant qu'objets d'image magick. Ensuite, vous empilez ces objets avec image_append (c (row1, row2, ..., row n), stack = TRUE)
@davidnortes, lorsque je convertis l'image png en objet ggplot, cela entraîne une perte de qualité? y a-t-il une meilleure façon de lire plusieurs images png et d'utiliser la fonction wrap_images
dans patchwork pour conserver des images de haute qualité? Ma réponse ci-dessous donne une image de haute qualité, mais l'ajout d'annotations de texte telles que des sous-titres dans un collage est compliqué avec la magie. La conversion de la pensée en ggplot donne un meilleur contrôle. Des suggestions à ce sujet?
J'ai regardé autour de moi et je dois te dire que, malheureusement, je n'ai pas (encore) de réponse pour toi
Vous pouvez également rbind
des tableaux d'images. Mais comme ils sont en 3D (x, y, RVB) , vous devez utiliser abind
fonction de abind
package. along = 1 pour lier verticalement, 2 horizontalement.
Fonctionne car l'image a la même taille.
img1 <- readPNG("filepath/img1.png") img2 <- readPNG("filepath/img2.png") img12 <- abind::abind(img1,img2,along=1) png::writePNG(img12,"filepath/img12.png")
Vous pouvez utiliser le package magick dans R pour faire un collage.
# 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 )
Désolé mec! il y avait un bug dans ma réponse avec ggplot2; c'est pourquoi vous avez des erreurs. Je le modifie maintenant