Home > front end >  Find requested colors in custom ggplot2 function
Find requested colors in custom ggplot2 function

Time:03-15

I am trying to build a custom version of scale_color_manual where it uses palettes I have created. I have the function for making and calling the palettes; however, I have a custom way of ordering them that makes is so I can feed in the whole palette to the new scale_color function. I want to know if there is a way to automatically calculate how may colors are being requested in the plot.

Here is some code to explain better: I have a palette generator function that looks a bit like this:

pals <- list(pal_1 = list(c("red", "blue", "yellow", "orange", "green"), c(1, 5, 3, 2, 4)))
pal_fun <- function(name, n){
  pal <- pals[[name]]
  pal_return <- pal[[1]][which(pal[[2]] %in% c(1:n)==TRUE)]
  return(pal_return)
}

If I am building a ggplot with colors from the pal_fun:

library(tidyverse)
ggplot(data=iris, aes(x=Petal.Length, y=Sepal.Length, color=Species))  
   geom_point()  
   scale_color_manual(values=pal_fun("pal_1", 3))

I want to create a custom scale_color_manual function where it directly uses my palette. I need it to request 3 colors, however, because the order matters. I also do not want to have an n parameter in my function, but rather just a way it knows how many colors need to be requested. Essentially, what I need is this:

scale_color_mine <- function(pal, ...){
  #n_ggplot <- CODE TO FIND OUT NUMBER OF COLORS REQUESTED
  scale_color_manual(values=pal_fun(pal, n=n_ggplot))
}

Then, I can simply run:

ggplot(data=iris, aes(x=Petal.Length, y=Sepal.Length, color=Species))  
   geom_point()  
   scale_color_mine("pal_1")

How would I go about doing this?

CodePudding user response:

The answer here is that you don't need to know how many colours ggplot requests. The point of a palette function is that it should itself return a function. The returned function should take a single integer argument, which is the number of colours it should return.

Rather than having an external list as the source of the colours, it would probably be best to have it as an object in the function (though it would still work in this example if it were outside the function). Here, I have added a second set of colours for demonstration purposes:

library(ggplot2)

pal_fun <- function(name) {
  
  pals <- list(pal_1 = list(c("red", "blue", "yellow", "orange", "green"), 
                            c(1, 5, 3, 2, 4)),
               pal_2 = list(c("green4", "cyan3", "violet", "deepskyblue", "gray"), 
                            c(1, 5, 3, 2, 4)))
  pal <- pals[[name]]
  function(n) pal[[1]][which(pal[[2]] %in% c(1:n))]
}

Now you can define your scale function like this:

scale_color_mine <- function(pal = "pal_1", ...) {
  discrete_scale(aesthetics = "colour", scale_name = "mine",
                 palette = pal_fun(pal))
}

So now you can do:

ggplot(data=iris, aes(Petal.Length, Sepal.Length, color = Species))  
   geom_point()  
   scale_color_mine()

and

ggplot(data=iris, aes(x=Petal.Length, y=Sepal.Length, color=Species))  
   geom_point()  
   scale_color_mine(pal = "pal_2")

Created on 2022-03-14 by the enter image description here

  • Related