Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

geom_polygon with hex fill color from data

I have a tibble with the following structure:

library(tidyverse)
dmd <- tibble(sample = rep(c(1,2,3), each = 2),
              time   = rep(c(1,2),3),
              score  = c(0.69,0.95,1,0.90,1,0.76)) %>%
  mutate(x = map(base::strsplit(paste(sample,
                                      sample + 0.5,
                                      sample,
                                      sample - 0.5,
                                      sep = ","),
                                split = ","),
                 as.numeric)) %>%
  mutate(y = map(base::strsplit(paste(time + 0.5,
                                      time,
                                      time - 0.5,
                                      time,
                                      sep = ","),
                                split = ","),
                 as.numeric)) %>%
  unnest(c(x,y)) %>%
  group_by(sample,time) %>%
  mutate(group_id = cur_group_id()) %>%
  ungroup
# A tibble: 24 × 6
   sample  time score     x     y group_id
    <dbl> <dbl> <dbl> <dbl> <dbl>    <int>
 1      1     1  0.69   1     1.5        1
 2      1     1  0.69   1.5   1          1
 3      1     1  0.69   1     0.5        1
 4      1     1  0.69   0.5   1          1
 5      1     2  0.95   1     2.5        2
 6      1     2  0.95   1.5   2          2
 7      1     2  0.95   1     1.5        2
 8      1     2  0.95   0.5   2          2
 9      2     1  1      2     1.5        3
10      2     1  1      2.5   1          3
# … with 14 more rows

I then use grDevices::rgb to generate a grayscale hex value dcolor based on score. The if() statement doesn’t do much in this example, but it’s important that I retain this element for the functionalization of my code.

minsc <- min(dmd$score)
thrsh <- 0.75
if (minsc < thrsh) {
  floor <- minsc
} else {
  floor <- thrsh
}

dmd <- dmd %>% mutate(temp = (1 - score) / (1 - floor)) %>%
  mutate(dcolor = grDevices::rgb(temp,temp,temp)) %>%
  dplyr::select(-temp)
# A tibble: 24 × 7
   sample  time score     x     y group_id dcolor 
    <dbl> <dbl> <dbl> <dbl> <dbl>    <int> <chr>  
 1      1     1  0.69   1     1.5        1 #FFFFFF
 2      1     1  0.69   1.5   1          1 #FFFFFF
 3      1     1  0.69   1     0.5        1 #FFFFFF
 4      1     1  0.69   0.5   1          1 #FFFFFF
 5      1     2  0.95   1     2.5        2 #292929
 6      1     2  0.95   1.5   2          2 #292929
 7      1     2  0.95   1     1.5        2 #292929
 8      1     2  0.95   0.5   2          2 #292929
 9      2     1  1      2     1.5        3 #000000
10      2     1  1      2.5   1          3 #000000
# … with 14 more rows

If I plot dmd with geom_polygon, dcolor is interpreted as a factor.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

ggplot(dmd) + 
  geom_polygon(mapping = aes(x = x,
                             y = y,
                             group = group_id,
                             fill = dcolor),
               color = "black") +
  theme_void()

diamonds, wrong

I would like to force ggplot to use the hex values given in dcolor as the fill color for each diamond. Using scale_fill_manual gets me closer, but the colors are still incorrect (#000000 should be black, #FFFFFF should be white).

pal <- dmd %>% dplyr::select(group_id, dcolor) %>%
  unique %>% dplyr::select(dcolor) %>% as_vector

ggplot(dmd) + 
  geom_polygon(mapping = aes(x = x,
                             y = y,
                             group = group_id,
                             fill = dcolor),
               color = "black") +
  scale_fill_manual(values = palette(pal)) +
  theme_void()

diamonds, also wrong

>Solution :

You could achieve your desired result using scale_fill_identity:

library(tidyverse)

ggplot(dmd) + 
  geom_polygon(mapping = aes(x = x,
                             y = y,
                             group = group_id,
                             fill = dcolor),
               color = "black") +
  theme_void() +
  scale_fill_identity(guide = guide_legend())

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading