Change size (width) of plot in ggplot - r

I am a newbie attempting to change the width of a ggplot, so that I am can arrange different plots(heatmap and dotplot) in the same figure. However, after hours of trying to reduce the width of the dotplot, I am about to give up.
Code for heatmap (maybe not relevant):
heatmap_GO_NES_1<-ggplot(data=long_frame_GO_NES_1) +
geom_tile(mapping = aes(
x = factor(timepoint,levels = c("6h","12h","24h")),
y =bio_process,fill = NES)) +
ylab(label="Biological process") +
theme(axis.title.x=element_blank()) +
scale_fill_gradient(low="red",high="green")+
facet_grid( group ~. , scales="free",space="free")+
theme(axis.text.x = element_text(angle = 90))+
theme(strip.text.y = element_text(size = 8))
heatmap_GO_NES_1
Code for dotplot:
dot_GO_NES_1<- ggplot(data=long_frame_GO_NES_2)+
geom_count(mapping=aes(x=timepoint, y =bio_process, size=setsize))+
theme(axis.title.x=element_blank(), axis.text.x=element_blank(),
axis.ticks.x=element_blank(),axis.title.y=element_blank(),
axis.text.y=element_blank(),axis.ticks.y=element_blank())
dot_GO_NES_1
Code for figure:
plot_grid(heatmap_GO_NES_1,dot_GO_NES_1)
Obviously, the dotplot is stealing all the figure space, so that my heatmap does not show up in the figure.

TL;DR - you need to use the rel_widths= argument of plot_grid(). Let me illustrate with an example using mtcars:
# Plots to display
p1 <- ggplot(mtcars, aes(mpg, disp)) + geom_point()
p2 <- ggplot(mtcars, aes(x='X', y=disp)) + geom_point(aes(size=cyl))
Here are the plots, where you see p2 is like your plot... should not be too wide or it looks ridiculous. This is the default behavior of plot_grid(), which makes both plots the same width/relative size:
plot_grid(p1,p2)
Adjust the relative width of the plots using rel_widths=:
plot_grid(p1,p2, rel_widths=c(1,0.3))

Related

How to guarantee exactly equal size of faceted plots across different plots?

I'm doing something like the following. I tend to use cowplot for saving images of ggplot-generated plots but non-cowplot solutions are also fine. The first plot produces three facets (and one empty space) in a 2x2 arrangement, the second produces 6 facets in a 3x2 arrangement. I set base_height and base_width assuming a size of 2 square for each plot. In the images generated from the code below, the individual plots (each facet) are not quite the same size, across the two images.
library(ggplot2)
library(cowplot)
ggplot(mtcars, aes(x=mpg, y=hp))+
geom_point()+
facet_wrap(~cyl,ncol=2) +
ggtitle("hp vs. mpg, by cyl") +
theme_cowplot(font_size=10)
save_plot("car1.png", last_plot(), base_height=4, base_width=4)
ggplot(mtcars, aes(x=mpg, y=hp))+
geom_point()+
ggtitle("hp vs. mpg, by carb") +
facet_wrap(~carb,ncol=3)+
theme_cowplot(font_size=10)
save_plot("car2.png", last_plot(), base_height=4, base_width=6)
I tried including the png files in the post but they each get scaled differently so it would be misleading.
I know I could generate each facet separately as its own plot and use plot_grid, and then base_height and base_width would set the size of each plot on its own, but is there any way to use facet_wrap or facet_grid and set the absolute size when saved of each facet?
Does cowplot::align_plots work for you?
library(ggplot2)
library(cowplot)
p1 <- ggplot(mtcars, aes(x = mpg, y = hp)) +
geom_point() +
facet_wrap(~cyl, ncol = 2) +
ggtitle("hp vs. mpg, by cyl") +
theme_cowplot(font_size = 10)
p2 <- ggplot(mtcars, aes(x = mpg, y = hp)) +
geom_point() +
ggtitle("hp vs. mpg, by carb") +
facet_wrap(~carb, ncol = 3) +
theme_cowplot(font_size = 10)
twoplots <- align_plots(p1, p2, align = "hv", axis = "tblr") #tblr' for aligning all margins
save_plot("car1.png", ggdraw(twoplots[[1]]))
save_plot("car2.png", ggdraw(twoplots[[2]]))

