ggplot2 align top of two facetted plots - r

I need to arrange two faceted graphs, like so:
d = data.frame(Index = LETTERS[1:5],x=1:5,y=1:5)
A = ggplot(subset(d,Index == 'A'),aes(x,y)) +
theme_bw() +
theme(axis.title.x = element_blank()) +
geom_point() + facet_wrap(~Index) + labs(title = "Title, The Title",
subtitle = "Subtitle, The Subtitle",
y = "Side Axes")
B = ggplot(subset(d,Index != 'A'),aes(x,y)) +
theme_bw() +
theme(axis.title.x = element_blank(), axis.title.y = element_blank()) +
geom_point() + facet_wrap(~Index) + labs(title = "", subtitle = "")
g = gridExtra::arrangeGrob(A,B,ncol=2,bottom="Bottom Axes")
grid.arrange(g)
Which produces the following:
As you can see from the above, there is a slight misalignment between the top edges of the plot region. This is caused by the 'commas' in the title and subtitles.
Does anyone know how I can enforce the top edges to align? I need a title and subtitle on the left plot, with an (empty) title, subtitle on the right one.

#CephBirk's solution is a clever and easy way to go here. For cases where a hack like that doesn't work, you can remove the title and sub-title from your plots and instead create separate grobs for them that you can lay out, along with the plots, using grid.arrange and arrangeGrob. In the code below, I've also added a nullGrob() as a spacer between plots A and B, so that the right x-label (1.50) in the left graph isn't cut off.
library(gridExtra)
A = ggplot(subset(d,Index == 'A'),aes(x,y)) +
theme_bw() +
theme(axis.title = element_blank()) +
geom_point() + facet_wrap(~Index)
B = ggplot(subset(d,Index != 'A'),aes(x,y)) +
theme_bw() +
theme(axis.title.x = element_blank(), axis.title.y = element_blank()) +
geom_point() + facet_wrap(~Index)
grid.arrange(
arrangeGrob(
arrangeGrob(textGrob("Title, The Title", hjust=0),
textGrob("Subtitle, The Subtitle", hjust=0, gp=gpar(cex=0.8))),
nullGrob(), ncol=2, widths=c(1,4)),
arrangeGrob(A, nullGrob(), B, ncol=3, widths=c(8,0.1,8),
left="Side Axes", bottom="Bottom Axes"),
heights=c(1,12))

It's a bit hackish, but you can have the same title and subtitle on the right as the left but print it in white font. :) You said it's due to the commas, so that fixes it.
Not the most satisfying, but it gets the job done.
B = ggplot(subset(d,Index != 'A'),aes(x,y)) +
theme_bw() +
theme(axis.title.x = element_blank(), axis.title.y = element_blank(), title = element_text(color = 'white')) +
geom_point() + facet_wrap(~Index) +
labs(title = "Title, The Title", subtitle = "Subtitle, The Subtitle")

egg::ggarrange(A, B, ncol=2, bottom="Bottom Axes")

Related

How to align text outside of ggplot?

