gpt4 book ai didi

r - ggplot 缺少图例

转载 作者:行者123 更新时间:2023-12-02 02:43:09 24 4
gpt4 key购买 nike

我正在尝试为我的数据集绘制线条的子集,但我似乎无法弄清楚如何让图例正常显示或使用熔化。数据集具有以下结构(实际数据集中有更多预测和日期,这只是一个示例):

Date        Actual Fcst1 Fcst2 Fcst3 Fcst4
2015-01-01 500 600 700 400 450
2015-02-01 600 610 630 480 600
2015-03-01 700 234 875 754 733
.......... ... ... ... ... ...

我目前正在使用此代码:

ggplot(df, aes(x = Date)) +
geom_line(aes(y = Fcst1), color = "red", size = 1) +
geom_line(aes(y = Fcst2),
color = "blue",
size = 1
) +
geom_line(aes(y = Fcst3),
color = "green",
size = 1
) +
geom_line(aes(y = Fcst4),
color = "yellow",
size = 1
) +
geom_line(aes(y = Fcst5),
color = "purple",
size = 1
) +
geom_line(aes(y = Fcst6), color = "orange", size = 1) +
geom_line(aes(y = Actual), color = "black", size = 1.2) +
ggtitle(label = "Actuals vs 2015 Forecasts", subtitle = fname) +
ylab("Balance") +
scale_y_continuous(labels = comma)

无论如何,即使我尝试使用熔化,我也无法让图例正确显示。有人可以帮我吗?

最佳答案

ggplot2 更喜欢长格式的内容,并且倾向于“惩罚”(使困难)像您现在正在做的事情。让我们 reshape 一下(我将使用 tidyr::pivot_longer,其他的也可以)。

library(ggplot2)
ggplot(tidyr::pivot_longer(df, Fcst1:Fcst4),
aes(Date, value, color = name)) +
geom_line()

basic ggplot2

正如您所知,在 aes 主题中使用 color= 会相应地改变颜色。如果您想控制颜色,有许多主题可用(例如,viridis 和许多带有色盲配置文件的主题),但手动操作是使用 scale_color_manual 完成的,我下面将进行演示。最后,我将调整名称等。

ggplot(tidyr::pivot_longer(df, Actual:Fcst4, names_to = "Forecast", names_prefix = "Fcst"),
aes(Date, value, color = Forecast)) +
geom_line(size = 1) +
scale_color_manual(values = c("Actual" = "black", "1" = "red", "2" = "blue",
"3" = "green", "4" = "yellow", "5" = "purple",
"6" = "orange")) +
ggtitle(label = "Actuals vs 2015 Forecasts", subtitle = "(unk filename)") +
ylab("Balance") +
scale_y_continuous(labels = scales::comma)

手动颜色不必完美匹配,正如您在定义但未使用的 5 中看到的那样(基于您的数据样本)。 values= 命名向量中缺少的颜色将从图中删除(并带有警告)。

same ggplot2, updated theme

最后,一个常见问题是对图例中的组件进行排序。这可以通过 factor 来完成:

df_long <- tidyr::pivot_longer(df, Actual:Fcst4, names_to = "Forecast", names_prefix = "Fcst")
df_long$Forecast <- relevel(factor(df_long$Forecast), "Actual")
ggplot(df_long, aes(Date, value, color = Forecast)) +
geom_line(size = 1) +
scale_color_manual(values = c("Actual" = "black", "1" = "red", "2" = "blue",
"3" = "green", "4" = "yellow", "5" = "purple",
"6" = "orange")) +
ggtitle(label = "Actuals vs 2015 Forecasts", subtitle = "(unk filename)") +
ylab("Balance") +
scale_y_continuous(labels = scales::comma)

same ggplot2, reordered legend

我使用 stats::relevel 将一个因素“移到前面”,否则它往往是按字母顺序排列的(如上面第二张图所示)。有很多用于处理因子的工具,forcats 软件包是一种流行的工具(尤其是在 tidyverse 用户中)。

此处理可以轻松地在 dplyr 管道中进行。


既然您提到一次绘制批量预测,这里有几种方法。我将通过将 Fcst 列复制到另一组 4 列中来扩充数据:

df <- cbind(df, setNames(df[,3:6], paste0("Fcst", 5:8)))
df_long <- tidyr::pivot_longer(df, Actual:Fcst8, names_to = "Forecast", names_prefix = "Fcst")
df_long$Forecast <- relevel(factor(df_long$Forecast), "Actual")

为了代码简洁,我将“简化”情节,但主题仍然如上所示。

  1. 单独的绘图,一次过滤一个并绘制它。

    ggplot(df_long[df_long$Forecast %in% c("Actual", "1", "3", "5", "7"),],
    aes(Date, value, color = Forecast)) +
    geom_line(size = 1)
  2. 分面。我将在这个示例中展示一种强制方法来执行此操作,然后是一种更灵活(可能)的方法。我在这里使用 dplyr 是因为它使一些操作更容易查看和理解(一旦您习惯了 dplyr 式语法)。 (我经常发现保持控制线“实际”与其他控制线不同的颜色/厚度有助于巩固各个方面的比较。交给你了。)

    library(dplyr)
    df_rest <- df_long %>%
    filter(! Forecast == "Actual") %>%
    mutate(grp = cut(as.integer(as.character(Forecast)), c(0, 5, 9), labels = FALSE))

    df_combined <- df_long %>%
    filter(Forecast == "Actual") %>%
    select(-grp) %>%
    crossing(., unique(select(df_rest, grp))) %>%
    bind_rows(df_rest)

    ggplot(df_combined, aes(Date, value, color = Forecast)) +
    geom_line(size = 1) +
    facet_grid(grp ~ .)

    expanded data, ggplot2 faceted

  3. 分面,但具有一组更易于维护的分面。我将使用一个简单的 data.frame 来控制哪些行包含在哪个 $grp 中。这使得(在我看来)更容易“挑选”特定方面的特定行。

    grps <- tibble::tribble(
    ~grp, ~Forecast
    ,1, "Actual"
    ,1, "1"
    ,1, "3"
    ,1, "5"
    ,2, "Actual"
    ,2, "2"
    ,2, "4"
    ,2, "6"
    ,2, "7"
    ,2, "8"
    )
    ggplot(left_join(df_long, grps, by = "Forecast"),
    aes(Date, value, color = Forecast)) +
    geom_line(size = 1) +
    facet_grid(grp ~ .)

    在本例中,我使用 tribble 只是为了更容易看出哪个组合在一起;任何data.frame都可以工作。我还证明 $grp 大小不需要相等,可以包含您想要的任何内容。

  4. 使用上面 #3 中的框架进行连接,然后对它们进行过滤,如下所示

    left_join(df_long, grps, by = "Forecase") %>%
    filter(grp == 1) %>%
    ggplot(., aes(Date, value, color = Forecast)) +
    geom_line(size = 1) +
    facet_grid(grp ~ .)

关于r - ggplot 缺少图例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63233362/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com