I am using the patchwork package in r to create panels of plots like:
panel<- (p1+ plot_spacer()+p2 + p3)+
plot_layout(ncol = 2) +
plot_layout(guides = "collect")
panel
I want to specify the legend to go to the empty top-right panel, more or less like this
Appreciate any pointers
For this use case patchwork provides guide_area() which could be used to place the legend:
library(patchwork)
library(ggplot2)
p1 <- p2 <- p3 <- ggplot(mtcars, aes(hp, mpg, color = factor(cyl))) +
geom_point()
p1 + guide_area() + p2 + p3 +
plot_layout(ncol = 2) +
plot_layout(guides = "collect")
as suggested by #kat, one solution is to use cowplot in combination to patchwork
library("cowplot")
library("patchwork")
legend_grob <-cowplot::get_legend(p1) #get legend
#emove legend in the original plots
p1 <- p1+theme(legend.position = "none")
p2 <- p2+theme(legend.position = "none")
p3 <- p3+theme(legend.position = "none")
# now patchwork it
p1+legend_grob+p2+p3)
plot_layout(ncol = 2)
I'm trying to figure out how to annotate combined patchworks as if they were individual plots.
I've got one patchwork consisting of three combined plots and another single plot. The final composite plot is the first patchwork on top and the individual plot on the bottom. I have no problem getting the layout I want, but when I use plot_annotation, it gives letters to every plot, whereas what I'd like to see is an A for the top plot (patchwork of three subplots) and a B for the bottom one (just a single plot)
Here's what I'm currently doing:
library(ggplot2)
library(patchwork)
p1 <- ggplot(mtcars) +
geom_point(aes(mpg, disp)) +
ggtitle('Plot 1')
p2 <- ggplot(mtcars) +
geom_boxplot(aes(gear, disp, group = gear)) +
ggtitle('Plot 2')
p3 <- ggplot(mtcars) +
geom_point(aes(hp, wt, colour = mpg)) +
ggtitle('Plot 3')
p4 <- ggplot(mtcars) +
geom_bar(aes(gear)) +
facet_wrap(~cyl) +
ggtitle('Plot 4')
top_plot = (p1 + p2 + p3)
bottom_plot = p4
combined_plot <- (top_plot / bottom_plot) + plot_annotation(tag_levels="A")
combined_plot
What I'd like to see, rather than A-D annotations, is A for the top plot (plots 1-3) and a B for the bottom one (plot 4). Is there a way to do this?
One solution is to create two complete patchwork plots, each with its own annotation. You have to put them each inside wrap_elements to declare them as complete patchworks for this to work. Thereafter you can combine them as you would combine ggplots:
# Set theme for annotations
thm <- theme(plot.title = element_text(face = 2, size = 16))
top_plot <- wrap_elements((p1 + p2 + p3) +
plot_annotation(title = "A", theme = thm))
bottom_plot <- wrap_elements(p4 + plot_annotation(title = "B", theme = thm))
top_plot / bottom_plot
I start to study R. I'm starting with Iris dataset in the package datasets. To draw som graph I need to use the ggplot2 package. How can I split the Plots window and draw two graphs?
I try with the following code, but only one graph is showed.
iris=datasets::iris
par(mfrow=c(2,1))
ggplot(iris, aes(x=Sepal.Length,y=Sepal.Width,color=Species))+ geom_point(size=3)
ggplot(iris, aes(x=Petal.Length,y=Petal.Width,color=Species))+ geom_point(size=3)
use win.graph() to split the window into two.
Since you have not provided dataset, if you want to create a side by side plot try based on my example below
Try this:
library(cowplot)
iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
geom_boxplot() + theme_bw()
iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
geom_density(alpha = 0.7) + theme_bw() +
theme(legend.position = c(0.8, 0.8))
plot_grid(iris1, iris2, labels = "AUTO")
As ggplot2 is based on grid graphics system instead of base plot, par does not effective in adjusting ggplot2 plots, and the latest version of ggplot2 has already supported the arrangement of different plots, and you can set tags for each of them:
iris=datasets::iris
ggplot(iris, aes(x=Sepal.Length,y=Sepal.Width,color=Species))+ geom_point(size=3) + labs(tag = "A") -> p1
ggplot(iris, aes(x=Petal.Length,y=Petal.Width,color=Species))+ geom_point(size=3) + labs(tag = "B") -> p2
p1 + p2
For more sophisticated arrangement, you can use patchwork package to arrange them
I would like to built a boxplot in which the 4 factors (N1:N4) are overlaid in the same column. For example with the following data:
df<-data.frame(N=N,Value=Value)
Q<-c("C1","C1","C2","C3","C3","C1","C1","C2","C2","C3","C3","Q1","Q1","Q1","Q1","Q3","Q3","Q4","Q4","Q1","Q1","Q1","Q1","Q3","Q3","Q4","Q4")
N<-c("N2","N3","N3","N2","N3","N2","N3","N2","N3","N2","N3","N0","N1","N2","N3","N1","N3","N0","N1","N0","N1","N2","N3","N1","N3","N0","N1")
Value<-c(4.7,8.61,8.34,5.89,8.36,1.76,2.4,5.01,2.12,1.88,3.01,2.4,7.28,4.34,5.39,11.61,10.14,3.02,9.45,8.8,7.4,6.93,8.44,7.37,7.81,6.74,8.5)
with the following (usual) code, the output is 4 box-plots displayed in 4 columns for the 4 variables
ggplot(df, aes(x=N, y=Value,color=N)) + theme_bw(base_size = 20)+ geom_boxplot()
many thanks
Updated Answer
Based on your comment, here's a way to add marginal boxplots. We'll use the built-in mtcars data frame.
First, some set-up:
library(cowplot)
# Common theme elements
thm = list(theme_bw(),
guides(colour=FALSE, fill=FALSE),
theme(plot.margin=unit(rep(0,4),"lines")))
Now, create the three plots:
# Main plot
p1 = ggplot(mtcars, aes(wt, mpg, colour=factor(cyl), fill=factor(cyl))) +
geom_smooth(method="lm") + labs(colour="Cyl", fill="Cyl") +
scale_y_continuous(limits=c(10,35)) +
thm[-2] +
theme(legend.position = c(0.85,0.8))
# Top margin plot
p2 = ggplot(mtcars, aes(factor(cyl), wt, colour=factor(cyl))) +
geom_boxplot() + thm + coord_flip() + labs(x="Cyl", y="")
# Right margin plot
p3 = ggplot(mtcars, aes(factor(cyl), mpg, colour=factor(cyl))) +
geom_boxplot() + thm + labs(x="Cyl", y="") +
scale_y_continuous(limits=c(10,35))
Lay out the plots and add the legend:
plot_grid(plotlist=list(p2, ggplot(), p1, p3), ncol=2,
rel_widths=c(5,1), rel_heights=c(1,5), align="hv")
Original Answer
You can overlay all four boxplots in a single column, but the plot will be unreadable. The first example below removes N as the x coordinate, but keeps N as the colour aesthetic. This results in the four levels of N being plotted at a single tick mark (which I've removed by setting breaks to NULL). However, the plots are still dodged. To plot them one on top of the other, set the dodge width to zero, as I've done in the second example. However, the plots are not readable when they are overlaid.
ggplot(df, aes(x="", y=Value,color=N)) +
theme_bw(base_size = 20) +
geom_boxplot() +
scale_x_discrete(breaks=NULL) +
labs(x="")
ggplot(df, aes(x="", y=Value,color=N)) +
theme_bw(base_size = 20) +
geom_boxplot(position=position_dodge(0)) +
scale_x_discrete(breaks=NULL) +
labs(x="")
I used the facetting in ggplot. My question is: how is it possible to draw ticks between facets? I am aware of the scale = "free_y" option which gives ticks and values:
library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + facet_wrap( ~ cyl, scale = "free_y")
But only ticks?
This is basically what I want: