adjust image size to ggplot2 grid - r

I need to plot over an image. The problem I have is that my PNG image doesn't adjust to grid:
library(webshot)
library(png)
webshot("http://www.doctormetrics.com/","doctor.png")
img <- readPNG("doctor.png")
dim(img)
x11()
g <- rasterGrob(img, interpolate=TRUE)
qplot(1:2, 1:2, geom="blank") +
annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
geom_point()

You could do
library(webshot)
library(png)
library(ggplot2)
library(grid)
webshot("http://www.doctormetrics.com/",tf<-tempfile(fileext = ".png"))
img <- readPNG(tf)
g <- rasterGrob(img, interpolate=TRUE, height = 1, width = 1)
ggplot() +
annotation_custom(g, xmin=1, xmax=2, ymin=1, ymax=2) +
geom_point(aes(x,y), data.frame(x=1:2, y=1:2)) +
coord_fixed(ratio = nrow(img)/ncol(img))

Related

ggplot2 & gridExtra: Reduce space between plots, but keep ylab of one plot

I would like to plot 3 graphics beside each other via the ggplot2 and gridExtra packages. The graphic on the left side has a ylab, the other 2 graphics do not. All three graphics should have the same size and the space between the graphics should be reduced as much as possible. However, due to the ylab of the graphic on the left side, I am either not able to reduce the space as much as I want; or I am cutting off the ylab.
Consider the following example in R:
library("ggplot2")
library("gridExtra")
# Example data
df <- data.frame(x = 1:10,
y = 1:10)
# Plots
ggp1 <- ggplot(df, aes(x, y)) +
geom_line() + theme_bw() +
ylab("Here is the ylab")
ggp2 <- ggplot(df, aes(x, y)) +
geom_line() + theme_bw() +
ylab("")
ggp3 <- ggplot(df, aes(x, y)) +
geom_line() + theme_bw() +
ylab("")
# Arrange grids
grid.arrange(ggp1, ggp2, ggp3, ncol = 3)
The space between the graphics should be reduced as much as possible.
All graphics should have the same size.
The ylab of the graphic on the left side should be kept.
I was trying to fix the problem with plot.margin, but unfortunately that didn't work.
I would suggest to cbind() the gtables, with the axis removed. null units automatically ensure equal panel widths.
lg <- lapply(list(ggp1,ggp2,ggp3),ggplotGrob)
rm_axis <- function(g){
lay <- g[["layout"]]
cp <- lay[lay$name == "panel",]
g[,-c(1:(cp$l-1))]
}
lg[-1] <- lapply(lg[-1], rm_axis)
grid::grid.draw(do.call(gtable_cbind, lg))
Adding theme (axis.title.y = element_blank()) to ggp2 and ggp3 will reduce the space between them.
library("ggplot2")
library("gridExtra")
# Example data
df <- data.frame(x = 1:10,
y = 1:10)
# Plots
ggp1 <- ggplot(df, aes(x, y)) +
geom_line() + theme_bw() +
ylab("Here is the ylab")
ggp2 <- ggplot(df, aes(x, y)) +
geom_line() + theme_bw() +
ylab("") + theme (axis.title.y = element_blank())
ggp3 <- ggplot(df, aes(x, y)) +
geom_line() + theme_bw() +
ylab("") + theme (axis.title.y = element_blank())
# Arrange grids
grid.arrange(ggp1, ggp2, ggp3, ncol = 3)

R - add transparency to rastergrob background of a ggplot

I'd like to add transparency to a rastergrob object used as a ggplot background.
Here is my code
library(ggplot2)
library(grid)
library(ggthemes)
reds <- c("brown", "red","orange","green","orange","red","brown","grey")
g <- rasterGrob(reds, width = unit(1, "npc"), height = unit(1,"npc"),interpolate = TRUE)
p <- ggplot(data = economics, aes(x = date, y = unemploy)) +
annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf)+
geom_line( alpha=1, color = "white", size = 0.5 ) +
xlab("Years") + ylab("Unemployed [thousands]") +
theme_base() +
theme(panel.background=element_blank(),
plot.background=element_blank(),
line = element_line(colour="white")) +
theme()
grid.newpage()
print(p, newpage = FALSE)
I could not add an alpha in the rastergrob , neither in annotation_custom. I've been searching for a while.
scales::alpha() is one option,
grid.newpage()
grid.text("background")
reds <- c("brown", "red","orange","green","orange","red","brown","grey")
grid.raster(scales::alpha(reds, 0.5), width = unit(1, "npc"), height = unit(1,"npc"),interpolate = TRUE)
I found out one possible way to do it is to use the function adjustcolor() that takes the parameter of transparency "alpha" And your list of colors and returns a list of transparent colors

How to add image to ggplot2 under the grid?

The most popular (and simplest) way to adding image to the ggplot2 graph is annotation_custom:
library(ggplot2)
library(png)
library(grid)
img <- readPNG(system.file("img", "Rlogo.png", package="png"), TRUE)
gpp <- rasterGrob(img, interpolate=TRUE)
gpp$width <- unit(1, "npc")
gpp$height <- unit(1, "npc")
df <- data.frame(x=seq(1,2,0.01),y=seq(1,2,0.01))
ggplot(df,aes(x=x,y=y)) +
annotation_custom(gpp, xmin=1, xmax=2.5, ymin=1, ymax=1.5) +
geom_point()
In this way, image will be placed over the scale grid.
How to place image under the grid, but with bindings to the coords, not to the borders of the plot?
It's possible in the development version of ggplot2.
How to install it see this answer: https://stackoverflow.com/a/9656182/4265407
Minimal working example:
library(devtools)
dev_mode(on=T)
library(ggplot2)
library(png)
library(grid)
img <- readPNG(system.file("img", "Rlogo.png", package="png"), TRUE)
gpp <- rasterGrob(img, interpolate=TRUE)
gpp$width <- unit(1, "npc")
gpp$height <- unit(1, "npc")
df <- data.frame(x=seq(1,2,0.01),y=seq(1,2,0.01))
ggplot(df,aes(x=x,y=y)) +
annotation_custom(gpp, xmin=1, xmax=2.5, ymin=1, ymax=1.5) +
geom_point() + theme(panel.ontop=TRUE,
panel.background = element_rect(colour = NA,fill="transparent"))

Label individual panels in a multi-panel ggplot2

