在ggplot中混合颜色和填充美学。

时间:2023-02-09 20:26:54

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))

在ggplot中混合颜色和填充美学。

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()

在ggplot中混合颜色和填充美学。

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()

在ggplot中混合颜色和填充美学。

#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

在ggplot中混合颜色和填充美学。

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()

在ggplot中混合颜色和填充美学。

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()

在ggplot中混合颜色和填充美学。

#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

在ggplot中混合颜色和填充美学。

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提供。这并不是我想要的:当然,可以对代码片段进行改进,以减少手工操作,但仍然缺少通常的简单的离散填充传奇。