I wonder if there is the possibility to change the fill main colour according to a categorical variable
我想知道是否有可能根据分类变量改变填充主颜色
Here is a reproducible example
这里有一个可复制的例子
df = data.frame(x = c(rnorm(10, mean = 0),
rnorm(10, mean = 3)),
y = c(rnorm(10, mean = 0),
rnorm(10, mean = 3)),
grp = c(rep('a', times = 10),
rep('b', times = 10)),
val = rep(1:10, times = 2))
ggplot(data = df,
aes(x = x,
y = y)) +
geom_point(pch = 21,
aes(color = grp,
fill = val,
size = val))
Of course it is easy to change the circle colour/shape, according to the variable grp, but I'd like to have the a group in shades of red and the b group in shades of blue. I also thought about using facets, but don't know if the fill gradient can be changed for the two panels.
当然,根据可变的grp很容易改变圆形的颜色/形状,但是我希望a组的颜色是红色,b组的颜色是蓝色。我也考虑过使用facet,但是不知道填充梯度是否可以为这两个面板改变。
Anyone knows if that can be done, without gridExtra?
有没有人知道这是否可以做到,没有格里德斯特拉?
Thanks!
谢谢!
2 个解决方案
#1
2
I think there are two ways to do this. The first is using the alpha
aesthetic for your val
column. This is a quick and easy way to accomplish your goal but may not be exactly what you want:
我认为有两种方法可以做到这一点。第一个是使用阿尔法美学的val列。这是一个快速而简单的方法来实现你的目标,但可能不是你想要的:
ggplot(data = df,
aes(x = x,
y = y)) +
geom_point(pch = 21,
aes(alpha=val,
fill = grp,
size = val)) + theme_minimal()
The second way would be to do something similar to this post: Vary the color gradient on a scatter plot created with ggplot2. I edited the code slightly so its not a range from white to your color of interest but from a lighter color to a darker color. This requires a little bit of work and using the scale_fill_identity
function which basically takes a variable that has the colors you want and maps them directly to each point (so it doesn't do any scaling).
第二种方法与本文类似:在使用ggplot2创建的散点图上改变颜色梯度。我稍微修改了一下代码,所以不是从白色到你感兴趣的颜色,而是从浅色到深色。这需要做一点工作,并使用scale_fill_identity函数,该函数使用一个具有所需颜色的变量,并将它们直接映射到每个点(因此它不做任何缩放)。
This code is:
这段代码是:
#Rescale val to [0,1]
df$scaled_val <- rescale(df$val)
low_cols <- c("firebrick1","deepskyblue")
high_cols <- c("darkred","deepskyblue4")
df$col <- ddply(df, .(grp), function(x)
data.frame(col=apply(colorRamp(c(low_cols[as.numeric(x$grp)[1]], high_cols[as.numeric(x$grp)[1]]))(x$scaled_val),
1,function(x)rgb(x[1],x[2],x[3], max=255)))
)$col
df
ggplot(data = df,
aes(x = x,
y = y)) +
geom_point(pch = 21,
aes(
fill = col,
size = val)) + theme_minimal() +scale_fill_identity()
#2
0
Thanks to this other post I found a way to visualize the fill bar in the legend, even though that wasn't what I meant to do.
多亏了这篇文章,我找到了一种方法,可以在图例中可视化填充条,尽管那不是我想做的。
Here's the ouptup
这是ouptup
And the code
和代码
df = data.frame(x = c(rnorm(10, mean = 0),
rnorm(10, mean = 3)),
y = c(rnorm(10, mean = 0),
rnorm(10, mean = 3)),
grp = factor(c(rep('a', times = 10),
rep('b', times = 10)),
levels = c('a', 'b')),
val = rep(1:10, times = 2)) %>%
group_by(grp) %>%
mutate(scaledVal = rescale(val)) %>%
ungroup %>%
mutate(scaledValOffSet = scaledVal + 100*(as.integer(grp) - 1))
scalerange <- range(df$scaledVal)
gradientends <- scalerange + rep(c(0,100,200), each=2)
ggplot(data = df,
aes(x = x,
y = y)) +
geom_point(pch = 21,
aes(fill = scaledValOffSet,
size = val)) +
scale_fill_gradientn(colours = c('white',
'darkred',
'white',
'deepskyblue4'),
values = rescale(gradientends))
Basically one should rescale fill values (e.g. between 0 and 1) and separate them using another order of magnitude, provided by the categorical variable grp. This is not what I wanted though: the snippet can be improved, of course, to make the whole thing less manual, but still lacks the simple usual discrete fill legend.
基本上,一个人应该重新计算填充值(例如,0和1之间),然后使用另一个数量级,由分类变量grp提供。这并不是我想要的:当然,可以对代码片段进行改进,以减少手工操作,但仍然缺少通常的简单的离散填充传奇。
#1
2
I think there are two ways to do this. The first is using the alpha
aesthetic for your val
column. This is a quick and easy way to accomplish your goal but may not be exactly what you want:
我认为有两种方法可以做到这一点。第一个是使用阿尔法美学的val列。这是一个快速而简单的方法来实现你的目标,但可能不是你想要的:
ggplot(data = df,
aes(x = x,
y = y)) +
geom_point(pch = 21,
aes(alpha=val,
fill = grp,
size = val)) + theme_minimal()
The second way would be to do something similar to this post: Vary the color gradient on a scatter plot created with ggplot2. I edited the code slightly so its not a range from white to your color of interest but from a lighter color to a darker color. This requires a little bit of work and using the scale_fill_identity
function which basically takes a variable that has the colors you want and maps them directly to each point (so it doesn't do any scaling).
第二种方法与本文类似:在使用ggplot2创建的散点图上改变颜色梯度。我稍微修改了一下代码,所以不是从白色到你感兴趣的颜色,而是从浅色到深色。这需要做一点工作,并使用scale_fill_identity函数,该函数使用一个具有所需颜色的变量,并将它们直接映射到每个点(因此它不做任何缩放)。
This code is:
这段代码是:
#Rescale val to [0,1]
df$scaled_val <- rescale(df$val)
low_cols <- c("firebrick1","deepskyblue")
high_cols <- c("darkred","deepskyblue4")
df$col <- ddply(df, .(grp), function(x)
data.frame(col=apply(colorRamp(c(low_cols[as.numeric(x$grp)[1]], high_cols[as.numeric(x$grp)[1]]))(x$scaled_val),
1,function(x)rgb(x[1],x[2],x[3], max=255)))
)$col
df
ggplot(data = df,
aes(x = x,
y = y)) +
geom_point(pch = 21,
aes(
fill = col,
size = val)) + theme_minimal() +scale_fill_identity()
#2
0
Thanks to this other post I found a way to visualize the fill bar in the legend, even though that wasn't what I meant to do.
多亏了这篇文章,我找到了一种方法,可以在图例中可视化填充条,尽管那不是我想做的。
Here's the ouptup
这是ouptup
And the code
和代码
df = data.frame(x = c(rnorm(10, mean = 0),
rnorm(10, mean = 3)),
y = c(rnorm(10, mean = 0),
rnorm(10, mean = 3)),
grp = factor(c(rep('a', times = 10),
rep('b', times = 10)),
levels = c('a', 'b')),
val = rep(1:10, times = 2)) %>%
group_by(grp) %>%
mutate(scaledVal = rescale(val)) %>%
ungroup %>%
mutate(scaledValOffSet = scaledVal + 100*(as.integer(grp) - 1))
scalerange <- range(df$scaledVal)
gradientends <- scalerange + rep(c(0,100,200), each=2)
ggplot(data = df,
aes(x = x,
y = y)) +
geom_point(pch = 21,
aes(fill = scaledValOffSet,
size = val)) +
scale_fill_gradientn(colours = c('white',
'darkred',
'white',
'deepskyblue4'),
values = rescale(gradientends))
Basically one should rescale fill values (e.g. between 0 and 1) and separate them using another order of magnitude, provided by the categorical variable grp. This is not what I wanted though: the snippet can be improved, of course, to make the whole thing less manual, but still lacks the simple usual discrete fill legend.
基本上,一个人应该重新计算填充值(例如,0和1之间),然后使用另一个数量级,由分类变量grp提供。这并不是我想要的:当然,可以对代码片段进行改进,以减少手工操作,但仍然缺少通常的简单的离散填充传奇。