0
votes

Créer une figure multi-panneaux à l'aide d'images PNG / JPEG

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


1 commentaires

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


3 Réponses :


1
votes

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.


10 commentaires

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



1
votes

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


0 commentaires

0
votes

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
      )


0 commentaires