2017-08-31 4 views
1

Existe-t-il un moyen de tracer une annotation raster dans un ggplot, pivoté selon un angle spécifié (pas nécessairement un multiple de 90 degrés)? En particulier, j'ai besoin de l'échelle de l'image pour apparaître inchangé. Ce que j'ai essayé jusqu'à présent: basé sur la question How to rotate an image R raster J'ai créé une fonction pour faire pivoter une image et l'enregistrer comme un fichier temporaire (semble être la seule chose que je peux faire pour stocker l'image créée par persp) , avec l'idée de le charger ensuite avec ggplot2::annotation_raster.Rotation de l'annotation raster ggplot2

raster_rotate <- function(img, theta, width) { 
    # only works with square imgs right now 
    theta <- theta %% 90 
    b <- cos(theta) + sin(theta) 

    x1 <- 0:ncol(img) 
    y1 <- 0:nrow(img) 
    z <- matrix(1, nrow = length(x1), ncol = length(y1)) 
    col_mat <- t(apply(matrix(rgb(getValues(img)/255), nrow=nrow(img), byrow=TRUE), 2, rev)) 

    tmppath = tempfile(pattern = "img", fileext = ".png", tmpdir = "tmp/imgrot") 
    side = round(b * width) 
    png(filename = tmppath, width = side, height = side) 
    persp(x1, y1, z, zlim = c(0, 2), theta = theta, phi = 90, 
     col = col_mat, scale = FALSE, border = NA, box = FALSE) 
    dev.off() 
} 

Du fait tourner l'image dans la même toile de taille apparaît pour rétrécir l'image que les angles approchent 45 degrés, je dois redimensionner la taille de la toile par un facteur de cos(theta) + sin(theta) que je tourne. Cependant, quand j'ajoute cette mise à l'échelle à la fonction png je reçois une erreur: Error in png(filename = tmppath, width = side, height = side) : invalid 'width' or 'height'

J'accepte une solution à cette erreur me aider à résoudre mon bidouille en désordre, mais s'il y a un moyen plus propre de le faire directement dans ggplot Ce serait encore mieux.

Répondre

0

Voici comment je fais tourner les cartes, peut-être que le peaufiner un peu va résoudre votre problème?

library(tidyverse) 
rotate.axis <- function(xy,theta){ 
     pimult <- (theta * 2 * pi)/360 
     newx <- c(cos(pimult), sin(pimult)) 
     newy <- c(-sin(pimult), cos(pimult)) 
     XY <- as.matrix(xy) %*% cbind(newx, newy) 
     as.data.frame(XY) 
} 

ak <- map_data('world','USA:Alaska') 

newd <- data.frame(longitude=ak$long, latitude=ak$lat) 
rotate <- rotate.axis(newd,30) 
newak <- bind_cols(ak,rotate) 

Aucune rotation de l'objet

newak %>% 
    filter(long<0) %>% 
    ggplot() + geom_polygon(aes(long,lat,group=group),fill=8,color="black") 

objet pivotée

newak %>% 
    filter(long<0) %>% 
    ggplot() + geom_polygon(aes(newx,newy,group=group),fill=8,color="black") 
+0

Je crains que non. Cette rotation de carte fonctionne parce que vous tracez l'objet cartographique sous forme de polygone, vous pouvez donc appliquer votre rotation comme une transformation des points. Mais une image raster est tracée différemment. – Empiromancer