Gem_rect颜色在ggplot中不保持不变

时间:2018-04-03 20:28:22

标签: r ggplot2

我正在设计一个闪亮的应用程序,该应用程序基于四分位数为各种类型的数据创建图表。该应用运行良好,但是,我注意到我创建的图中的颜色不是保持不变,使用geom_rect

我在下面的代码中会生成两个图表。

第一个情节有一点点"褪色"感觉到,与第二个情节相比,它具有更柔和的色彩。看到我如何使用相同的过程创建它们,我不确定为什么颜色不匹配。它好像alpha值已经改变,或者颜色值本身。

这似乎只发生在我的闪亮应用程序中有两个或更少的类别,但我只是在墙上试图弄清楚我在这里做错了什么。关于为什么这两个图上的颜色不同的任何想法?

library('tidyverse')

df <- structure(list(grade = c(1L, 1L, 2L, 2L, 2L, 2L), 
                     benchmark = c("C","D", "B", "C", "D", "F"), 
                     count = c(22L, 15L, 32L, 168L, 117L, 41L), 
                     min = c(155, 169, 154, 160, 164, 178), 
                     q05 = c(163.1, 170.4,161.6, 164.3, 169.8, 179), 
                     q10 = c(165, 172.6, 165.2, 169, 172.6,180), 
                     q15 = c(165, 175.1, 167, 171.1, 176, 181), 
                     q20 = c(165, 175.8, 167.2, 173.4, 177.2, 182), 
                     q25 = c(165.2, 176, 169.5, 174.8, 180, 184), 
                     q30 = c(166, 176.4, 171, 176, 182, 184), 
                     q35 = c(166, 177.8, 171.8, 177, 183, 185), 
                     q40 = c(166.4, 178, 172, 179, 183, 186), 
                     q45 = c(167.4, 178.3, 172.9, 180, 185, 187), 
                     q50 = c(168, 179, 174.5, 181, 186, 188), 
                     q55 = c(171.3, 182.5, 176.1, 181.8, 187, 189), 
                     q60 = c(174.6, 184, 177, 183, 187, 190), 
                     q65 = c(175, 184.2, 177, 183.6, 188, 192), 
                     q70 = c(176.4, 185.6, 177.7, 185, 190, 192),
                     q75 = c(177, 187, 179, 185, 191, 194), 
                     q80 = c(177.8, 188.4, 180.6, 187, 191, 194), 
                     q85 = c(178.8, 189.8, 182.1, 188, 192.6, 195), 
                     q90 = c(186.2, 193, 186.7, 190, 194.4, 199), 
                     q95 = c(187, 196.8, 187.4, 192, 197, 201), 
                     max = c(194, 201, 188, 203, 210, 206)), 
                .Names = c("grade", "benchmark", "count", "min", "q05", 
                           "q10", "q15", "q20", "q25", "q30", "q35", "q40", "q45", "q50", 
                           "q55", "q60", "q65", "q70", "q75", "q80", "q85", "q90", "q95", 
                           "max"), 
                row.names = c(137L, 138L, 310L, 311L, 312L, 313L), 
                class = "data.frame")

#### Grade 1 Graph ########################################################################

# Sets up temporary data frame
temp <- df[df$grade == 1, ]

# Sets widths for geom_rect later.
for(i in seq(from = 1, to = nrow(temp), by = 1)){
  temp$xmin[i] <- i - 1 + .55
  temp$xmax[i] <- i + .45
}

ggplot(temp, aes(x = benchmark)) +
  geom_boxplot(aes(lower = q20, middle = q50, upper = q80, ymax = max, ymin = min), stat = 'identity') +
  scale_y_continuous(breaks = seq((min(temp$min)%/%10 * 10), (max(temp$max)%/%10 * 10 + 10), 10),
                     limits = c((min(temp$min)%/%10 * 10), (max(temp$max)%/%10 * 10 + 10))) +
  labs(x = 'Category', y = 'Values', title = 'Percentile Boxplots') +
  theme(axis.text = element_text(size = 12),
        axis.title = element_text(size = 14),
        title = element_text(size = 16)) +

  ## Geom_rect for Category C
  geom_rect(aes(xmin = temp[temp$benchmark == 'C', ]$xmin, xmax = temp[temp$benchmark == 'C', ]$xmax,
                ymin = temp[temp$benchmark == 'C', ]$q20, ymax = temp[temp$benchmark == 'C', ]$q40),
            alpha = .15, fill = '#FFFF00') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'C', ]$xmin, xmax = temp[temp$benchmark == 'C', ]$xmax,
                ymin = temp[temp$benchmark == 'C', ]$q40, ymax = temp[temp$benchmark == 'C', ]$q60),
            alpha = .15, fill = '#92D050') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'C', ]$xmin, xmax = temp[temp$benchmark == 'C', ]$xmax,
                ymin = temp[temp$benchmark == 'C', ]$q60, ymax = temp[temp$benchmark == 'C', ]$q80),
            alpha = .15, fill = '#00B050') +

  ## Geom_rect for Category D
  geom_rect(aes(xmin = temp[temp$benchmark == 'D', ]$xmin, xmax = temp[temp$benchmark == 'D', ]$xmax,
                ymin = temp[temp$benchmark == 'D', ]$q20, ymax = temp[temp$benchmark == 'D', ]$q40),
            alpha = .15, fill = '#FFFF00') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'D', ]$xmin, xmax = temp[temp$benchmark == 'D', ]$xmax,
                ymin = temp[temp$benchmark == 'D', ]$q40, ymax = temp[temp$benchmark == 'D', ]$q60),
            alpha = .15, fill = '#92D050') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'D', ]$xmin, xmax = temp[temp$benchmark == 'D', ]$xmax,
                ymin = temp[temp$benchmark == 'D', ]$q60, ymax = temp[temp$benchmark == 'D', ]$q80),
            alpha = .15, fill = '#00B050') +

  ## Geom_labels for quartiles.
  geom_label(aes(x = benchmark, y = q20, label = round(q20, 1)), fill = '#fdae61', size = 4) +
  geom_label(aes(x = benchmark, y = q80, label = round(q80, 1)), fill = '#a6d96a', size = 4) +
  geom_label(aes(x = benchmark, y = q50, label = round(q50, 1), fontface = 'bold'), fill = '#ffffbf', size = 5) +
  coord_flip() 

#### Grade 2 Graph ####

temp <- df[df$grade == 2, ]

for(i in seq(from = 1, to = nrow(temp), by = 1)){
  temp$xmin[i] <- i - 1 + .55
  temp$xmax[i] <- i + .45
}