I'm interested in trying to create simple corner labels for a multipanel figure I am preparing in ggplot. This is similar to this previously asked question, but the answers only explained how to include a label at the top of the plot, not produce a corner label in the format required by many journals. I hope to replicate something similar to the plotrix function corner.label() in ggplot2.
Here is an example using plottrix of what I would like to recreate in ggplot2.
require(plotrix)
foo1<-rnorm(50,25,5)
foo2<-rpois(50,25)
foo3<-rbinom(50,25,0.5)
foo4<-rnbinom(50,25,0.5)
par(mfrow=c(2,2))
hist(foo1)
corner.label(label='a',figcorner=T)
hist(foo2)
corner.label(label='b',figcorner=T)
hist(foo3)
corner.label(label='c',figcorner=T)
hist(foo4)
corner.label(label='d',figcorner=T)
This produces the following:
Thanks for any help in advance!
Two recent changes have made this a lot easier:
The latest release of ggplot2 has added the tag caption which can be used to label subplots.
The package patchwork makes it really easy to plot multiple ggplot objects. https://github.com/thomasp85/patchwork
This means that no altering of grobs is required. Adapting the reproducible example provided by Kev:
library(ggplot2)
# install.package("patchwork")
library(patchwork)
a <- 1:20
b <- sample(a, 20)
c <- sample(b, 20)
d <- sample(c, 20)
mydata <- data.frame(a, b, c, d)
myplot1 <- ggplot(mydata, aes(x=a, y=b)) + geom_point() + labs(tag = "A")
myplot2 <- ggplot(mydata, aes(x=b, y=c)) + geom_point() + labs(tag = "B")
myplot3 <- ggplot(mydata, aes(x=c, y=d)) + geom_point() + labs(tag = "C")
myplot4 <- ggplot(mydata, aes(x=d, y=a)) + geom_point() + labs(tag = "D")
myplot1 + myplot2 + myplot3 + myplot4
Extension: Changing Style:
If you want to change the labelling style, you can either set this individually for each plot or set a theme default. I would recommend the second approach. Add the following line before you build your plots to make the font bold and blue
ggplot2::theme_update(plot.tag = element_text(face = "bold", colour = "blue"))
For more information on customising the theme of ggplot2, see here.
I had the same problem and came up with the following solution, which is a bit different:
loading r packages
library(ggplot2)
library(grid)
library(gridExtra)
example data
a <- 1:20
b <- sample(a, 20)
c <- sample(b, 20)
d <- sample(c, 20)
create a data frame
mydata <- data.frame(a, b, c, d)
create example plots
myplot1 <- ggplot(mydata, aes(x=a, y=b)) + geom_point()
myplot2 <- ggplot(mydata, aes(x=b, y=c)) + geom_point()
myplot3 <- ggplot(mydata, aes(x=c, y=d)) + geom_point()
myplot4 <- ggplot(mydata, aes(x=d, y=a)) + geom_point()
set corner labels
myplot1 <- arrangeGrob(myplot1, top = textGrob("A", x = unit(0, "npc")
, y = unit(1, "npc"), just=c("left","top"),
gp=gpar(col="black", fontsize=18, fontfamily="Times Roman")))
myplot2 <- arrangeGrob(myplot2, top = textGrob("B", x = unit(0, "npc")
, y = unit(1, "npc"), just=c("left","top"),
gp=gpar(col="black", fontsize=18, fontfamily="Times Roman")))
myplot3 <- arrangeGrob(myplot3, top = textGrob("C", x = unit(0, "npc")
, y = unit(1, "npc"), just=c("left","top"),
gp=gpar(col="black", fontsize=18, fontfamily="Times Roman")))
myplot4 <- arrangeGrob(myplot4, top = textGrob("D", x = unit(0, "npc")
, y = unit(1, "npc"), just=c("left","top"),
gp=gpar(col="black", fontsize=18, fontfamily="Times Roman")))
plotting all plots on one page
grid.arrange(myplot1, myplot2, myplot3, myplot4, ncol = 2)
An example:
d <- data.frame(x = runif(16),
y = runif(16),
grp = rep(letters[1:4],each = 4))
ggplot(d,aes(x = x,y = y)) +
facet_wrap(~grp) +
geom_point() +
theme(strip.text = element_text(hjust = -0.05),
strip.background = element_blank())
Here's a solution using a custom labeller function. This doesn't invovle any manipulations to the data. Currently it only works with 1-dimensional facets (facet_wrap). I'm still working on how to increment along a 2-D grid...
Define the labeller function
make_labelstring <- function(mypanels) {
mylabels <- sapply(mypanels,
function(x) {LETTERS[which(mypanels == x)]})
return(mylabels)
}
label_panels <- ggplot2::as_labeller(make_labelstring)
Pass label_panels as the labeller to facet_wrap
library(ggplot2)
data("diamonds")
# create a faceted plot
ggplot(data = diamonds, aes(x = depth, y = price)) +
geom_point() +
facet_wrap(~cut, labeller = label_panels) +
theme(strip.text = element_text(hjust = -0),
strip.background = element_blank())

Set the scale in ggplot to be 1:1 in r

I would like to set the x and y axis in the following plot to have the same scale distance (i.e. 0.1 on the x axis is the same length as 0.1 on the y axis). Any advice? Thanks.
df <-data.frame(x = c(0,0.2,0.5), y = c(0.6,0.7,0.9))
p <-ggplot(df, aes(x, y, ymin=0, ymax=1, xmin=0, xmax=1))
p <- p + geom_point(alpha=2/10, shape=21, fill="blue", colour="black", size=5)
grid.arrange(p, p,ncol=1)
p
You need to use coord_equal()
df <-data.frame(x = c(0,0.2,0.5), y = c(0.6,0.7,0.9))
p <-ggplot(df, aes(x, y, ymin=0, ymax=1, xmin=0, xmax=1))
p <- p + geom_point(alpha=2/10, shape=21, fill="blue", colour="black", size=5)
p + coord_equal()
You need to set your width and height of your graphic device with height = 2*width
library('ggplot2')
library('gridExtra')
df <-data.frame(x = c(0,0.2,0.5), y = c(0.6,0.7,0.9))
p <-ggplot(df, aes(x, y, ymin=0, ymax=1, xmin=0, xmax=1))
p <- p + geom_point(alpha=2/10, shape=21, fill="blue", colour="black", size=5)
w <- 550
png("test.png", width=w, height=2*w, units="px")
grid.arrange(p, p,ncol=1)
dev.off()

Resources