8

Let's start with the viridis palette. In my opinion, colours are a bit just too bright for me, and for my purposes they look too artificial. therefore, I would like to apply some sort of transparency or similar to reduce saturation:

library(nord)
library(scales)
library(viridis)
library(nord)

show_col(viridis(5))
show_col(viridis(5, alpha=.5))

Applying alpha transparency internally seems to work. enter image description here.

However, when run in ggplot, it automatically changes alpha to 1 and plots the original viridis in full intensity:

ggplot(faithfuld, aes(waiting, eruptions)) +
  geom_raster(aes(fill = density)) +
  scale_fill_viridis(5, alpha=.5)

enter image description here

In another example, I found the opposite problem, lack of intensity/saturation. For example, the "aurora" palette from the nord package is great, but it looks a bit faded, lacking some saturation, at least for my purposes.

show_col(nord("aurora",5))

enter image description here

Similarly, I tried to set alpha internally, in this case to 1, but this pruduces a different effect as compared to viridis, changing the palette.

show_col(nord("aurora", alpha=.5))

enter image description here
Alternatively, I have set alpha as alpha(). However, this only changes the color names, but they look the same.

show_col(alpha(nord("aurora",5)), .5)

enter image description here

How can I reduce saturation/intensity in viridisand increase in the nord palettes in ggplot?

Jaap
  • 81,064
  • 34
  • 182
  • 193
fede_luppi
  • 1,063
  • 4
  • 17
  • 29

3 Answers3

8

You can adjust the viridis colors to reduce their saturation without making them transparent. I was hoping you could do this within the viridis function, but it doesn't look like there's a way to do that. Instead, the example below is a function that converts a vector of hexadecimal input colors (we'll create this vector with the viridis function) to the hsv colorspace, adjusts the saturation and value levels and then converts back to hexadecimal.

The approach below is a bit convoluted. There are probably more direct ways to transform between color systems.

vir_lite = function(cols, ds=0.4, dv=0.7) {
  cols = rgb2hsv(col2rgb(cols))
  cols["v", ] = cols["v", ] + dv*(1 - cols["v", ])
  cols["s", ] = ds*cols["s", ]
  apply(cols, 2, function(x) hsv(x[1], x[2], x[3]))
}

Here are the original viridis colors:

show_col(viridis(5))

enter image description here

And the adjusted colors:

show_col(vir_lite(viridis(5)))

enter image description here

You can change the adjusted colors by changing the ds and dv arguments. Now let's use the adjusted colors in the plot:

p = ggplot(faithfuld, aes(waiting, eruptions)) +
      geom_raster(aes(fill = density))

p + scale_fill_gradientn(colors=vir_lite(viridis(5)))

enter image description here

p + scale_fill_gradientn(colors=vir_lite(viridis(5), ds=0.6, dv=0.5))

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • This worked to both decrease saturation in viridis and increase it in nord. Thanks! – fede_luppi Mar 08 '18 at 08:17
  • I'm assuming `ds` is for desaturate, but what is the `dv` variable doing here? – Brandon Nov 29 '20 at 02:20
  • Well, I wrote this answer 2.7 years ago, when I was smarter than I am now, but I think `dv` is the adjustment to the value dimension of the `hsv` color. – eipi10 Nov 29 '20 at 06:00
4

Add your alpha value to the geom_raster() layer:

ggplot(faithfuld, aes(waiting, eruptions)) +
    geom_raster(alpha = 0.5, aes(fill = density)) +
    scale_fill_viridis(5)

enter image description here

De Novo
  • 7,120
  • 1
  • 23
  • 39
  • This works, the problem is that with my real data this applies alpha not only to the fill of geom_raster but also to the other "layers", background, border lines, etc, fading the entire plot – fede_luppi Mar 08 '18 at 07:25
  • What's the call you're using with your real data? You may be able to reset the alpha in those layers to 1. – De Novo Mar 08 '18 at 07:36
1

You have a little typo in your last function. the .5 is within show_col and not within alpha. So within show_col it gets interpret as a rounded 1 and this is boolean TRUE which leads to show the HEX values.

So the correct line would be

show_col(alpha(nord("aurora",5), .5))

And this produces the faint colors.

drmariod
  • 11,106
  • 16
  • 64
  • 110
  • I just realised I didn't read the complete question :-D Just identified the wrong brackets. – drmariod Mar 08 '18 at 06:50
  • Well I stopped with part 1, so between us we solved it :) – De Novo Mar 08 '18 at 06:51
  • Thanks to both! The typo solves the technical aspect of including alpha with the "aurora" palette. However, setting alpha to 1 does not affect the palette. I had the feeling alpha in ´nord´ was set to <1 so adjusting to 1 could increase saturation. But no. So my question still remains: how can I increase saturation (make colours brighter) in the nord palette? – fede_luppi Mar 08 '18 at 07:31
  • Just a comment on the HEX values which were changing using alpha. The normal HEX code has only 3 channels time 2 digits like `#FF3355`, by using alpha, you add a 4th channel to it which is for example `FF` for no transparency and `80` for 50% transparency. – drmariod Mar 08 '18 at 08:21