I wanted to make a barplot like the figure a of this one that I found in a publication with something like a table tab showing some information outside the plot using ggplot. I found this general approach of adding text outside of a plot using gridExtra.
However, my question is how to align the height of each row of the table tab to each bar of the barplot so they match?
Here is an example. I wanted to add the note as a table tab on the right of the barplot.
library(ggplot2)
library(gridExtra)
df <- data.frame(Model = c("Datsun 710","Duster 360","Hornet 4 Drive","Hornet
Sportabout","Mazda RX4 Wag","Merc 230","Merc 240D","Valiant"),
logFC = c(1.879,1.552,1.360,1.108,-2.407,-2.416,-2.670,-3.061),
Note = c("ModelA","ModelB","ModelC","ModelD","ModelE","ModelF","ModelG","ModelH"))
plot <- ggplot(df, aes(Model, logFC)) +
geom_bar(stat="identity") +
coord_flip() +
theme_bw() +
ggtitle("Data for cars") +
theme(plot.title = element_text(size = 18, hjust = 0.5))
tab <- as.data.frame(
c(Note = df$Note))
rownames(tab) <- NULL
p_tab <- tableGrob(unname(tab))
grid.arrange(plot, p_tab, ncol = 2)
Per Gregor's comment, this works for me:
plot <- ggplot(df, aes(Model, logFC, label=Note)) +
geom_bar(stat="identity") +
coord_flip(clip = "off") +
theme_bw() +
ggtitle("Data for cars") +
theme(plot.title = element_text(size = 18, hjust = 0.5))+
geom_text(y = 3,
hjust = 0,
size = 5) +
theme(plot.margin = unit(c(1,10,1,1), "lines"),
panel.border=element_blank(),
axis.line = element_line(),
panel.grid.major=element_blank(),
panel.grid.minor = element_blank())

margin text when combining multiple plots into one

I have a series of plots that I want to combine into one, and I cannot use facet_wrap. So each of my plots is a separate object. I want them all the same size, and I can combine them this way.
p = ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() + xlab("") + ylab("")
g=ggpubr::ggarrange(p, p, p,
p, p, p,
p, p, p,
ncol = 3, nrow = 3)
I want to add some text labels that would apply to the columns and rows, as shown here.
I have tried adding titles to the individual plots (for example, those on the top row), but that reduces the size of the (grayed) plot compared to the others so that the plot dimensions are no longer all the same size.
Any clues would be greatly appreciated.
You can add secondary axes, clear the title for the primary ones and delete the tick marks for secondary ones but keep the titles (look into the theme function I added to your ggplot object). Then tile of those secondary axes can be used to write your desired text. Look below for an example.
library(ggplot2)
library(ggpubr)
p <- ggplot(mtcars, aes(x=wt, y=mpg)) +
geom_point() +
xlab("") + ylab("") +
scale_y_continuous(position = 'right', sec.axis = dup_axis()) +
scale_x_continuous(position = "top", sec.axis = dup_axis()) +
theme(plot.title = element_text(hjust=0.5),
axis.text.x.top = element_blank(),
axis.ticks.x.top = element_blank(),
axis.text.y.right = element_blank(),
axis.ticks.y.right = element_blank(),
axis.title.x.bottom = element_blank(),
axis.title.y.left = element_blank())
ggarrange(p + xlab("some text 1"),
p + xlab("some text 2"),
p + xlab("some text 3") + ylab("some text 33"),
p, p, p + ylab("some text44"),
p, p, p + ylab("some text55"),
ncol = 3, nrow = 3)
You can add axis.title.y.right = element_text(angle = 0) into theme to make y-axis title to be horizontal.
In reference to How to keep axis labels in one side and axis title in another using ggplot2

Unequal horizontal adjustment to title lines in ggplot

I've got a plot with a fairly wide y-axis label, so I want to adjust the title to the left so that it's flush with the label rather than the axis (like this question) but the twist is that I have a multiline title. I've been using hjust, but it adjusts the two lines differently.
For example
ggplot(mtcars,aes(x=wt,y=mpg))+
geom_point()+
ggtitle("Figure: My long and winding title\nthat goes on and on and on") +
ylab("My long label") +
theme_bw() +
theme(plot.title = element_text(size=16, hjust=-.33, color="black", face="bold")) +
theme(axis.title.y = element_text(angle = 0, hjust = 1))
Gives
Is there a way to make the start of the two lines of the title flush after adjusting them horizontally?
You could use the following code. First create the plot and assign it to g, then turn g in to a grob with ggplotGrob. Consequently, manipulate the title left alignment in the layout part of the grob (from 5 to 2). And Finally plot the adapted grob.
g <- ggplot(mtcars,aes(x=wt,y=mpg)) +
geom_point() +
ggtitle("Figure: My long and winding title\nthat goes on and on and on") +
ylab("My long label") +
theme_bw() +
theme(plot.title = element_text(size=16, color="black", face="bold")) +
theme(axis.title.y = element_text(angle = 0, hjust = 1))
grob <- ggplotGrob(g)
# what is the current content
grob$layout$l[grob$layout$name == "title"]
[1] 5
grob$layout$l[grob$layout$name == "title"] <- 2
# plot the new grob
grid::grid.draw(grob)
yielding this plot:
Please let me know whether this is what you want.
Sorry I misunderstood your question.
I think you're just missing a space in the title.
ggtitle("Figure: My long and winding title\n that goes on and on and on")
Here You have it:
library(ggplot2)
library(grid)
library("gridExtra")
p<-ggplot(mtcars,aes(x=wt,y=mpg))+
geom_point()+
ggtitle("") +
ylab("My long label") +
theme_bw() +theme(axis.title.y = element_text(angle = 0, hjust = 1))
title.grob <- textGrob(
label = "Figure: My long and winding title\nthat goes on and on and on",
x = unit(0, "lines"),
y = unit(0, "lines"),
hjust = 0, vjust = 0,
gp = gpar(fontsize = 16))
p1 <- arrangeGrob(p, top = title.grob)
grid.draw(p1)`
hjust is the responsible of the white space.
Removing it remove the 2 white spaces on the second line.
library(ggplot2)
ggplot(mtcars,aes(x=wt,y=mpg))+
geom_point()+
ggtitle("Figure: My long and winding title\nthat goes on and on and on") +
ylab("My long label") +
theme_bw() +
theme(plot.title = element_text(size=16,
color="black", face="bold",
),
axis.title.y = element_text(angle = 0, hjust = 1))
EDIT 1:
If you want to automatically split the title in multiple line, you can use gsub. Here is one example where I split the title after 30 characters. (source)
long_title <- "Figure: My long and winding title that goes on and on and on"
ggplot(mtcars,aes(x=wt,y=mpg))+
geom_point()+
ggtitle(gsub('(.{1,30})(\\s|$)', '\\1\n', long_title)) +
ylab("My long label") +
theme_bw() +
theme(plot.title = element_text(size=16,
color="black", face="bold",
),
axis.title.y = element_text(angle = 0, hjust = 1))
Hope that help !

Moving facet labels that have two lines near the plotting area

I’m working with faceted plots and I’m having an issue trying to move facet labels that have two lines near the plotting area.
Consider the minimal example:
require(ggplot2)
labs <- as_labeller(c(`0` = "LABEL 1",
`1` = "LABEL 2 HAS TWO LINES\nBECAUSE IT'S TOO LONG"))
p <- ggplot(mtcars, aes(disp, drat)) +
geom_point() +
theme_bw() +
geom_hline(yintercept=2, linetype="solid") +
geom_vline(xintercept=50, linetype="solid") +
scale_x_continuous(limits=c(50,500), expand =c(0,0)) +
scale_y_continuous(limits = c(2, 5), expand = c(0,0)) +
theme(panel.border = element_blank(),
strip.background = element_blank(),
strip.text = element_text(size=9),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
facet_wrap(~am, labeller = labs)
p
Now adding vjust=-0.62 to move the facet labels near the plotting area we have the following:
p + theme(strip.text = element_text(size=9, vjust=-0.62))
As you can see only LABEL 1, the single line label, is moved close to the plotting area - and that’s the problem.
I wished that both labels could have moved. Does anyone have any suggestion?
*Observation: I’m working with a considerable amount of faceted plots so making and customizing plots one-by-one doesn’t seem to be a good idea.
Hope this may helpful for you
p + theme(strip.text = element_text(size=9, vjust=1))

Change plot title sizes in a facet_wrap multiplot

Can any help me change the title text size for these plots. i.e. make them larger?
Script
ggplot(NMPSCMOR, aes(Length, fill=Year)) +
geom_histogram(position="dodge", binwidth=60, colour="black") + xlim(0, 600) +
scale_fill_grey(start = 1, end = 0)+
geom_vline(data=ddply(NMPSCMOR, Year~Morphology~Sector2, numcolwise(mean)),
mapping=aes(xintercept=Length,color=Year), linetype=2, size=1) +
scale_color_grey(start=1,end=0)+
xlab("Length Class") +
ylab(expression(paste("Total Count"))) + #( ", m^2, ")", sep =
facet_wrap( ~ Morphology + Sector2, ncol=3, scales = "free") +
theme(
panel.grid.minor = element_blank(), #removes minor grid lines
panel.grid.major = element_blank())
In theme(), add strip.text = element_text(size=25) or whatever size you want.

Resources