ggplot(temp, aes(x = benchmark)) +
  geom_boxplot(aes(lower = q20, middle = q50, upper = q80, ymax = max, ymin = min), stat = 'identity') +
  scale_y_continuous(breaks = seq((min(temp$min)%/%10 * 10), (max(temp$max)%/%10 * 10 + 10), 10),
                     limits = c((min(temp$min)%/%10 * 10), (max(temp$max)%/%10 * 10 + 10))) +
  labs(x = 'Category', y = 'Values', title = 'Percentile Boxplots') +
  theme(axis.text = element_text(size = 12),
        axis.title = element_text(size = 14),
        title = element_text(size = 16)) +

  ## Geom_rect for Category B
  geom_rect(aes(xmin = temp[temp$benchmark == 'B', ]$xmin, xmax = temp[temp$benchmark == 'B', ]$xmax,
                ymin = temp[temp$benchmark == 'B', ]$q20, ymax = temp[temp$benchmark == 'B', ]$q40),
            alpha = .15, fill = '#FFFF00') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'B', ]$xmin, xmax = temp[temp$benchmark == 'B', ]$xmax,
                ymin = temp[temp$benchmark == 'B', ]$q40, ymax = temp[temp$benchmark == 'B', ]$q60),
            alpha = .15, fill = '#92D050') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'B', ]$xmin, xmax = temp[temp$benchmark == 'B', ]$xmax,
                ymin = temp[temp$benchmark == 'B', ]$q60, ymax = temp[temp$benchmark == 'B', ]$q80),
            alpha = .15, fill = '#00B050') +

  ## Geom_rect for Category C
  geom_rect(aes(xmin = temp[temp$benchmark == 'C', ]$xmin, xmax = temp[temp$benchmark == 'C', ]$xmax,
                ymin = temp[temp$benchmark == 'C', ]$q20, ymax = temp[temp$benchmark == 'C', ]$q40),
            alpha = .15, fill = '#FFFF00') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'C', ]$xmin, xmax = temp[temp$benchmark == 'C', ]$xmax,
                ymin = temp[temp$benchmark == 'C', ]$q40, ymax = temp[temp$benchmark == 'C', ]$q60),
            alpha = .15, fill = '#92D050') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'C', ]$xmin, xmax = temp[temp$benchmark == 'C', ]$xmax,
                ymin = temp[temp$benchmark == 'C', ]$q60, ymax = temp[temp$benchmark == 'C', ]$q80),
            alpha = .15, fill = '#00B050') +

  ## Geom_rect for Category D
  geom_rect(aes(xmin = temp[temp$benchmark == 'D', ]$xmin, xmax = temp[temp$benchmark == 'D', ]$xmax,
                ymin = temp[temp$benchmark == 'D', ]$q20, ymax = temp[temp$benchmark == 'D', ]$q40),
            alpha = .15, fill = '#FFFF00') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'D', ]$xmin, xmax = temp[temp$benchmark == 'D', ]$xmax,
                ymin = temp[temp$benchmark == 'D', ]$q40, ymax = temp[temp$benchmark == 'D', ]$q60),
            alpha = .15, fill = '#92D050') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'D', ]$xmin, xmax = temp[temp$benchmark == 'D', ]$xmax,
                ymin = temp[temp$benchmark == 'D', ]$q60, ymax = temp[temp$benchmark == 'D', ]$q80),
            alpha = .15, fill = '#00B050') +

  ## Geom_rect for Category F
  geom_rect(aes(xmin = temp[temp$benchmark == 'F', ]$xmin, xmax = temp[temp$benchmark == 'F', ]$xmax,
                ymin = temp[temp$benchmark == 'F', ]$q20, ymax = temp[temp$benchmark == 'F', ]$q40),
            alpha = .15, fill = '#FFFF00') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'F', ]$xmin, xmax = temp[temp$benchmark == 'F', ]$xmax,
                ymin = temp[temp$benchmark == 'F', ]$q40, ymax = temp[temp$benchmark == 'F', ]$q60),
            alpha = .15, fill = '#92D050') +
  geom_rect(aes(xmin = temp[temp$benchmark == 'F', ]$xmin, xmax = temp[temp$benchmark == 'F', ]$xmax,
                ymin = temp[temp$benchmark == 'F', ]$q60, ymax = temp[temp$benchmark == 'F', ]$q80),
            alpha = .15, fill = '#00B050') +

  ## Geom_labels for quartiles.
  geom_label(aes(x = benchmark, y = q20, label = round(q20, 1)), fill = '#fdae61', size = 4) +
  geom_label(aes(x = benchmark, y = q80, label = round(q80, 1)), fill = '#a6d96a', size = 4) +
  geom_label(aes(x = benchmark, y = q50, label = round(q50, 1), fontface = 'bold'), fill = '#ffffbf', size = 5) +
  coord_flip() 

1 个答案:

答案 0 :(得分:1)

针对特定类别的每个geom_rect()调用实际上创建了多个相互重叠的矩形,每个矩形都有alpha = .15,因此整体颜色变得更加强烈。

而不是:

# temp here is based on the second plot, with 4 categories
p.overlay <- ggplot(temp) +

  ## Geom_rect for Category B
  geom_rect(aes(xmin = temp[temp$benchmark == 'B', ]$xmin, 
                xmax = temp[temp$benchmark == 'B', ]$xmax,
                ymin = temp[temp$benchmark == 'B', ]$q20, 
                ymax = temp[temp$benchmark == 'B', ]$q40),
            alpha = .15, fill = '#FFFF00') +

  ## Geom_rect for Category C
  geom_rect(aes(xmin = temp[temp$benchmark == 'C', ]$xmin, 
                xmax = temp[temp$benchmark == 'C', ]$xmax,
                ymin = temp[temp$benchmark == 'C', ]$q20, 
                ymax = temp[temp$benchmark == 'C', ]$q40),
            alpha = .15, fill = '#FFFF00') +

  ## Geom_rect for Category D
  geom_rect(aes(xmin = temp[temp$benchmark == 'D', ]$xmin, 
                xmax = temp[temp$benchmark == 'D', ]$xmax,
                ymin = temp[temp$benchmark == 'D', ]$q20, 
                ymax = temp[temp$benchmark == 'D', ]$q40),
            alpha = .15, fill = '#FFFF00') +

  ## Geom_rect for Category F
  geom_rect(aes(xmin = temp[temp$benchmark == 'F', ]$xmin, 
                xmax = temp[temp$benchmark == 'F', ]$xmax,
                ymin = temp[temp$benchmark == 'F', ]$q20, 
                ymax = temp[temp$benchmark == 'F', ]$q40),
            alpha = .15, fill = '#FFFF00')

