Change order margin is presented in facet_grid ggplot2? - r

I've seen several answers on how to change the order of facets by reordering the factor levels. But I would like to change the order in which the margin is presented. So basically have (all) displayed on the left panel before 4, 6, 8. Thanks in advance!
library(ggplot2)
qplot(mpg, wt, data=mtcars) + facet_grid(. ~ cyl, margins=TRUE)

How about
mtcars2 <- rbind(mtcars, within(mtcars, cyl <- "(All)"))
qplot(mpg, wt, data = mtcars2) + facet_grid(. ~ cyl)

I have a very sophisticated solution, you always could edit your grobs structure:
library(ggplot2)
gg = qplot(mpg, wt, data=mtcars) + facet_grid(. ~ cyl, margins=TRUE)
ggg = ggplotGrob(gg)
ggg$grobs = ggg$grobs[c(1,5,2:4,9,6:8,10:15,19,16:18,20:27)]
grid::grid.newpage()
grid::grid.draw(ggg)

Related

how to create multiple plots using for loop

I would like to create multiple plots using for loop setup. However my code does not work. Could anyone give me some guidance on this?
for i in 1:4 {
paste0("p_carb_",i) <- ggplot(mtcars%>% filter(carb==4), aes(x = wt, y = mpg, color = disp))
+ geom_point()
}
Perhaps this?
library(ggplot2)
library(dplyr)
ggs <- lapply(sort(unique(mtcars$carb)), function(crb) {
ggplot(filter(mtcars, carb == crb), aes(x = wt, y = mpg, color = disp)) +
geom_point()
})
This produces six plots, which when the first two are viewed side-by-side (calling ggs[[1]] and then ggs[[2]]), we see
An alternative might be to facet the data, as in
ggplot(mtcars, aes(x = wt, y = mpg, color = disp)) +
facet_wrap(~ carb) +
geom_point()
But the literal translation of your paste(..) <- ... code into something syntactically correct, we'd use an anti-pattern in R: assign:
for (crb in sort(unique(mtcars$carb))) {
gg <- ggplot(filter(mtcars, carb == crb), aes(x = wt, y = mpg, color = disp)) +
geom_point()
assign(paste0("carb_", crb), gg)
}
Again, this is not the preferred/best-practices way of doing things. It is generally considered much better to keep like-things in a list for uniform/consistent processing of them.
Multiple IDs ... two ways:
Nested lapply:
carbs <- sort(unique(mtcars$carb))
ggs <- lapply(carbs, function(crb) {
gears <- subset(mtcars, carb == crb)$gear
lapply(gears, function(gr) {
ggplot(dplyr::filter(mtcars, carb == crb, gear == gr), aes(x = wt, y = mpg, color = disp)) +
geom_point()
})
})
Where ggs[[1]] is a list of lists. ggs[[1]][[1]] will be one plot.
split list, one-deep:
carbsgears <- split(mtcars, mtcars[,c("carb", "gear")], drop = TRUE)
ggs <- lapply(carbsgears, function(dat) {
ggplot(dat, aes(x = wt, y = mpg, color = disp)) + geom_point()
})
Here, ggs is a list only one-deep. The names are just concatenated strings of the two fields, so since we have mtcars$carb with values c(1,2,3,4,6,8) and mtcars$gear with values c(3,4,5), removing combinations without data we have names:
names(ggs)
# [1] "1.3" "2.3" "3.3" "4.3" "1.4" "2.4" "4.4" "2.5" "4.5" "6.5" "8.5"
where "1.3" is carb == 1 and gear == 3. When column names have dots in them, this might become ambiguous.

How to respect ratio size when merging ggplot2 figures

I'm looking for help in order to merge two plots and respect their respective scale size.
Here is a reproductible example:
data1<- subset(mtcars, cyl = 4)
data1$mpg <- data1$mp*5.6
data2<- subset(mtcars, cyl = 8)
p1 <- ggplot(data1, aes(wt, mpg, colour = cyl)) + geom_point()
p2 <- ggplot(data2, aes(wt, mpg, colour = cyl)) + geom_point()
grid.arrange(p1, p2, ncol = 2)
But what I'm looking for is to merge the two plots and respect the scale size and get something like :
It would be nice to not use a package which need to define the ratio since it's difficult to known how much I should reduce the second plot compared to the first one... And event more difficult when we have more than 2 plots.
I think what you are trying to achieve is something like this:
library(tidyverse)
mtcars %>%
filter(cyl %in% c(4, 8)) %>%
mutate(mpg = ifelse(cyl == 4, mpg * 5.6, mpg)) %>%
ggplot(aes(x = wt, y = mpg, col = as.factor(cyl))) +
geom_point(show.legend = FALSE) +
facet_wrap(~ cyl)
NOTE: I see some bugs in your original code. For example, if you want to use subset() to subset your data, you have to change your code from:
data1 <- subset(mtcars, cyl = 4)
to:
data1 <- subset(mtcars, cyl == 4)
subset(mtcars, cyl = 4) does not do anything.

Adding Title to ggplot from the dataset itself

I am working with the R programming language. I made the following graph using the built-in "mtcars" dataset:
library(ggplot2)
a = ggplot(data=mtcars, aes(x=wt, y=mpg)) + geom_point() + ggtitle("mtcars: wt vs mpg")
Question: Now, I am trying to customize the title, but I want the title to "contain a variable reference", for example:
b = ggplot(data=mtcars, aes(x=wt, y=mpg)) + geom_point() + ggtitle("mtcars: wt vs mpg - average mpg = mean(mtcars$mpg)")
But this command literally just prints the code I wrote:
I know that the "mean" command runs by itself:
mean(mtcars$mpg)
[1] 20.09062
But can someone please help me change this code:
ggplot(data=mtcars, aes(x=wt, y=mpg)) + geom_point() + ggtitle("mtcars: wt vs mpg - average mpg = mean(mtcars$mpg)")
So that it produces something like this (note: here, I manually wrote the "mean" by hand):
Thanks
You can do this using paste().
ggplot(data=mtcars, aes(x=wt, y=mpg)) + geom_point() + ggtitle(paste0("mtcars: wt vs mpg - average mpg = ", mean(mtcars$mpg)))
If you need to you can add more text and variables with commas like so:
ggtitle(paste0('text ', var1, 'text2 etc ', var2, var3, 'text3'))
Note that paste0 is a variant of paste that concatenates things with no space or separator in between.
An option with glue
library(ggplot2)
library(glue)
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
ggtitle(glue("mtcars: wt vs mpg - average mpg = {mean(mtcars$mpg)}"))
We could also use str_c from stringr package which is part of tidyverse package. str_c is equivalent to paste0
library(tidyverse)
ggplot(data=mtcars, aes(x=wt, y=mpg)) + geom_point() + ggtitle(str_c("mtcars: wt vs mpg - average mpg = ", mean(mtcars$mpg)))

Putting different ggplots next to each other, while keeping a common facet wrap

Background: I have a set of ggplots (different types) that I would to have displayed next to each other, but they share a common facet.
Here is a minimal working example:
p1 <- mtcars %>% ggplot(mapping = aes(x = wt, y = qsec)) + geom_point() +
facet_wrap(~ cyl)
plot(p1)
p2 <- mtcars %>% ggplot(mapping = aes(x = disp, y = qsec)) + geom_smooth() +
facet_wrap(~ cyl)
plot(p2)
Question
I would like to have the first plot of p1 (say, above) the first plot of p2, the second plot of p1 above the second plot of p2 and so on... How could I do that? So far my solution is to have p1 and p2 separately, but this is not what I am looking for. Any help would be appreciated.
Try the patchwork package
# install.packages("devtools")
# devtools::install_github("thomasp85/patchwork")
library(patchwork)
p1 / p2
You can also use the cowplot package available on cran.
library(tidyverse)
library(cowplot)
p1 <- mtcars %>% ggplot(mapping = aes(x = wt, y = qsec)) + geom_point() +
facet_wrap(~ cyl)
p2 <- mtcars %>% ggplot(mapping = aes(x = disp, y = qsec)) + geom_smooth() +
facet_wrap(~ cyl)
plot_grid(p1, p2, ncol = 1, align = "v")
I like cowplot a lot, but it does change the default theme of ggplot. If you want to change it back, you need to add this: theme_set(theme_gray()).

ScatterPlot of Cars example

I am trying to plot a scatterplot from mtcars of: hp ~ mpg and for each point (x,y) show how many cylinders (cyl) by different colors.
I tried to use the function ScatterPlot , but it's not recognized without adding the 'car' package.
So I tried :
plot(mtcars$mpg ~ mtcars$hp , data=mtcars, xlab="HP", ylab="Hwy.MPG")
How can I add number of cylinders for each point of this graph? (with different colors)
I'm going to assume you're using mtcars from datasets.
The simplest way to add colour is to just add a colargument:
plot(mpg ~ hp , data=mtcars, col=cyl, xlab="HP", ylab="Hwy.MPG")
If you want custom colours, you can use the palettefunction:
palette(c("red", "blue", "green"))
plot(mpg ~ hp , data=mtcars, col=cyl, xlab="HP", ylab="Hwy.MPG")
Here's an example in lattice It's a little more "Oo-Lala", and fairly straightforward.
library(lattice)
xyplot(mpg ~ hp, data = mtcars, groups = cyl, pch = 19,
xlab = "HP", ylab = "Hwy.MPG", auto.key = list(columns = 3))
And to complete the picture, here's the ggplot example
library(ggplot2)
ggplot(mtcars, aes(x = hp, y = mpg)) + geom_point(aes(color = factor(cyl)), size = 4)

Resources