Different colors with gradient for subgroups on a treemap ggplot2 R

前端 未结 2 1186
不思量自难忘°
不思量自难忘° 2020-12-10 16:28

I have a treemap plot (shown below). The only change that I want to have is to change the color of subgroup (YEAR in the plot) to different colors, not all blue. Is this pos

相关标签:
2条回答
  • 2020-12-10 16:42

    It's not the most beautiful solution, but mapping count to alpha simulates a light-to-dark gradient for each color. Add aes(alpha = CNT) inside geom_treemap, and scale alpha however you want.

    library(ggplot2)
    library(treemapify)
    
    PL <- c(rep("PL1",4),rep("PL2",4),rep("PL3",4),rep("PL4",4))
    CNT <- sample(seq(1:50),16)
    YEAR <- rep(c("2015","2016","2017","2018"),4)
    
    df <- data.frame(PL,YEAR,CNT)
    
    ggplot(df, aes(area = CNT, fill = YEAR, label=PL, subgroup=YEAR)) +
    
    # change this line
        geom_treemap(aes(alpha = CNT)) +
        geom_treemap_subgroup_border(colour="white") +
        geom_treemap_text(fontface = "italic",
                                            colour = "white",
                                            place = "centre",
                                            grow = F,
                                            reflow=T) +
        geom_treemap_subgroup_text(place = "centre",
                                                             grow = T,
                                                             alpha = 0.5,
                                                             colour = "#FAFAFA",
                                                             min.size = 0) +
        scale_alpha_continuous(range = c(0.2, 1))
    

    Created on 2018-05-03 by the reprex package (v0.2.0).

    Edit to add: Based on this post on hacking faux-gradients by putting an alpha-scaled layer on top of a layer with a darker fill. Here I've used two geom_treemaps, one with fill = "black", and one with the alpha scaling. Still leaves something to be desired.

    ggplot(df, aes(area = CNT, fill = YEAR, label=PL, subgroup=YEAR)) +
        geom_treemap(fill = "black") +
        geom_treemap(aes(alpha = CNT)) +
        geom_treemap_subgroup_border(colour="white") +
        geom_treemap_text(fontface = "italic",
                                            colour = "white",
                                            place = "centre",
                                            grow = F,
                                            reflow=T) +
        geom_treemap_subgroup_text(place = "centre",
                                                             grow = T,
                                                             alpha = 0.5,
                                                             colour = "#FAFAFA",
                                                             min.size = 0) +
        scale_alpha_continuous(range = c(0.4, 1))
    

    Created on 2018-05-03 by the reprex package (v0.2.0).

    0 讨论(0)
  • 2020-12-10 16:52

    One option is to calculate the colors separately for each cell and then just plot them directly. This doesn't give you a legend, but arguably a legend isn't that useful anyways. (You'd need 4 separate legends, and those could be made and added to the plot if needed.)

    library(ggplot2)
    library(treemapify)
    
    set.seed(342)
    PL <- c(rep("PL1", 4), rep("PL2", 4), rep("PL3", 4), rep("PL4", 4))
    CNT <- sample(seq(1:50), 16)
    YEAR <- rep(c("2015", "2016", "2017", "2018"), 4)
    
    df <- data.frame(PL, YEAR, CNT)
    
    # code to add colors to data frame follows
    # first the additional packages needed
    library(dplyr)
    library(colorspace)  # install via: install.packages("colorspace", repos = "http://R-Forge.R-project.org")
    library(scales)
    
    # I'll use 4 palettes from the colorspace package, one for each year
    palette <- rep(c("Teal", "Red-Yellow", "Greens", "Purples"), 4)
    
    # We add the palette names and then calculate the colors for each
    # data point. Two notes:
    #  - we scale the colors to the maximum CNT in each year
    #  - we're calculating 6 colors but use only 5 to make the gradient;
    #    this removes the lightest color
    df2 <- mutate(df,
                  palette = palette) %>%
      group_by(palette) %>%
      mutate(
        max_CNT = max(CNT),
        color = gradient_n_pal(sequential_hcl(6, palette = palette)[1:5])(CNT/max_CNT))
    
    
    ggplot(df2, aes(area = CNT, fill = color, label=PL, subgroup=YEAR)) +
      geom_treemap() +
      geom_treemap_subgroup_border(colour="white") +
      geom_treemap_text(fontface = "italic",
                        colour = "white",
                        place = "centre",
                        grow = F,
                        reflow=T) +
      geom_treemap_subgroup_text(place = "centre",
                                 grow = T,
                                 alpha = 0.5,
                                 colour = "#FAFAFA",
                                 min.size = 0) +
      scale_fill_identity()
    

    It's also possible to generate color scales dynamically if you don't know ahead of time how many cases there will be:

    library(ggplot2)
    library(treemapify)
    
    set.seed(341)
    PL <- c(rep("PL1", 6), rep("PL2", 6), rep("PL3", 6), rep("PL4", 6))
    CNT <- sample(seq(1:50), 24)
    YEAR <- rep(c("2013", "2014", "2015", "2016", "2017", "2018"), 4)
    
    df <- data.frame(PL, YEAR, CNT)
    
    # code to add colors to data frame follows
    # first the additional packages needed
    library(dplyr)
    library(colorspace)  # install via: install.packages("colorspace", repos = "http://R-Forge.R-project.org")
    library(scales)
    
    # number of palettes needed
    n <- length(unique(YEAR))
    
    # now calculate the colors for each data point
    df2 <- df %>%
      mutate(index = as.numeric(factor(YEAR))- 1) %>%
      group_by(index) %>%
      mutate(
        max_CNT = max(CNT),
        color = gradient_n_pal(
          sequential_hcl(
            6,
            h = 360 * index[1]/n,
            c = c(45, 20),
            l = c(30, 80),
            power = .5)
          )(CNT/max_CNT)
        )
    
    ggplot(df2, aes(area = CNT, fill = color, label=PL, subgroup=YEAR)) +
      geom_treemap() +
      geom_treemap_subgroup_border(colour="white") +
      geom_treemap_text(fontface = "italic",
                        colour = "white",
                        place = "centre",
                        grow = F,
                        reflow=T) +
      geom_treemap_subgroup_text(place = "centre",
                                 grow = T,
                                 alpha = 0.5,
                                 colour = "#FAFAFA",
                                 min.size = 0) +
      scale_fill_identity()
    

    Finally, you can manually define the hues of the color scales:

    library(ggplot2)
    library(treemapify)
    
    set.seed(341)
    PL <- c(rep("PL1", 6), rep("PL2", 6), rep("PL3", 6), rep("PL4", 6))
    CNT <- sample(seq(1:50), 24)
    YEAR <- rep(c("2013", "2014", "2015", "2016", "2017", "2018"), 4)
    
    df <- data.frame(PL, YEAR, CNT)
    
    # code to add colors to data frame follows
    # first the additional packages needed
    library(dplyr)
    library(colorspace)  # install via: install.packages("colorspace", repos = "http://R-Forge.R-project.org")
    library(scales)
    
    # each color scale is defined by a hue, a number between 0 and 360
    hues <- c(300, 50, 250, 100, 200, 150)
    
    # now calculate the colors for each data point
    df2 <- df %>%
      mutate(index = as.numeric(factor(YEAR))) %>%
      group_by(index) %>%
      mutate(
        max_CNT = max(CNT),
        color = gradient_n_pal(
          sequential_hcl(
            6,
            h = hues[index[1]],
            c = c(45, 20),
            l = c(30, 80),
            power = .5)
        )(CNT/max_CNT)
      )
    
    ggplot(df2, aes(area = CNT, fill = color, label=PL, subgroup=YEAR)) +
      geom_treemap() +
      geom_treemap_subgroup_border(colour="white") +
      geom_treemap_text(fontface = "italic",
                        colour = "white",
                        place = "centre",
                        grow = F,
                        reflow=T) +
      geom_treemap_subgroup_text(place = "centre",
                                 grow = T,
                                 alpha = 0.5,
                                 colour = "#FAFAFA",
                                 min.size = 0) +
      scale_fill_identity()
    

    0 讨论(0)
提交回复
热议问题