Set asymmetric midpoint for data_color in gt table

1k views Asked by At

I am trying to recreate a simple table from 538 using the gt package. I want to use 0 as the midpoint of the domain of the color scale and set that to white but 0 is not the midpoint of the actual domain.

df <- tribble(
  ~SEASON, ~ACC, ~BIG_10, ~BIG_12, ~PAC_12, ~SEC,
  2019, .02, -.05, 0, .02, .04,
  2018, -.06, .07, .07, .02, .01,
  2017, .05, -.04, .06, .16, .04,
  2016, 0, .05, -.04, -.02, .07,
  2015, .06, -.04, -.03, .01, .06,
  2014, .04, .05, .14, -.01, .06
)

This is what I have attempted to do:

gt(df) %>%
  data_color(
    columns = 2:6,
    colors = scales::col_numeric(
      palette = c('#feb8cd', '#ffffff', '#69cfd5'),
      domain = c(-.06,0, .16)
    )
  )

Table

This does not set the midpoint of the scale as values such as 0.04 are still slightly red/pink. I want those to be blue. I basically want two domains, the negative values (red to white) and positive values (white to blue) is there a way to do this?

1

There are 1 answers

3
Paul On

It looks like scales::col_numeric doesn't look at the individual domain values - it just gets the range and divides it evenly.

You can create your own function which calls one of two col_numeric functions.

pal <- function(x) {
  f_neg <- scales::col_numeric(
    palette = c('#feb8cd', '#ffffff'),
    domain = c(-.06, 0)
  )
  f_pos <- scales::col_numeric(
    palette = c('#ffffff', '#69cfd5'),
    domain = c(0, 0.16)
  )
  ifelse(x < 0, f_neg(x), f_pos(x))
}

gt(df) %>%
  data_color(columns = 2:6, colors = pal)

image