I have below code which is based upon my earlier question. When I save the image SaveThisPlot.png, it creates unwanted background and the image size also changes (it reduces). How can i save the image such that the rotated part is of exactly same size as earlier (77 rows and 101 columns) and there is no background?
library(raster)
r1 <- brick(system.file("external/rlogo.grd", package="raster"))
r1
x <- crop(r1, extent(0,ncol(r1),0,nrow(r1)))
plotRGB(x)
x1 <- 0:ncol(x)
y1 <- 0:nrow(x)
z <- matrix(1, nrow=length(x1), ncol=length(y1))
col.mat <- t(apply(matrix(rgb(getValues(x)/255), nrow=nrow(x), byrow=TRUE), 2, rev))
# Rotate 45 degrees
persp(x1, y1, z, zlim=c(0,2), theta = 20, phi = 90,
col = col.mat, scale=FALSE, border=NA, box=FALSE)
png("SaveThisPlot.png")
persp(x1, y1, z, zlim=c(0,2), theta = 20, phi = 90,
col = col.mat, scale=FALSE, border=NA, box=FALSE)
dev.off()
You can use a transparent background, but rotating the plot will require re-sizing.
When you save your plot you can set
png("SaveThisPlot.png", bg="transparent")
to prevent a background from showing. Try:Notice if you try to do this with a rotated version of the logo, the logo is re-sized to fit within the 101 x 77 pixel png. If you want to rotate it and maintain the logo size, you'll have to resize the png, ass @RomanLuštrik mentioned in his comment. Re-sizing, if that is an option for you, is just a matter of trigonometry to find the appropriate height and width parameters.
You can try setting new heights and widths to save the png using some trigonometry. Here is an example with 35 degrees of rotation:
The overall image will be not be 77 x 101 pixels, but the logo itself should be the same size, though a bit rugged. For a smoother image, see the
rgl
answer below, but note that a transparent background isn't available forrgl
Alternative approach using the rgl package:
A different approach to producing the image might be better if the end goal is to maintain the size and smoothness of the image. You can try the
rgl
(R-to-OpenGL) package and thepersp3d
function, where you can rotate the plot within its window without re-sizing the window or altering the proportions of the logo. You can mostly use what you've already got, but the color matrix needs to be modified to work withpersp3d
:Then, set the scene, call
persp3d
, rotate it, and save.To force this image into a smaller window, you can manipulate the size of the rgl display window and the amount of background using a combination of the
windowRect
andzoom
parameters (See this question and answer, for example). However, a transparent background isn't an option withrgl
currently.I wasn't able to make the window any less than 124 pixels wide. It seems there is a minimum width of 124 pixels to an rgl window on my computer, as I can't make the window any smaller (i.e. can't collapse the minimize, restore, and close buttons on top of the window).
To get a transparent background, you could import these saved pngs, and assign alpha values of 1 to the background color ("#FF69B4"):
It turns out this method isn't perfect, and you may end up with a slight border on rotated images where the color isn't exactly "#FF00FF". You can address the border one way or another, if it is a problem for you, but it may not make a difference depending on the end goals. Try using
add.alpha[,,4][which(add.alpha[,,1] > .9 & add.alpha[,,3] > .9 & add.alpha[,,2] < .85 )] <- 0
beforewritePNG
If you don't want the image corners cut off like above, then use the trigonometry from earlier to help size the window properly within
par3d
: