John Huang
John Huang

Reputation: 845

Creating the same scale for graphs with different scales

I have a data set where I created ggplots for each ind where I end up with four different graphs. I had put these graphs into a list, and then used plot_grid from cowplot to get a single output that displays all four graphs at once. I'm not quite sure how to create a generic example here.The four graphs have different scales, but I would like my end product to have the same scales for each graph from the plot_grid output. How would I do this?

Here is a sample data set:

library(ggplot2)
data(iris)
rsq <- lapply(1:length(unique(iris$Species)), function(i) {
  cor(iris[iris$Species == unique(iris$Species)[i], "Sepal.Length"], iris[iris$Species == unique(iris$Species)[i], "Petal.Length"])^2
})

p.list <- lapply(1:length(unique(iris$Species)), function(i) {
  ggplot(iris[iris$Species == unique(iris$Species)[i], ], aes(x = Sepal.Length, y = Petal.Length)) +
    geom_point() + theme_bw()+
    geom_text(aes(x=min(Sepal.Length),y=max(Petal.Length),label=paste0("R= ",round(rsq[[i]],2))))
})

cowplot::plot_grid(plotlist = p.list[1:3], nrow = 1, ncol = 3, 
                   labels = "AUTO")

Upvotes: 1

Views: 804

Answers (1)

stefan
stefan

Reputation: 124413

There are at least two options to achieve your desired result.

  1. If you want to stick with plot.grid you could achieve your desired result by setting the same limits for the x and the y scale in each of your plots. To this end compute the overall minimum and maximum in your data:
library(ggplot2)

rsq <- lapply(1:length(unique(iris$Species)), function(i) {
  cor(iris[iris$Species == unique(iris$Species)[i], "Sepal.Length"], iris[iris$Species == unique(iris$Species)[i], "Petal.Length"])^2
})

d_list <- split(iris, iris$Species)

xmin <- min(unlist(lapply(d_list, function(x) min(x["Sepal.Length"]))))
xmax <- max(unlist(lapply(d_list, function(x) max(x["Sepal.Length"]))))
ymin <- min(unlist(lapply(d_list, function(x) min(x["Petal.Length"]))))
ymax <- max(unlist(lapply(d_list, function(x) max(x["Petal.Length"]))))

p.list <- lapply(1:length(unique(iris$Species)), function(i) {
  ggplot(iris[iris$Species == unique(iris$Species)[i], ], aes(x = Sepal.Length, y = Petal.Length)) +
    geom_point() +
    scale_x_continuous(limits = c(xmin, xmax)) +
    scale_y_continuous(limits = c(ymin, ymax)) +
    theme_bw() +
    geom_text(aes(x = min(Sepal.Length), y = max(Petal.Length), label = paste0("R= ", round(rsq[[i]], 2))))
})

cowplot::plot_grid(
  plotlist = p.list[1:3], nrow = 1, ncol = 3,
  labels = "AUTO"
) 

enter image description here

  1. As a second approach you could make use of faceting as I mentioned in my comment. To this end bind your datasets into one and add an id variable. Additionally put the r-square values in a data frame too. Doing so allows you to make your plot using facetting:
library(ggplot2)
library(dplyr)

d_list <- split(iris, iris$Species)

rsq_list <- lapply(d_list, function(x) {
  data.frame(
    rsq = cor(x["Sepal.Length"], x["Petal.Length"])[1, 1]^2,
    Sepal.Length = min(x["Sepal.Length"]),
    Petal.Length = max(x["Petal.Length"])
  )
})

d_bind <- dplyr::bind_rows(d_list)
rsq_bind <- dplyr::bind_rows(rsq_list, .id = "Species")

ggplot(d_bind, aes(x = Sepal.Length, y = Petal.Length)) +
  geom_point() +
  theme_bw() +
  geom_text(data = rsq_bind, aes(label = paste0("R= ", round(rsq, 2)))) +
  facet_wrap(~Species)

enter image description here

Upvotes: 1

Related Questions