Different colourbar for each facet in ggplot figure
Asked Answered
J

3

4

Say, I make a gpplot2 plot like the following with several facets:

ggplot(iris) + 
  geom_tile(aes(x = Petal.Width, fill = Sepal.Width, y = Petal.Length)) +
  facet_wrap(~Species)

Note that there is one colourbar for all three plots, but each facet could potentially have a very different values. Is it possible to have a separate colourbar for each facet?

enter image description here

Jeaz answered 14/7, 2017 at 18:10 Comment(2)
I think the point of small multiples (facetting) is to be able to compare and contrast different subgroups; having different colour scales kind of negates the intent. With that in mind, I think a solution to your problem would be to create individual plots, and display them side-by-side on a common page.Gaffrigged
I think you're right. The real plot isn't really subgroups, just stuff I'd like to show together, so perhaps individual plots is the way to go. I was just trying to be a bit more concise with my code and this seemed an easy way to go.Jeaz
D
3

I agree with Alex's answer, but against my better scientific and design judgment, I took a stab at it.

require(gridExtra)
require(dplyr)

iris %>% group_by(Species) %>% 
  do(gg = {ggplot(., aes(Petal.Width, Petal.Length, fill = Sepal.Width)) + 
      geom_tile() + facet_grid(~Species) + 
      guides(fill = guide_colourbar(title.position = "top")) +
      theme(legend.position = "top")}) %>% 
  .$gg %>% arrangeGrob(grobs = ., nrow = 1) %>% grid.arrange()

enter image description here

Of course, then you're duplicating lots of labels, which is annoying. Additionally, you lose the x and y scale information by plotting each species as a separate plot, instead of facets of a single plot. You could fix the axes by adding ... + coord_cartesian(xlim = range(iris$Petal.Width), ylim = range(iris$Petal.Length)) + ... within that ggplot call.

To be honest, the only way this makes sense at all is if it's comparing two different variables for the fill, which is why you don't care about comparing their true value between plots. A good alternative would be rescaling them to percentiles within a facet using dplyr::group_by() and dplyr::percent_rank.


Edited to update:

In the two-different-variables case, you have to first "melt" the data, which I assume you've already done. Here I'm repeating it with the iris data. Then you can look at the relative values by examining the percentiles, rather than the absolute values of the two variables.

iris %>% 
  tidyr::gather(key = Sepal.measurement, 
                value = value, 
                Sepal.Length, Sepal.Width) %>% 
  group_by(Sepal.measurement) %>% 
  mutate(percentilevalue = percent_rank(value)) %>% 
  ggplot(aes(Petal.Length, Petal.Width)) + 
  geom_tile(aes(fill = percentilevalue)) + 
  facet_grid(Sepal.measurement ~ Species) + 
  scale_fill_continuous(limits = c(0,1), labels = scales::percent)

enter image description here

Dominga answered 14/7, 2017 at 20:9 Comment(1)
Thanks, @Brian. The things I'm plotting are actually different variables, so it makes sense to have different scales. I was just trying to be as brief as possible in my code and facet_wrap seemed like an easy shortcut.Jeaz
S
2

Separate palettes for facets in ggplot facet_grid

It has been asked before. This is the best solution I have seen so far, however I think having a common palette is more ideal from a visualization standpoint.

Schurman answered 14/7, 2017 at 18:18 Comment(2)
I don't think this is quite the same thing I'm asking, as the colourbar is the same for all plots in that solution.Jeaz
The proposed solution in https://mcmap.net/q/1395371/-separate-palettes-for-facets-in-ggplot-facet_grid "[fakes] a colour scale with transparency". It uses the alpha aesthetic to create the gradient and then sets a color for each facet.Slushy
L
0

the colour scheme

If this is what you want then there is a simple hack to it.

tf1 <- iris
tf1$COL <- rep(1:50, each=3)

ggplot(tf1) + 
  geom_tile(aes(x = Petal.Width, fill = interaction(Petal.Length,COL), y = Petal.Length)) +
  facet_wrap(~Species, scales = "free") + theme(legend.position="none")
Linalinacre answered 2/9, 2022 at 5:53 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.