Draw two plots in R with ggplot and par - r

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

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 plot two histograms on the same axis scale?

I have two dataframes: dataf1, dataf2. They have the same structure and columns.
3 columns names are A,B,C. And they both have 50 rows.
I would like to plot the histogram of column B on dataf1 and dataf2. I can plot two histograms separately but they are not of the same scale. I would like to know how to either put them on the same histogram using different colors or plot two histograms of the same scale?
ggplot() + aes(dataf1$B)+ geom_histogram(binwidth=1, colour="black",fill="white")
ggplot() + aes(dataf2$B)+ geom_histogram(binwidth=1, colour="black", fill="white")
Combine your data into a single data frame with a new column marking which data frame the data originally came from. Then use that new column for the fill aesthetic for your plot.
data1$source="Data 1"
data2$source="Data 2"
dat_combined = rbind(data1, data2)
You haven't provided sample data, so here are a few examples of possible plots, using the built-in iris data frame. In the plots below, dat is analogous to dat_combined, Petal.Width is analogous to B, and Species is analogous to source.
dat = subset(iris, Species != "setosa") # We want just two species
ggplot(dat, aes(Petal.Width, fill=Species)) +
geom_histogram(position="identity", colour="grey40", alpha=0.5, binwidth=0.1)
ggplot(dat, aes(Petal.Width, fill=Species)) +
geom_histogram(position="dodge", binwidth=0.1)
ggplot(dat, aes(Petal.Width, fill=Species)) +
geom_histogram(position="identity", colour="grey40", binwidth=0.1) +
facet_grid(Species ~ .)
As Zheyuan says, you just need to set the y limits for each plot to get them on the same scale. With ggplot2, one way to do this is with the lims command (though scale_y_continuous and coord_cartesian also work, albeit slightly differently). You also should never use data$column indside aes(). Instead, use the data argument for the data frame and unquoted column names inside aes(). Here's an example with some built-in data.
p1 = ggplot(mtcars, aes(x = mpg)) + geom_histogram() + lims(y = c(0, 13))
p2 = ggplot(iris, aes(x = Sepal.Length)) + geom_histogram() + lims(y = c(0, 13))
gridExtra::grid.arrange(p1, p2, nrow = 1)
Two get two histograms on the same plot, the best way is to combine your data frames. A guess, without seeing what your data looks like:
dataf = rbind(dataf1["B"], dataf2["B"])
dafaf$source = c(rep("f1", nrow(dataf1)), rep("f2", nrow(dataf2))
ggplot(dataf, aes(x = B, fill = source)) +
geom_histogram(position = "identity", alpha = 0.7)

Plotting only stat_smooth without original ggplot2 data

I plot data with ggplot, and I wanted to see the smoothed lines using stat_smooth.
But now I would like to only plot the smoothed lines (somehow extract it), without the original ggplot.
Do you think it's possible?
Here is my code :
Graph <- ggplot(data=Forecasttemp, aes(x=Price.date, y=Price, colour=Group)) + geom_line() + scale_colour_hue(guide = "none")
Graph <- Graph + stat_smooth(se = FALSE, aes(fill = Group)) + scale_colour_hue(guide = "none")
If you want to plot only the smoothed lines without original sample points, you can simply omit geom_line(), thus resulting in:
Graph <- ggplot(data=Forecasttemp, aes(x=Price.date, y=Price, colour=Group)) +
stat_smooth(se = FALSE, aes(fill = Group)) +
scale_colour_hue(guide = "none")
Unfortunately I can not try this due to the lack of a reproducible example, but I make a try with an R base dataset and it worked:
library(ggplot2)
data(iris)
g1 <- ggplot(data=iris, aes(x=Sepal.Length, y=Petal.Length, colour=Species)) +
scale_colour_hue(guide = "none") + geom_smooth()
g1

How to set upper bound for x-axes for ploting using ggplot?

I'm using ggplot to create the plot of the density of my data.But I want to get plot for the X value until 2.0.
How can I put this restiriction in my code?
Here is my code and the plot:
ggplot()+geom_density(aes(data=Ge,x=GeN[,1]),color='red')
ggplot(iris, aes(x = Petal.Length)) + geom_density()
ggplot(iris, aes(x = Petal.Length)) + geom_density() + xlim(0, 2)

How to use scale from previous plot in current plot with ggplot2?

I am using ggplot2 to produce a plot that has 3 facets. Because I am comparing two different data sets, I would like to then be able to plot a second data set using the same y scale for the facets as in the first plot. However, I cannot find a simple way to save the settings of the first plot to then re-use them with the second plot. Since each facet has its own y scale, it will be a pain to specify them by hand for the second plot. Does anyone know of a quick way of re-using scales? To make this concrete, here is how I am generating first my plot:
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + facet_wrap(~ cyl, scales = "free_y")
EDIT
When applying one of the suggestions below, I found out that my problem was more specific than described in the original post, and it had to do specifically with scaling of the error bars. Concretely, the error bars look weird when I rescale the second plot as suggested. Does anyone have any suggestions on how to keep the same scale for both plots and dtill display the error bars correctly? I am attaching example below for concreteness:
#Create sample data
d1 <- data.frame(fixtype=c('ff','ff','fp','fp'), detype=c('det','pro','det','pro'),
diffscore=c(-1,-15,3,-17),se=c(2,3,1,2))
d2 <- data.frame(fixtype=c('ff','ff','fp','fp'), detype=c('det','pro','det','pro'),
diffscore=c(-1,-3,-2,-1),se=c(4,3,5,3))
#Plot for data frame 1, this is the scale I want to keep
lim_d1 <- aes(ymax = diffscore + se, ymin=diffscore - se)
ggplot(d1, aes(colour=detype, y=diffscore, x=detype)) +
geom_point(aes(size=1), shape=15) +
geom_errorbar(lim_d1, width=0.2,size=1) +
facet_wrap(~fixtype, nrow=2, ncol=2, scales = "free_y")
#Plot for data frame 2 original scale
lim_d2 <- aes(ymax = diffscore + se, ymin=diffscore - se)
ggplot(d2, aes(colour=detype, y=diffscore, x=detype)) +
geom_point(aes(size=1), shape=15) +
geom_errorbar(lim_d2, width=0.2,size=1) +
facet_wrap(~fixtype, nrow=2, ncol=2, scales = "free_y")
#Plot for data frame 2 adjusted scale. This is where things go wrong!
#As suggested below, first I plot the first plot, then I draw a blank screen and try
#to plot the second data frame on top.
lim_d2 <- aes(ymax = diffscore + se, ymin=diffscore - se)
ggplot(d1, aes(colour=detype, y=diffscore, x=detype)) +
geom_blank() +
geom_point(data=d2, aes(size=1), shape=15) +
geom_errorbar(lim_d2, width=0.2,size=1) +
facet_wrap(~fixtype, nrow=2, ncol=2, scales = "free_y")
#If the error bars are fixed, by adding data=d2 to geom_errorbar(), then
#the error bars are displayed correctly but the scale gets distorted again
lim_d2 <- aes(ymax = diffscore + se, ymin=diffscore - se)
ggplot(d1, aes(colour=detype, y=diffscore, x=detype)) +
geom_blank() +
geom_point(data=d2, aes(size=1), shape=15) +
geom_errorbar(data=d2,lim_d2, width=0.2,size=1) +
facet_wrap(~fixtype, nrow=2, ncol=2, scales = "free_y")
You may first call ggplot on your original data where you add a geom_blank as a first layer. This sets up a plot area, with axes and legends based on the data provided in ggplot.
Then add geoms which use data other than the original data. In the example, I use a simple subset of the original data.
From ?geom_blank: "The blank geom draws nothing, but can be a useful way of ensuring common scales between different plots.".
ggplot(data = mtcars, aes(mpg, wt)) +
geom_blank() +
geom_point(data = subset(mtcars, wt < 3)) +
facet_wrap(~ cyl, scales = "free_y")
Here is an ugly hack that assumes you have an identical facetting layout in both plots.
It replaces the panel element of the ggplot build.
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p1 <- p + facet_wrap(~ cyl, scales = "free_y") + labs(title = 'original')
# create "other" data.frame
n <- nrow(mtcars)
set.seed(201405)
mtcars2 <- mtcars[sample(seq_len(n ),n-15),]
# create this second plot
p2 <- p1 %+% mtcars2 + labs(title = 'new data')
# and a copy so we can attempt to fix
p3 <- p2 + labs(title = 'new data original scale')
# use ggplot_build to construct the plots for rendering
p1b <- ggplot_build(p1)
p3b <- ggplot_build(p3)
# replace the 'panel' information in plot 2 with that
# from plot 1
p3b[['panel']] <- p1b[['panel']]
# render the revised plot
# for comparison
library(gridExtra)
grid.arrange(p1 , p2, ggplot_gtable(p3b))

Resources