有没有办法可以在ggplot中绘制光栅注释,以指定角度旋转(不必须是90度的倍数)?特别是,我需要图像的比例不变。
我到目前为止所尝试的内容:基于问题How to rotate an image R raster我创建了一个旋转图像并将其保存为临时文件的函数(似乎是我唯一能够存储的图像由persp
创建的图片,然后将其加载到ggplot2::annotation_raster
。
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()
}
因为当角度接近45度时,在相同尺寸的画布内旋转图像会使图像缩小,我必须在旋转时将画布尺寸重新缩放cos(theta) + sin(theta)
倍。但是,当我将此缩放添加到png
函数时,我收到一个错误:
Error in png(filename = tmppath, width = side, height = side) :
invalid 'width' or 'height'
我会接受这个错误的解决方案,以帮助我修复我的凌乱黑客,但如果有一个更简洁的方法直接进入ggplot,那将更好。
答案 0 :(得分:0)
以下是我如何旋转地图,可能会稍微调整一下以解决您的问题?
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)
没有旋转物体
newak %>%
filter(long<0) %>%
ggplot() + geom_polygon(aes(long,lat,group=group),fill=8,color="black")
旋转物体
newak %>%
filter(long<0) %>%
ggplot() + geom_polygon(aes(newx,newy,group=group),fill=8,color="black")