2

Can ggplot2 be used to create a plot matrix of one set of columns against another set?

For example, with the dataframe below plot all columns beginning with 'x' against all columns beginning with 'y', to produce a grid of plots.

require("tidyverse")

df <- tibble(
  x1 = sample(10),
  x2 = sample(10),
  x3 = sample(10),
  y1 = sample(10),
  y2 = sample(10)
)

And what if, unlike in the example above, the columns are not named in a regular pattern - is there a way that arbitrary sets of columns can be chosen?

Thanks in advance

1
  • 1
    Look at the expand.grid function. It should create all 2-way combinations of an arbitrary set of 2 list names. (It's not a part of tidyverse.) Commented Jan 12, 2018 at 4:34

3 Answers 3

2

You can reshape with tidyr::gather then facet:

df_long <- df %>% 
  gather(x_axis, x, contains("x")) %>% 
  gather(y_axis, y, contains("y"))
# A tibble: 60 x 4
   x_axis     x y_axis     y
    <chr> <int>  <chr> <int>
 1     x1    10     y1     6
 2     x1     6     y1    10
 3     x1     5     y1     3
 4     x1     7     y1     8
 5     x1     8     y1     2
 6     x1     1     y1     1
 7     x1     3     y1     5
 8     x1     9     y1     9
 9     x1     4     y1     7
10     x1     2     y1     4
# ... with 50 more rows

Instead of contains you can use any other tidyverse selection function, or just supply the raw column names.

Then plot:

ggplot(df_long, aes(x, y)) + 
    geom_point() + 
    facet_grid(y_axis ~ x_axis, switch = "both") +
    labs(x = NULL, y = NULL) +
    theme(strip.placement = "outside", strip.background = element_blank())

enter image description here

If you need free scales, you can wrap instead:

ggplot(df_long, aes(x, y)) + 
    geom_point() + 
    facet_wrap(~ interaction(y_axis, x_axis), scales = "free")

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

2

The simplest approach is probably to just loop over all possible combinations, make the respective plot, and then combine all into a grid.

require("tidyverse")

df <- tibble(
  x1 = sample(10),
  x2 = sample(10),
  x3 = sample(10),
  y1 = sample(10),
  y2 = sample(10)
)


group1 <- c("x1", "x2", "x3") # set of variables along x axis
group2 <- c("y1", "y2") # set of variables along y axis

plotlist <- list()
for (x in group1) {
  for (y in group2) {
    p <- ggplot(df, aes_string(x, y)) + geom_point() + ggtitle(paste0(y, " versus ", x))
    plotlist <- append(plotlist, list(p))
  }
}

cowplot::plot_grid(plotlist = plotlist)

enter image description here

The last step here uses the cowplot package, which I wrote. Alternatively, you could use ggarrange from the egg package to place the plots into a grid.

Comments

1

For the sake of completeness, here's a solution that uses ggduo from the GGally package (a function I just became aware of)

require(GGally)    
df %>% ggduo(columnsX = 1:3, columnsY = 4:5)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.