我们如何在单个图表中使用多个geom_smooth?

时间:2021-11-01 00:54:00

I would like to use multiple geom_smooth layers in a single ggplot2 chart. When I try to do that, the color scheme gets screwed up. Here is an example demonstrating what is happening.

我想在一个ggplot2图表中使用多个geom_smooth图层。当我尝试这样做时,配色方案搞砸了。这是一个展示正在发生的事情的例子。

We construct a simple dataframe we want to visualize.

我们构建了一个我们想要可视化的简单数据帧。

df = data.frame(x = c("a", "b", "c"),
             y1 = seq(1, 3),
             y1_upr = seq(2, 4),
             y1_lwr = seq(0, 2),
             y2 = seq(2, 4),
             y2_upr = seq(2.5, 4.5),
             y2_lwr = seq(1.5, 3.5))

We can visualize y1 and y2 easily.

我们可以轻松地将y1和y2可视化。

plot_obj = ggplot(data = df, aes(x = x, group = 1)) + 
  geom_line(aes(y = y1, colour = "y1")) + 
  geom_line(aes(y = y2, colour = "y2")) +     
  scale_colour_manual("", breaks = c("y1", "y2"), values = c("blue", "red"))
plot_obj

我们如何在单个图表中使用多个geom_smooth? If we add one geom_smooth, the behavior is still as expected.

如果我们添加一个geom_smooth,行为仍然符合预期。

plot_obj + 
  geom_smooth(aes(y = y1, ymin = y1_lwr, ymax = y1_upr), stat="identity", fill="blue", alpha=0.2)

我们如何在单个图表中使用多个geom_smooth? Lastly, we add the second geom_smooth layer.

最后,我们添加第二个geom_smooth图层。

plot_obj + 
  geom_smooth(aes(y = y1, ymin = y1_lwr, ymax = y1_upr), stat="identity", fill="blue", alpha=0.2) + 
  geom_smooth(aes(y = y2, ymin = y2_lwr, ymax = y2_upr), stat="identity", fill="red", alpha=0.2)

我们如何在单个图表中使用多个geom_smooth?

Notice that the top line is no longer red in the last chart. Why is this happening and how can it be fixed? Thank you!

请注意,最后一个图表中的顶行不再是红色。为什么会发生这种情况?如何解决?谢谢!

2 个解决方案

#1


1  

Certainly reshaping your dataset will make things easier, and is the recommended approach. However, if you want to keep using separate layers:

当然,重塑数据集会使事情变得更容易,并且是推荐的方法。但是,如果要继续使用单独的图层:

As you haven't mapped a color for geom_smooth, it uses the default color of blue for the smoothed lines it drew. If you want just the ribbon, use geom_ribbon instead.

由于您没有为geom_smooth绘制颜色,因此它使用默认颜色为蓝色绘制的平滑线条。如果您只想要功能区,请改用geom_ribbon。

ggplot(data = df, aes(x = x, group = 1)) + 
    geom_line(aes(y = y1, colour = "y1")) + 
    geom_line(aes(y = y2, colour = "y2")) +     
    scale_colour_manual("", breaks = c("y1", "y2"), values = c("blue", "red")) +
    geom_ribbon(aes(y = y1, ymin = y1_lwr, ymax = y1_upr), stat="identity", fill="blue", alpha=0.2) + 
    geom_ribbon(aes(y = y2, ymin = y2_lwr, ymax = y2_upr), stat="identity", fill="red", alpha=0.2)

Otherwise you'll need to map your colors for each smooth layer within aes or set them manually to red and blue or NA outside of aes.

否则,您需要为aes中的每个平滑图层映射颜色,或者手动将它们设置为红色和蓝色或在aes之外的NA。

