teunbrand / ggchromatic

Colour and fill scales for 'ggplot2' using colour spaces.
https://teunbrand.github.io/ggchromatic/
Other
11 stars 1 forks source link

Add example for custom color space #12

Open Raoul-Kima opened 2 years ago

Raoul-Kima commented 2 years ago

I think custom color scales are important for multidimensional color scales, because different colorspaces imply different dependencies of the differente channels amongst each other, and create different "perceptual correlations" in the viewer. Therefore being able to create a custom made colorspace for a particular application is useful. When trying to do so with the package I first had the impression that it is very difficult to do due to its (at first sight) tight integration with the farver package, which quickly leads one to calls of c/c++ functions. Then later I found out that it's actually quite simple to implement a custom colorspace. It would be great it the welcome page listed one such example to show how simple it can be and to give users a headstart. Here's a simple example, probably not in full production quality. It could be used as a basis to make a good example for the starting page.

library(tidyverse)
library(ggchromatic)

# define a custom palette function
ab_spec=
    function(observationEffort=double(),nDetections=double()){
        ggchromatic:::new_colour_spec(
            observationEffort=observationEffort
            ,nDetections=nDetections
            ,class="ab_spec"
            )
    }
ab_palette=
    function (x, min = 0, max = 1) 
    {
        x=as.matrix(x)
        # print(x)
        out=character(nrow(x))
        inputsWithNA=is.na(x[,"observationEffort"])|is.na(x[,"nDetections"]) # only run rgb() on inputs without NA, as it doesnt have NA-handling implemented. return NA for all inputs that contain NA in any channel.
        out[inputsWithNA]=NA
        out[!inputsWithNA]=rgb(x[!inputsWithNA,"observationEffort"],x[!inputsWithNA,"nDetections"],1-x[!inputsWithNA,"observationEffort"])
        out
    }

# apply the custom palette
n=30
tibble(observationEffort=(1:n)/n,nDetections=runif(n)) %>% 
    ggplot()+
    geom_point(
        aes(
            observationEffort
            ,nDetections
            ,colour=ab_spec(observationEffort,nDetections)
        )
    )+
    chromatic_scale(
        aesthetics="colour"
        ,name=c("observation effort","number of\ndetections")
        ,scale_name="ab_scale"
        ,palette=ab_palette
        ,prototype=ab_spec
        ,limits=
            list(
                observationEffort=c(0,1)
                ,nDetections=c(0,1)
                )
        ,channel_limits=ab_spec(0:1,0:1)
        ,expand=0
    )