Saving grid.arrange plot with my function - r

I wrote a function for saving ggplots:
fun.save <- function(my.plot, my.plot.name, width, height){
name <- deparse(substitute(my.plot.name))
name <- paste(name, ".pdf", sep="")
cairo_pdf(name, width=width, height=height)
print(my.plot)
dev.off()
}
I used grid.arrange to create one plot from 2 others:
#create data frame
state <- c("USA", "Szwajcaria", "Kanada", "Japonia", "Korea Płd.", "Meksyk")
state <- as.factor(state)
gdp <- c(35, 30, 28, 26, 15, 9)
expenditure <- c(7.75, 8, 6, 6, 3.75, 1.5)
df.gdp <- data.frame(state, gdp, expenditure)
df.gdp$state <- factor(df.gdp$state, levels=df.gdp[order(df.gdp$gdp), "state"])
#create two bar plots
plot.tmp <- ggplot(df.gdp, aes(x=1, y=state)) +
geom_text(aes(label=state)) +
ggtitle("") +
ylab(NULL) +
scale_x_continuous(expand=c(0,0),limits=c(0.94, 1.065)) +
theme(axis.title=element_blank(),
panel.grid=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
panel.background=element_blank(),
axis.text.x=element_text(color=NA),
axis.ticks.x=element_line(color=NA),
plot.margin = unit(c(1,-1,1,-1), "mm"))
plot.gdp <- ggplot(data = df.gdp, aes(x = state, y = gdp)) +
xlab(NULL) +
geom_bar(stat = "identity") +
ggtitle("PKB na osobę (w tys. $)") +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank()) +
scale_y_reverse() +
coord_flip()
plot.exp <- ggplot(data = df.gdp, aes(x = state, y = expenditure)) +
xlab(NULL) +
geom_bar(stat = "identity") +
ggtitle("Roczny wydatek na studenta (w tys. $)") +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank() ) +
coord_flip()
#merge plots
plot.gdp <- ggplot_gtable(ggplot_build(plot.gdp))
plot.exp <- ggplot_gtable(ggplot_build(plot.exp))
plot.tmp<- ggplot_gtable(ggplot_build(plot.tmp))
I can save it in this way:
pdf("GnpexpBad.pdf", width=10, height=5)
grid.arrange(plot.gdp, plot.tmp, plot.exp, ncol=3, widths=c(0.35, 0.078, 0.35))
dev.off()
But I want to use my function to do it. I call my function:
myplot <- grid.arrange(plot.gdp, plot.tmp, plot.exp, ncol=3, widths=c(0.35, 0.078, 0.35))
fan.save(myplot, nameofmyplot, 10,5)
Unfortunately it doesn't work. Any idea how to rearrange function to make it work also for grid plots?

Related

R ggplot graph color gradient same for two different plots

Hello I am ploting two graph using ggplot for two different data sent and using viridis colour gradient. because of data two graph colour gradient are different so I wanted make it same can any one suggest me
data
https://drive.google.com/file/d/1HUbEQMjIS3ybYuKUaVXT9M_f4ZR-BQXt/view?usp=sharing
code what i used
library("viridis")
df=read.table("test.txt",sep='\t', header=TRUE)
df = data.frame(df)
#first data
df$log_mean=log(df$data1)
df$data3=log2(df$data3)
df$data2=log2(df$data2)
#second data
df$log_mean2=log(df$df1)
df$df3=log2(df$df3)
df$df2=log2(df$df2)
#plot1
p1=ggplot(df, aes(data3,data2),pch=19,cex=1.9)+
geom_point(aes(color =log_mean)) +
theme(legend.position = "top")+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
theme(text = element_text(size = 20, face="bold"))
#plot2
p2=ggplot(df, aes(df3,df2),pch=19,cex=1.9)+
geom_point(aes(color =log_mean2)) +
theme(legend.position = "top")+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
theme(text = element_text(size = 20, face="bold"))
#viridis color
p1+scale_color_viridis(option = "C")
p2+scale_color_viridis(option = "C")
This could be achieved by setting the same limits for the color scale in both plots.
Using mtcars as example dataset try this:
library(ggplot2)
library(dplyr)
mtcars1 <- filter(mtcars, cyl == 4)
mtcars2 <- filter(mtcars, cyl == 6)
p1 <- ggplot(mtcars1, aes(hp, mpg, color = mpg)) +
geom_point()
p2 <- ggplot(mtcars2, aes(hp, mpg, color = mpg)) +
geom_point()
p1 + scale_color_viridis_c(limits = c(18, 33))
p2 + scale_color_viridis_c(limits = c(18, 33))
Edit:
For your data you can use e.g.
p1 + scale_color_viridis(option = "C", limits = c(-1, 8))
p2 + scale_color_viridis(option = "C", limits = c(-1, 8))
which gives:

Ho to add the count values calculated in the geom_histogram on top of the bars in R

