AlbertRapp / blogComments

0 stars 0 forks source link

posts/ggplot2-tips/07_four_ways_colors_more_efficiently/07_four_ways_colors_more_efficiently #8

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

Albert Rapp - 4 Ways to use colors in ggplot more efficiently

Inspired by a datawrapper blogpost, we explore how to work with fewer colors in ggplot.

https://albert-rapp.de/posts/ggplot2-tips/07_four_ways_colors_more_efficiently/07_four_ways_colors_more_efficiently.html

be-favorite commented 2 years ago

What an excellent article for data scientists/analysts. thanks a lot, Mr.Rapp!

RoyalTS commented 8 months ago

I really like the idea of essentially embedding the legend of the color scale in the text annotation. But mapping colors to values still seems a little manual. Is there a way to extract the value -> color mapping from the ggplot object, and to use that to generate the right annotation automatically?

RoyalTS commented 8 months ago

Actually... this gets the value -> color mapping out:

get_value_to_color_mapping <- function(plot) {
  build <- ggplot2::ggplot_build(plot)

  # extract the color scale from the plot
  scale <- build$plot$scales$get_scales("colour")

  # the numeric values of the variables (ggplot maps even categorical variables to numeric values)
  breaks <- scale$get_breaks()
  # the labels of the variables (i.e. the actual labels of the categorical variable)
  labels <- scale$get_labels()
  # extract the colors corresponding to the breaks
  colors <- scale$map(breaks)

  # return a named vector of labels (values) and colors (names)
  labels |>
    purrr::set_names(colors)
}
AlbertRapp commented 8 months ago

@RoyalTS you can make the colors vector into a named vector. In the glue() call you can then use colors["alone"]. The same strategy also works in geom_text() layers.

RoyalTS commented 8 months ago

Yeah, but that requires I do the color mapping manually. The above potentially lets me use any old scale_color_*(), and then create an appropriate annotation string from it.

AlbertRapp commented 8 months ago

@RoyalTS You can always set the names with names(color) <-. That's what I do most of the time when I create my colors vector (which I pass into scale_fill_manual(). What I do usually, when setting a nice color palette is something like this

groups <- unique(dat$col)
color <- RColorBrewer::brewer.pal(n = length(groups), palette = "Set1")
names(color) <- groups

dat |>
    ggplot() +
    ...

Here, 'dat$col` refers to the thing that I map to the color aesthetic anyway. I think this approach is a little less verbose but in the end the choice is always yours :)

anilyayavar commented 3 months ago

Fantastic post.

anilyayavar commented 3 months ago

I have a question. Can we manipulate color of text labels, in a dynamic way of course, so that the text color is automatic a bit like MS Excel. I mean for darker colors text color should be white and black for lighter. Is it doable?