ggplot(data = df, aes(x = x, group = 1)) + 
    geom_line(aes(y = y1, colour = "y1")) + 
    geom_line(aes(y = y2, colour = "y2")) +     
    scale_colour_manual("", breaks = c("y1", "y2"), values = c("blue", "red")) +
    geom_smooth(aes(y = y1, ymin = y1_lwr, ymax = y1_upr, colour = "y1"), 
              stat="identity", fill="blue", alpha=0.2) + 
    geom_smooth(aes(y = y2, ymin = y2_lwr, ymax = y2_upr, colour = "y2"), 
              stat="identity", fill="red", alpha=0.2)

#2


1  

I would probably do something closer to this:

我可能会更接近这个:

library(dplyr)
df1 <- df %>%
    select(x,contains("y1")) %>%
    rename(y = y1,y_upr = y1_upr,y_lwr = y1_lwr) %>%
    mutate(grp = "y1")
df2 <- df %>%
    select(x,contains("y2")) %>%
    rename(y = y2,y_upr = y2_upr,y_lwr = y2_lwr) %>%
    mutate(grp = "y2")
df_all <- bind_rows(df1,df2)

ggplot(df_all,aes(x = x,y = y,ymin = y_lwr,ymax = y_upr,group = grp)) +
    geom_line(aes(color = grp)) + 
    geom_ribbon(aes(fill = grp),alpha = 0.2)

#1


1  

Certainly reshaping your dataset will make things easier, and is the recommended approach. However, if you want to keep using separate layers:

当然,重塑数据集会使事情变得更容易,并且是推荐的方法。但是,如果要继续使用单独的图层:

As you haven't mapped a color for geom_smooth, it uses the default color of blue for the smoothed lines it drew. If you want just the ribbon, use geom_ribbon instead.

由于您没有为geom_smooth绘制颜色,因此它使用默认颜色为蓝色绘制的平滑线条。如果您只想要功能区,请改用geom_ribbon。

ggplot(data = df, aes(x = x, group = 1)) + 
    geom_line(aes(y = y1, colour = "y1")) + 
    geom_line(aes(y = y2, colour = "y2")) +     
    scale_colour_manual("", breaks = c("y1", "y2"), values = c("blue", "red")) +
    geom_ribbon(aes(y = y1, ymin = y1_lwr, ymax = y1_upr), stat="identity", fill="blue", alpha=0.2) + 
    geom_ribbon(aes(y = y2, ymin = y2_lwr, ymax = y2_upr), stat="identity", fill="red", alpha=0.2)

Otherwise you'll need to map your colors for each smooth layer within aes or set them manually to red and blue or NA outside of aes.

否则,您需要为aes中的每个平滑图层映射颜色,或者手动将它们设置为红色和蓝色或在aes之外的NA。

ggplot(data = df, aes(x = x, group = 1)) + 
    geom_line(aes(y = y1, colour = "y1")) + 
    geom_line(aes(y = y2, colour = "y2")) +     
    scale_colour_manual("", breaks = c("y1", "y2"), values = c("blue", "red")) +
    geom_smooth(aes(y = y1, ymin = y1_lwr, ymax = y1_upr, colour = "y1"), 
              stat="identity", fill="blue", alpha=0.2) + 
    geom_smooth(aes(y = y2, ymin = y2_lwr, ymax = y2_upr, colour = "y2"), 
              stat="identity", fill="red", alpha=0.2)

#2


1  

I would probably do something closer to this:

我可能会更接近这个:

library(dplyr)
df1 <- df %>%
    select(x,contains("y1")) %>%
    rename(y = y1,y_upr = y1_upr,y_lwr = y1_lwr) %>%
    mutate(grp = "y1")
df2 <- df %>%
    select(x,contains("y2")) %>%
    rename(y = y2,y_upr = y2_upr,y_lwr = y2_lwr) %>%
    mutate(grp = "y2")
df_all <- bind_rows(df1,df2)

ggplot(df_all,aes(x = x,y = y,ymin = y_lwr,ymax = y_upr,group = grp)) +
    geom_line(aes(color = grp)) + 
    geom_ribbon(aes(fill = grp),alpha = 0.2)