I'd like to add the count values calculated in the geom_histogram function on ggplot2. I've put the ggplot2 into a loop so I can produce multiple plots, in my case 30 but for ease, here is a dummy set for only four plots. Facet wrap didn't work as the geom density was pooling the data across all factors before calculating proportions, rather than within a factor/variable. To produce this plot, I've essentially mixed a whole bunch of code from various sources so credit to them.
library(dplyr)
library(ggplot2)
library(ggridges)
library(reshape2)
library(gridExtra)
#Make the data#
df.fact <- data.frame("A"=rnorm(400, mean = 350, sd=160),"B"=rnorm(400, mean = 300, sd=100), "C"=rnorm(400, mean = 200, sd=80), names=rep(factor(LETTERS[23:26]), 100))
df.test<-melt(df.fact, id.vars = "names", value.name = "Length2")
names(df.test)[names(df.test) =="variable"] <- "TSM.FACT"
#Create the plotlist##
myplots <- list()
#Loop for plots##
for(i in 1:(length(unique(df.test$names)))){
p1 <- eval(substitute(
ggplot(data=df.test[df.test$names == levels(df.test$names)[i],], aes(x=Length2, group=TSM.FACT, colour = TSM.FACT, fill=TSM.FACT)) +
geom_histogram(aes( y = stat(width*density)), position = "dodge", binwidth = 50, alpha =0.4, show.legend=T)+
ggtitle(paste0(levels(df.test$names)[i]))+
geom_density_line(stat="density", aes(y=(..count..)/sum(..count..)*50), alpha=0.3, size=0.5, show.legend=F) +
geom_vline(data=ddply(df.test[df.test$names == levels(df.test$names)[i],], ~ TSM.FACT, numcolwise(mean)), mapping=aes(xintercept = Length2, group=TSM.FACT, colour=TSM.FACT), linetype=2, size=1, show.legend=F) +
scale_y_continuous(labels = percent_format()) +
ylab("relative frequency") +
scale_color_manual(values= c("#00B2EE", "#1E90FF", "#104E8B")) +
scale_fill_manual(values= c("#00B2EE", "#1E90FF", "#104E8B")) +
theme_bw() + theme(
plot.title = element_text(lineheight=0.5, hjust= 0.5, size=10),
strip.text.y = element_text(hjust = 1, angle = 0),
strip.text.x = element_text(size=10, vjust = 0.9),
strip.text=element_text(margin = margin(t=0.3,r=1,b=0.3,l=1), size=8, debug = F, vjust=0.2),
strip.background = element_blank(),
axis.text.x = element_text(size=8, angle=0, vjust=0.2, margin = margin(t=0.3,r=0.1,b=0.3,l=0.1)),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
axis.line.x=element_line(colour="black"),
axis.line.y=element_line(colour="black"),
panel.grid.minor = element_blank(),
panel.border=element_blank(),
panel.background=element_blank(),
legend.position=(c(0.9,0.9)),
legend.title = element_blank(),
legend.key = element_blank()),
list(i = i)))
print(i)
print(p1)
myplots[[i]] <- p1
plot(p1)
}
#Join the plots
panelplot=grid.arrange(plotlist = myplots, grobs = myplots, shared.legend=T)
Unfortunately I am unable to reproduce your example. I can recommend adding a column that includes the sum of each bar (let's name it "Bar")
The required addition to the ggplot code then involves:
geom_text(aes(label = Bar), position = position_stack(vjust = 1)) +
The text height above the bar can be adjusted with vjust

How to put plots without any space using plot_grid?

I'm doing an arrangement of 2x2 plots. The plots share the same axis, so I want to put them together, e.g.
This code:
library(ggplot2)
library(cowplot)
Value <- seq(0,1000, by = 1000/10)
Index <- 0:10
DF <- data.frame(Index, Value)
plot <- ggplot(DF, aes(x = Index, y = Value)) +
geom_line(linetype = 2) +
theme(aspect.ratio = 0.5)
plot_grid(plot, plot, plot, plot, align = "hv", ncol = 2)
produces
But I'd like something like:
How can I achieve a similar result?
I think this is a case for the ggarrange() function from the egg package. Doing this with plot_grid() would require endless fiddling and isn't worth it.
(The technical reason is that plot_grid() keeps the total area for each plot in the grid constant, but if some plots have an x axis and others don’t then they take up different areas. One could try to circumvent this by using the rel_heights argument but there’s no good way to calculate the correct values for rel_heights, so it would be trial and error. By contrast, ggarrange() separately looks at the plot panel and the surrounding elements and makes sure the plot panels have the same size.)
Here is the code using ggarrange():
Value <- seq(0,1000, by = 1000/10)
Index <- 0:10
DF <- data.frame(Index, Value)
pbase <- ggplot(DF, aes(x = Index, y = Value)) +
geom_line(linetype = 2) +
theme_bw()
ptopleft <- pbase +
scale_x_continuous(position = "top") +
theme(plot.margin = margin(5.5, 0, 0, 5.5),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
ptopright <- pbase +
scale_y_continuous(position = "right") +
scale_x_continuous(position = "top") +
theme(plot.margin = margin(5.5, 5.5, 0, 0),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
pbottomleft <- pbase +
theme(plot.margin = margin(0, 0, 5.5, 5.5))
pbottomright <- pbase +
scale_y_continuous(position = "right") +
theme(plot.margin = margin(0, 5.5, 5.5, 0))
library(egg)
ggarrange(ptopleft, ptopright,
pbottomleft, pbottomright,
ncol = 2)
Two comments:
To remove every last bit of space below the plot panel on the top plots, we need to move the x axis to the top, even though we're not showing it. This is a strange limitation of the theming mechanism. We can't fully get rid of just one axis.
I'm not a big fan of shared axis titles, as in your example. I think each axis should have a title. If you want shared axis titles, why not use the faceting mechanism?
You can set subtle plot.margin each plot, then grid.arrange and add labs.
library(ggplot2)
library(grid)
library(gridExtra)
Value <- seq(0,1000, by = 1000/10)
Index <- 0:10
DF <- data.frame(Index, Value)
plot1 <- ggplot(DF, aes(x = Index, y = Value)) +
geom_line(linetype = 2) +
theme_minimal() +
theme(aspect.ratio = 0.5,
panel.border = element_rect(fill = NA),
axis.text.x = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
plot.margin = unit(c(5.5, 5.8, -50, 5.5), "pt"))
plot2 <- ggplot(DF, aes(x = Index, y = Value)) +
geom_line(linetype = 2) +
theme_minimal() +
theme(aspect.ratio = 0.5,
panel.border = element_rect(fill = NA),
axis.text.x = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
plot.margin = unit(c(5.5, 5.5, -50, 5.5), "pt")) +
scale_y_continuous(position = "right")
plot3 <- ggplot(DF, aes(x = Index, y = Value)) +
geom_line(linetype = 2) +
theme_minimal() +
theme(aspect.ratio = 0.5,
panel.border = element_rect(fill = NA),
axis.title = element_blank(),
axis.ticks = element_blank(),
plot.margin = unit(c(-50, 5.8, -50, 5.5), "pt"))
plot4 <- ggplot(DF, aes(x = Index, y = Value)) +
geom_line(linetype = 2) +
theme_minimal() +
theme(aspect.ratio = 0.5,
panel.border = element_rect(fill = NA),
axis.title = element_blank(),
axis.ticks = element_blank(),
plot.margin = unit(c(-50, 5.5, -50, 5.5), "pt")) +
scale_y_continuous(position = "right")
grid.arrange(grobs = list(plot1, plot2, plot3, plot4), ncol = 2, bottom = 'Index', left = 'Value', right = 'Value')
final plot

ggplot2: Make the filled area of the spatial plot flush with facet strip [duplicate]

I am creating some maps and want to remove all margins between the plot region and panel border.
This is the minimal example to reproduce my question
library(ggplot2)
library(grid)
df <- expand.grid(list(x = seq(1, 10), y = seq(1, 10), z = seq(1, 2)))
p <- ggplot(df) + geom_tile(aes(x, y)) + facet_wrap(~z)
p <- p + theme_minimal() + xlab('') + ylab('')
p <- p + theme(axis.text = element_blank(),
panel.grid = element_blank(),
axis.ticks = element_blank(),
panel.border = element_rect(colour = 'black', fill = 'transparent'),
panel.margin = unit(0, 'mm'))
p + ylim(2, 6) + xlim(2, 6)
This is the result of my codes.
How could I remove all white areas in the figure above? Thanks for any suggestions.
(Alright, here's my comment as an answer..)
Just add the following to the plot:
+ scale_y_continuous(expand = c(0,0)) + scale_x_continuous(expand = c(0,0))

How to remove the margin between plot region and panel in ggplot2?

I am creating some maps and want to remove all margins between the plot region and panel border.
This is the minimal example to reproduce my question
library(ggplot2)
library(grid)
df <- expand.grid(list(x = seq(1, 10), y = seq(1, 10), z = seq(1, 2)))
p <- ggplot(df) + geom_tile(aes(x, y)) + facet_wrap(~z)
p <- p + theme_minimal() + xlab('') + ylab('')
p <- p + theme(axis.text = element_blank(),
panel.grid = element_blank(),
axis.ticks = element_blank(),
panel.border = element_rect(colour = 'black', fill = 'transparent'),
panel.margin = unit(0, 'mm'))
p + ylim(2, 6) + xlim(2, 6)
This is the result of my codes.
How could I remove all white areas in the figure above? Thanks for any suggestions.
(Alright, here's my comment as an answer..)
Just add the following to the plot:
+ scale_y_continuous(expand = c(0,0)) + scale_x_continuous(expand = c(0,0))

Resources