How to control the space between categories in a barplot?

I have done a barplot in RStudio successfully, but I want to decrease the space between the categories (CPLEX and Heurística), but I can't do it. My objective is to make this figures thinner since I am working in a latex file where I want to put two of this plots side by side in the same line, but they are too wide and the get out of the margins. My code is the following.
library("ggplot2")
df <- data.frame(
Metodo = factor(c("CPLEX","Heurística"),levels=c("CPLEX","Heurística")),
Item = factor(c("Demanda total","UE","UI")),
Unidades = c(6440,6291,0,6440,6440,149)
)
ggplot(data=df, aes(x=Metodo, y=Unidades, fill=Item)) +
geom_bar(stat="identity", position=position_dodge(), colour="black",width=0.3) +
theme(text = element_text(family="serif", size=12,face="bold")) +
labs(x = "Método") +
ggtitle("Instancia 1") +
theme(legend.position="top")
ggsave("I1.png")
And the output is
I would like to reduce the wide of this plot, obviously without deforming it. Any ideas?
Add width into position_dodge:
ggplot(data=df, aes(x=Metodo, y=Unidades, fill=Item)) +
geom_bar(stat="identity", position=position_dodge(width = 0.5), colour="black",width=0.3) +
theme(text=element_text(family="serif", size=12,face="bold"))+labs(x="Método")+ggtitle("Instancia 1")+theme(legend.position="top")

Add significance lines outside/between facets

I wanted to add significant stars over 3 facets to compare them.
I google online but it is so complicated to add things outside plot. There is a ggsignif package but it does nothing to facets (https://github.com/const-ae/ggsignif/issues/22). It seems possible using gridExtra but I cannot make it.
The stars can be draw easily in a single plot, not facets. But I have to use facets to have separate rugs on the left. If you know how to have separate rugs inside a single plot, it should also solve the problem.
Here is the code and plot I want to add things on:
library(ggplot2)
ToothGrowth$dose = factor(ToothGrowth$dose)
ggplot(ToothGrowth, aes(x='', y=len, color=dose)) +
geom_boxplot() +
geom_rug(sides="l") +
facet_grid(. ~ dose)
What I want is:
Sorry for the drawing. The line width should be the same. The final result should be really similar to this but for facets:
This is a workaround - plot two plots (one for significance annotation, another for boxplots).
library(ggplot2)
library(ggsignif)
ToothGrowth$dose <- factor(ToothGrowth$dose)
Plot significance annotation. Don't use boxplot here and set tips to 0 (using only one comparison here as others return error from statistical test, but I'm assuming that this is only an example dataset).
p1 <- ggplot(ToothGrowth, aes(as.factor(dose), len)) +
geom_signif(comparisons = list(c("1", "2")), tip_length = 0.005) +
coord_cartesian(ylim = c(35, 35.5)) +
theme_void()
Plot boxplots with different x axis (need this to specify comparisons groups in ggsignif)
p2 <- ggplot(ToothGrowth, aes(factor(dose), len)) +
geom_boxplot() +
geom_rug(sides = "l") +
facet_grid(. ~ dose, scales = "free_x") +
labs(x = NULL) +
theme(axis.text.x = element_blank(),
axis.ticks.x = element_blank())
Draw plots together geom_signif on-top of geom_boxplot with facet_wrap
egg::ggarrange(p1, p2, heights = c(2, 10))

Adjust width of panel labels on ggplot with faceting

I am having trouble with excessively wide panel labels on my ggplot2 faceted plot.
Here is the code that I used to generate the plot:
png(paste("/directory/", hgnc_symbol, "_", curr_gene, ".png", sep=""),
width=4, height=3, units="in", pointsize=1, res=300)
print({barplot <-
ggplot(curr_data, aes(x = condition, y = tpm, fill=condition)) +
geom_boxplot(outlier.colour=NA, lwd=0.2, color="grey18") +
stat_boxplot(geom ='errorbar', color="grey18") +
geom_jitter(size=0.8) +
facet_wrap(~target_id) +
guides(fill=FALSE) +
theme_bw() +
labs(title=paste(hgnc_symbol, "_", curr_gene, sep="")) +
labs(x="condition") + labs(y="TPM") +
theme(text = element_text(size=5), strip.background=element_rect(size = 1),
axis.text.x = element_text(angle = 90, hjust = 1, size=4.5))})
dev.off()
The plot comes out looking like this:
As you can see, the background of the panel labels is so wide, that the plots themselves are barely visible. The points plotted on the graph are also much larger than I expected them to be.
The odd thing is that I used this same exact code to produce this following plot (which looks good) just a few days ago:
What is causing this difference, and how can I fix the problem?
In ggplot, text is defined in pts, which are absolute units of measure. The plot panel is relative in size and scales according to the dimensions you specify when you save your plot. If the dimensions are small, then the text will be large relative to the panel areas. If the dimensions are large, then the text will be small relative to the panel areas. See examples below:
ggplot(diamonds, aes(x = x, y =y)) + geom_point() + facet_wrap(~ clarity)
ggsave("filepath//4x3.png", width=4, height = 3)
ggsave("filepath//8x6.png", width=8, height = 6)
The 4 x 3 in plot:
The 8 x 6 in plot:
You can edit the grobs to exert finer control on the plot dimensions (example).

ggplot geom_text font size control

I tried to change the font to 10 for the labels of my bar plot in ggplot2 by doing something like this:
ggplot(data=file,aes(x=V1,y=V3,fill=V2)) +
geom_bar(stat="identity",position="dodge",colour="white") +
geom_text(aes(label=V2),position=position_dodge(width=0.9),
hjust=1.5,colour="white") +
theme_bw()+theme(element_text(size=10))
ggsave(filename="barplot.pdf",width=4,height=4)
but the resulting image has super big font size for the bar plot labels.
Then I thought of modifying in geom_text() with this:
geom_text(size=10,aes(label=V2),position=position_dodge(width=0.9),
hjust=1.5,colour="white")
The label font is even bigger...
I can change the size within geom_text to something like 3 and now it looks like font 10, similar to the axis labels.
I'm wondering what's going on? Does theme(text=element_text(size=10)) doesn't apply to labels?
And why size of 10 in geom_text() is different from that in theme(text=element_text()) ?
Here are a few options for changing text / label sizes
library(ggplot2)
# Example data using mtcars
a <- aggregate(mpg ~ vs + am , mtcars, function(i) round(mean(i)))
p <- ggplot(mtcars, aes(factor(vs), y=mpg, fill=factor(am))) +
geom_bar(stat="identity",position="dodge") +
geom_text(data = a, aes(label = mpg),
position = position_dodge(width=0.9), size=20)
The size in the geom_text changes the size of the geom_text labels.
p <- p + theme(axis.text = element_text(size = 15)) # changes axis labels
p <- p + theme(axis.title = element_text(size = 25)) # change axis titles
p <- p + theme(text = element_text(size = 10)) # this will change all text size
# (except geom_text)
For this And why size of 10 in geom_text() is different from that in theme(text=element_text()) ?
Yes, they are different. I did a quick manual check and they appear to be in the ratio of ~ (14/5) for geom_text sizes to theme sizes.
So a horrible fix for uniform sizes is to scale by this ratio
geom.text.size = 7
theme.size = (14/5) * geom.text.size
ggplot(mtcars, aes(factor(vs), y=mpg, fill=factor(am))) +
geom_bar(stat="identity",position="dodge") +
geom_text(data = a, aes(label = mpg),
position = position_dodge(width=0.9), size=geom.text.size) +
theme(axis.text = element_text(size = theme.size, colour="black"))
This of course doesn't explain why? and is a pita (and i assume there is a more sensible way to do this)
Take a look at the relevant entry in ggplot2's customization FAQ: https://ggplot2.tidyverse.org/articles/faq-customising.html#what-is-the-default-size-of-geom_text-and-how-can-i-change-the-font-size-of-geom_text
You can modify the default size of geom_text() by placing update_geom_defaults("text", list(size = X), where X is your choice of new size, at the beginning of your script.

Resources