使用 cowplot 拼凑图时颜色渐变不正确
Incorrect colour gradient when using cowplot to patch together plots
假设我有一个包含 x
和 y
值的数据集,这些值根据两个变量分组:grp
是 a
、b
、或 c
,而 subgrp
是 E
、F
或 G
。
a
在 [0, 1] 中有 y
个值
b
在 [10, 11] 中有 y
个值
c
在 [100, 101] 中有 y
个值。
我想用 y
为所有 grp
和 subgrp
组合定义的点的颜色针对 x
绘制 y
。由于每个 grp
都有非常不同的 y
值,我不能单独使用 facet_grid
,因为色标是没有用的。因此,我用自己的比例绘制每个 grp
,然后将它们与 cowplot
中的 plot_grid
拼接在一起。我还想使用 scale_colour_gradient2
指定的三点渐变。我的代码如下所示:
# Set RNG seed
set.seed(42)
# Toy data frame
df <- data.frame(x = runif(270), y = runif(270) + rep(c(0, 10, 100), each = 90),
grp = rep(letters[1:3], each = 90), subgrp = rep(LETTERS[4:6], 90))
head(df)
#> x y grp subgrp
#> 1 0.9148060 0.1362958 a D
#> 2 0.9370754 0.7853494 a E
#> 3 0.2861395 0.4533034 a F
#> 4 0.8304476 0.1357424 a D
#> 5 0.6417455 0.8852210 a E
#> 6 0.5190959 0.3367135 a F
# Load libraries
library(cowplot)
library(ggplot2)
library(dplyr)
# Plotting list
g_list <- list()
# Loop through groups 'grp'
for(i in levels(df$grp)){
# Subset the data
df_subset <- df %>% filter(grp == i)
# Calculate the midpoint
mp <- mean(df_subset$y)
# Print midpoint
message("Midpoint: ", mp)
g <- ggplot(df_subset) + geom_point(aes(x = x, y = y, colour = y))
g <- g + facet_grid(. ~ subgrp) + ggtitle(i)
g <- g + scale_colour_gradient2(low = "blue", high = "red", mid = "yellow", midpoint = mp)
g_list[[i]] <- g
}
#> Midpoint: 0.460748857570191
#> Midpoint: 10.4696476330981
#> Midpoint: 100.471083269571
plot_grid(plotlist = g_list, ncol = 1)
由 reprex package (v0.2.1)
于 2019-04-17 创建
在此代码中,我将颜色渐变的中点指定为每个 grp
的 y
的平均值。我打印它并验证它是否正确。是的。
我的问题:为什么前两个图的色标不正确?
尽管对数据进行了子集化,但似乎每个 grp
都应用了相同的范围。如果我将 for(i in levels(df$grp)){
替换为 for(i in levels(df$grp)[1]){
,则色阶对于生成的单个图是正确的。
更新
好吧,这很奇怪。在 g_list[[i]] <- g
之前插入 ggplot_build(g)$data[[1]]$colour
可以解决问题。 但是,为什么?
长话短说,您正在创建未评估的承诺,然后在原始数据消失时评估它们。如果您使用适当的函数式编程风格而不是过程代码,通常可以避免这个问题。即,定义一个完成工作的函数,然后为循环使用一个应用函数。
set.seed(42)
# Toy data frame
df <- data.frame(x = runif(270), y = runif(270) + rep(c(0, 10, 100), each = 90),
grp = rep(letters[1:3], each = 90), subgrp = rep(LETTERS[4:6], 90))
library(cowplot)
library(ggplot2)
library(dplyr)
# Loop through groups 'grp'
g_list <- lapply(
levels(df$grp),
function(i) {
# Subset the data
df_subset <- df %>% filter(grp == i)
# Calculate the midpoint
mp <- mean(df_subset$y)
# Print midpoint
message("Midpoint: ", mp)
g <- ggplot(df_subset) + geom_point(aes(x = x, y = y, colour = y))
g <- g + facet_grid(. ~ subgrp) + ggtitle(i)
g <- g + scale_colour_gradient2(low = "blue", high = "red", mid = "yellow", midpoint = mp)
g
}
)
#> Midpoint: 0.460748857570191
#> Midpoint: 10.4696476330981
#> Midpoint: 100.471083269571
plot_grid(plotlist = g_list, ncol = 1)
由 reprex package (v0.2.1)
于 2019-04-17 创建
假设我有一个包含 x
和 y
值的数据集,这些值根据两个变量分组:grp
是 a
、b
、或 c
,而 subgrp
是 E
、F
或 G
。
a
在 [0, 1] 中有 b
在 [10, 11] 中有 c
在 [100, 101] 中有y
个值。
y
个值
y
个值
我想用 y
为所有 grp
和 subgrp
组合定义的点的颜色针对 x
绘制 y
。由于每个 grp
都有非常不同的 y
值,我不能单独使用 facet_grid
,因为色标是没有用的。因此,我用自己的比例绘制每个 grp
,然后将它们与 cowplot
中的 plot_grid
拼接在一起。我还想使用 scale_colour_gradient2
指定的三点渐变。我的代码如下所示:
# Set RNG seed
set.seed(42)
# Toy data frame
df <- data.frame(x = runif(270), y = runif(270) + rep(c(0, 10, 100), each = 90),
grp = rep(letters[1:3], each = 90), subgrp = rep(LETTERS[4:6], 90))
head(df)
#> x y grp subgrp
#> 1 0.9148060 0.1362958 a D
#> 2 0.9370754 0.7853494 a E
#> 3 0.2861395 0.4533034 a F
#> 4 0.8304476 0.1357424 a D
#> 5 0.6417455 0.8852210 a E
#> 6 0.5190959 0.3367135 a F
# Load libraries
library(cowplot)
library(ggplot2)
library(dplyr)
# Plotting list
g_list <- list()
# Loop through groups 'grp'
for(i in levels(df$grp)){
# Subset the data
df_subset <- df %>% filter(grp == i)
# Calculate the midpoint
mp <- mean(df_subset$y)
# Print midpoint
message("Midpoint: ", mp)
g <- ggplot(df_subset) + geom_point(aes(x = x, y = y, colour = y))
g <- g + facet_grid(. ~ subgrp) + ggtitle(i)
g <- g + scale_colour_gradient2(low = "blue", high = "red", mid = "yellow", midpoint = mp)
g_list[[i]] <- g
}
#> Midpoint: 0.460748857570191
#> Midpoint: 10.4696476330981
#> Midpoint: 100.471083269571
plot_grid(plotlist = g_list, ncol = 1)
由 reprex package (v0.2.1)
于 2019-04-17 创建在此代码中,我将颜色渐变的中点指定为每个 grp
的 y
的平均值。我打印它并验证它是否正确。是的。
我的问题:为什么前两个图的色标不正确?
尽管对数据进行了子集化,但似乎每个 grp
都应用了相同的范围。如果我将 for(i in levels(df$grp)){
替换为 for(i in levels(df$grp)[1]){
,则色阶对于生成的单个图是正确的。
更新
好吧,这很奇怪。在 g_list[[i]] <- g
之前插入 ggplot_build(g)$data[[1]]$colour
可以解决问题。 但是,为什么?
长话短说,您正在创建未评估的承诺,然后在原始数据消失时评估它们。如果您使用适当的函数式编程风格而不是过程代码,通常可以避免这个问题。即,定义一个完成工作的函数,然后为循环使用一个应用函数。
set.seed(42)
# Toy data frame
df <- data.frame(x = runif(270), y = runif(270) + rep(c(0, 10, 100), each = 90),
grp = rep(letters[1:3], each = 90), subgrp = rep(LETTERS[4:6], 90))
library(cowplot)
library(ggplot2)
library(dplyr)
# Loop through groups 'grp'
g_list <- lapply(
levels(df$grp),
function(i) {
# Subset the data
df_subset <- df %>% filter(grp == i)
# Calculate the midpoint
mp <- mean(df_subset$y)
# Print midpoint
message("Midpoint: ", mp)
g <- ggplot(df_subset) + geom_point(aes(x = x, y = y, colour = y))
g <- g + facet_grid(. ~ subgrp) + ggtitle(i)
g <- g + scale_colour_gradient2(low = "blue", high = "red", mid = "yellow", midpoint = mp)
g
}
)
#> Midpoint: 0.460748857570191
#> Midpoint: 10.4696476330981
#> Midpoint: 100.471083269571
plot_grid(plotlist = g_list, ncol = 1)
由 reprex package (v0.2.1)
于 2019-04-17 创建