尝试:

p.single <- ggplot(temp) +

  geom_rect(aes(xmin = xmin, xmax = xmax, ymin = q20, ymax = q40),
            alpha = .15, fill = "#FFFF00")

比较结果:

cowplot::plot_grid(p.overlay, p.single, labels = c("Overlay", "Single"))

comparison plot

<强>解释

如果我们查看p.overlayp.single的结构,我们可以看到每个geom_rect()创建了一个单独的图层:

> length(p.overlay$layers)
[1] 4
> length(p.single$layers)
[1] 1

layer_data()返回与每个特定图层相关联的数据,我们可以看到p.overlay中的每个矩形图层实际上与四个相关联相同的重叠矩形(对于同一类别),而p.single中的矩形层与四个不同的矩形相关联,每个矩形用于不同的类别:

> lapply(1:4, function(i) layer_data(p.overlay, i))
[[1]]
  xmin xmax  ymin ymax PANEL group colour    fill size linetype alpha
1 0.55 1.45 167.2  172     1    -1     NA #FFFF00  0.5        1  0.15
2 0.55 1.45 167.2  172     1    -1     NA #FFFF00  0.5        1  0.15
3 0.55 1.45 167.2  172     1    -1     NA #FFFF00  0.5        1  0.15
4 0.55 1.45 167.2  172     1    -1     NA #FFFF00  0.5        1  0.15

[[2]]
  xmin xmax  ymin ymax PANEL group colour    fill size linetype alpha
1 1.55 2.45 173.4  179     1    -1     NA #FFFF00  0.5        1  0.15
2 1.55 2.45 173.4  179     1    -1     NA #FFFF00  0.5        1  0.15
3 1.55 2.45 173.4  179     1    -1     NA #FFFF00  0.5        1  0.15
4 1.55 2.45 173.4  179     1    -1     NA #FFFF00  0.5        1  0.15

[[3]]
  xmin xmax  ymin ymax PANEL group colour    fill size linetype alpha
1 2.55 3.45 177.2  183     1    -1     NA #FFFF00  0.5        1  0.15
2 2.55 3.45 177.2  183     1    -1     NA #FFFF00  0.5        1  0.15
3 2.55 3.45 177.2  183     1    -1     NA #FFFF00  0.5        1  0.15
4 2.55 3.45 177.2  183     1    -1     NA #FFFF00  0.5        1  0.15

[[4]]
  xmin xmax ymin ymax PANEL group colour    fill size linetype alpha
1 3.55 4.45  182  186     1    -1     NA #FFFF00  0.5        1  0.15
2 3.55 4.45  182  186     1    -1     NA #FFFF00  0.5        1  0.15
3 3.55 4.45  182  186     1    -1     NA #FFFF00  0.5        1  0.15
4 3.55 4.45  182  186     1    -1     NA #FFFF00  0.5        1  0.15

> layer_data(p.single, i = 1)
  xmin xmax  ymin ymax PANEL group colour    fill size linetype alpha
1 0.55 1.45 167.2  172     1    -1     NA #FFFF00  0.5        1  0.15
2 1.55 2.45 173.4  179     1    -1     NA #FFFF00  0.5        1  0.15
3 2.55 3.45 177.2  183     1    -1     NA #FFFF00  0.5        1  0.15
4 3.55 4.45 182.0  186     1    -1     NA #FFFF00  0.5        1  0.15

为什么一切都重复了四次?因为顶级ggplot()调用指定temp作为默认继承的所有后续geom的数据源,并且它有四行。如果我们使用了为第一个绘图生成的temp数据框,那么一切都会重复两次。

为了避免这种现象,我建议采用上面p.single中演示的方法,&amp;使用一个geom_rect()为所有类别指定填充颜色。代码更短,更清晰,更灵活,可以更改类别编号/标签。

如果您有充分的理由为每个类别定义单独的geom_rect(),请不要在顶级ggplot()调用中指定任何数据框。根据您的原始代码,只有geom_boxplot()仍然使用它,因此您可以在那里指定data = temp

(以上演示适用于q20-q40矩形,但其余原则同样适用。)