【问题标题】:Line with size=0 still drawn by geom_line尺寸=0 的线仍由 geom_line 绘制
【发布时间】:2015-12-07 21:28:40
【问题描述】:

所以我有一个data.frame 某些物种随时间的活动。这是其中的一部分:

df <- structure(list(soort_wet = structure(c(2L, 1L, 2L, 1L, 2L, 1L, 
        2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
        2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
        2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L), .Label = c("Callophrys rubi", 
            "Coenagrion hastulatum"), class = "factor"), periode = structure(c(1L, 
                            1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 
                            9L, 10L, 10L, 11L, 11L, 12L, 12L, 13L, 13L, 14L, 14L, 15L, 15L, 
                            16L, 16L, 17L, 17L, 18L, 18L, 19L, 19L, 20L, 20L, 21L, 21L, 22L, 
                            22L, 23L, 23L, 24L, 24L, 25L, 25L), .Label = c("1-mrt", "10-mrt", 
                  "20-mrt", "1-apr", "10-apr", "20-apr", "1-mei", "10-mei", "20-mei", 
                  "1-jun", "10-jun", "20-jun", "1-jul", "10-jul", "20-jul", "1-aug", 
                  "10-aug", "20-aug", "1-sep", "10-sep", "20-sep", "1-okt", "10-okt", 
                  "20-okt", "30-okt"), class = "factor"), activiteit = c(NA, NA, 
                    NA, NA, NA, NA, NA, NA, 0, NA, 1, 0, 1, 1, 3, 2, 3, 3, 3, 3, 
                    3, 3, 1, 2, 1, 2, 0, 1, 0, 1, NA, 1, NA, 0, NA, NA, NA, NA, NA, 
                   NA, 0, NA, 0, NA, NA, NA, NA, NA, NA, NA)), .Names = c("soort_wet", 
                   "periode", "activiteit"), class = "data.frame", row.names = c(9L, 
                           15L, 70L, 76L, 131L, 137L, 192L, 198L, 253L, 259L, 314L, 320L, 
                           375L, 381L, 436L, 442L, 497L, 503L, 558L, 564L, 619L, 625L, 680L, 
                           686L, 741L, 747L, 802L, 808L, 863L, 869L, 924L, 930L, 985L, 991L, 
                           1046L, 1052L, 1107L, 1113L, 1168L, 1174L, 1229L, 1235L, 1290L, 
                           1296L, 1351L, 1357L, 1412L, 1418L, 1473L, 1479L))

如您所见,我已将活动分为 4 类(0 到 3)。现在我想绘制一个图表,将活动显示为一条线。我为此使用 ggplot2:

library(ggplot2)

# First attempt: size = 0 is still plotted as a line
ggplot(df, aes(x=periode,y=soort_wet, group=soort_wet)) +
  geom_line(aes(size=activiteit))

嗯,这几乎就是我想要的,除了:我想要带有 acitiviteit==0 的线条,因此不绘制 size==0。 所以我的第一个问题是为什么要绘制 size==0 的线条,我该如何解决这个问题? 请注意,我不想用 NA 替换 0,因为这会导致我的行过早结束。

我想我可以自己解决这个问题,将这些线条设为白色(或 colour=NA):

ggplot(df, aes(x=periode,y=soort_wet, group=soort_wet)) +
  geom_line(aes(size=activiteit,colour=ifelse(activiteit==0,NA,"black")))

但这让我陷入了更深的麻烦。有谁知道为什么这不起作用(奖金问题!)。

【问题讨论】:

    标签: r ggplot2 line


    【解决方案1】:

    诚然,这样做有点烦人。让我回顾一下您尝试中的一些内容,以及为什么它没有首先起作用。

    首先,简单地声明 size=activiteit 并不意味着值为 0 将导致大小为 0。ggplot 首先进行缩放,默认情况下在大小 1 和 6 之间。如果你想映射到实际值,你必须使用scale_size_identity() 或调整scale_size_continuous 中的range。不幸的是,调整它会产生更好的图表,但由于我也不明白的原因,这条线仍然可见。

    接下来,您的第二次尝试也不起作用,因为您现在正在映射值 'black'(这种方法适用于基础 R)。

    现在,为了解决所有这些问题,我们可以在activiteit == 0 时创建一个新变量TRUE,并将该变量映射到alpha,这样我们就可以使该行的那部分透明。

    示例代码:

    df$alp <- ifelse(df$activiteit == 0, T, F)
    
    ggplot(df, aes(x=periode,y=soort_wet, group=soort_wet, alpha=alp)) +
      geom_line(aes(size=activiteit)) + theme_bw() +
      scale_alpha_manual(values = c("TRUE" = 0, "FALSE" = 1), guide = 'none') +
      scale_size_continuous(range = c(0, 15)) +
      theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))
    

    结果:

    编辑:

    我刚刚意识到还有一种更简单的方法,您可以将大小比例的限制调整为不包括 0:

    ggplot(df, aes(x=periode,y=soort_wet, group=soort_wet)) +
      geom_line(aes(size=activiteit)) + theme_bw() +
      scale_size_continuous(range = c(3, 15), limit = c(1, 3)) +
      theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))
    

    【讨论】:

    • 请注意,结果图是不同的,不知道为什么。我认为您正在寻找第一个。
    • 谢谢,这就是我要找的(第一个)!我应该考虑自己使用alpha。我认为您的第二次尝试(编辑)似乎与下面的 MLavoie 存在相同的问题:由于缺少连接点,最后一行消失了。不知道为什么。
    • 我同意,只需手动确认第一个正是您想要的,然后就可以了。 Veel 成功!
    【解决方案2】:

    这对你有用吗?

    根据需要先设置子集

    df_s <- df %>% filter(activiteit > 0)
    

    然后绘制

    ggplot(df_s, aes(x=periode,y=soort_wet, group=soort_wet)) +
      geom_line(aes(size=as.factor(activiteit)))
    

    你的尺寸为 0 不是情节。

    【讨论】:

    • 子集不起作用,原因与用 Nas 替换 0 不起作用的原因相同:它删除最后一行 size = 1。顺便说一句:我得到了一个 Error in UseMethod("filter_") : no applicable method for 'filter_' applied to an object of class "function"
    • 它对我有用!也许你加载了其他库尝试 df_s % dplyr::filter(activiteit > 0)
    • 我不明白为什么子集化不起作用。但值得注意的是,当您将 size 映射到“activiteit”时,R 没有理由认为 activiteit==0 意味着 size ==0。这只是该变量的一个级别,因此与类别从 25 开始的情况相同。它将简单地将最低级别映射到一条小线,并将最高级别映射到一条较大的线。如果您添加了+scale_size_identity(),那么它将正确映射大小,except 为 0。由于某种原因,声明行大小 0 不会删除该行。
    • @Matt74 将子集图与我的问题进行比较。您会看到最后一行 size=1 也被删除了。我已经尝试过“scale_size_identity”,但仍然绘制了 0 条线。知道为什么吗?
    • 似乎您的问题不在于子集本身 - 它与默认绘图函数截断您的数据有关,因为不再有任何理由让 x 轴一直延伸到日期没有数据。我建议将 df$periode 转换为 POSIXct 类型并探索 scale_x_datetime()。或其他控制 x 轴的方式,以便您控制其限制。作为旁注,由于您的变量“周期”是一个因素(不是日期)并按字母顺序排列,您可能会遇到一些问题,例如将 mrt-10 放在 mrt-2 之前。
    猜你喜欢
    • 2015-06-26
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    相关资源
    最近更新 更多