2

Here is come basic code for a column plot:

library(tidyverse)

diamonds %>%
  group_by(cut) %>%
  summarise(
    count = n()
  ) %>%
  ggplot(
    aes(
      x = cut,
      y = count,
      fill = count
    )
  ) +
  geom_col() +
  scale_fill_viridis_c(
    option = "plasma"
  )

basic col plot

I could not find any examples of what I would like to do so I will try and explain it as best I can. I have applied a colour gradient to the fill aesthetic which colours the whole column plot one colour. Is it possible to have it such that each column of the plot contains the full colour spectrum up until it's respective value?

By which I mean the "Ideal" column of my plot would look exactly like the key in the legend. Then the "Premium" column would look like the key in the legend but cut off ~2/3 of the way up.

Thanks

Hugh Warden
  • 454
  • 4
  • 14
  • Looks like there's a very complex solution presented [here](https://stackoverflow.com/questions/33965018/ggplot-how-to-produce-a-gradient-fill-within-a-geom-polygon). – caldwellst Feb 03 '22 at 12:14

1 Answers1

4

You can do this fairly easily with a bit of data manipulation. You need to give each group in your original data frame a sequential number that you can associate with the fill scale, and another column the value of 1. Then you just plot using position_stack

library(ggplot2)
library(dplyr)

diamonds %>%
  group_by(cut) %>%
  mutate(fill_col = seq_along(cut), height = 1) %>%
  ggplot(aes(x = cut, y = height, fill = fill_col)) +
  geom_col(position = position_stack()) +
  scale_fill_viridis_c(option = "plasma")

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Convincingly easy! or you can use Teun's wicked function from https://stackoverflow.com/questions/64691000/create-top-to-bottom-fade-gradient-geom-density-in-ggplot2/64695516#64695516 :D – tjebo Feb 03 '22 at 13:38
  • 1
    Yes, that's pretty cool @tjebo, but on this occasion I was surprised myself at how little code it took to generate the intended effect. – Allan Cameron Feb 03 '22 at 13:41
  • 1
    Nice Alan! I definitely agree that this gets the task done with much easier code. – teunbrand Feb 03 '22 at 15:11
  • Thanks @teunbrand. Obviously not as generalizable as the solution of yours that tjebo linked. I had a quick look round ggplot extensions thinking this must have already been implemented somewhere, but can't find it. I know you've done the line equivalent in {elementalist}, but is there a fill version in a CRAN repo that you know of? I suppose it will be easy to implement (or even included in ggplot2) once the graphics devices are updated to support grid's gradient fills (though they don't really fit with the gg manifesto!) – Allan Cameron Feb 03 '22 at 15:20
  • The [ggpattern](https://coolbutuseless.github.io/package/ggpattern/articles/patterns-noise.html) package does this, but its not on CRAN. I think it doesn't (yet) use grid's gradient fills. I don't think there are data-driven gradients out there where (as is in this case), the fill corresponds to the height of a shape. – teunbrand Feb 03 '22 at 16:05