【问题标题】:R: Order of points and lines within geom in ggplot2R:ggplot2中geom内的点和线的顺序
【发布时间】:2014-09-11 02:33:18
【问题描述】:

我正在尝试在 ggplot 中绘制数据框,但无法让点和线以所需的顺序显示。

数据基于同一列(因子 0 或 1)进行拆分,我希望 0 为线和点绘制超过 1 的线和点(使用来自其他 4 个单独列的数据)。

我在下面制作了一个测试数据框来说明我的观点。我的真实数据框有数千个点,我想绘制一些数据框,所以真的不想使用像子集我的数据和绘制为单独的图层/几何图形这样的解决方法。

testdata <- data.frame(Split = c(rep(0,5), rep(1,5)), a = rep(1:5,2), 
      b = c(7,8,9,10,11,6,8,9,10,12), x = c(1:5, 1:5), y = c(1:3,5,6,1.1,2.1,4.1,5.1,7.1))
testdata$Split <- factor(testdata$Split)


ggplot(data = testdata)+
  geom_point(aes(x = x, y = y, colour = Split), size = 4)+
  geom_line(aes(x = a, y = b, colour = Split))

testdata$Split <- ordered(testdata$Split, levels = rev(levels(testdata$Split)))

当我运行代码行来反转我的关卡顺序时,它会交换我的哪一行被带到前面,而不是哪一组点。所以最初与Split = 0相关的点和线都在后面,但是当我颠倒顺序时,Split = 0的线在前面(我想要的),但Split = 0的点仍然在Split = 1的点后面。

任何想法这里发生了什么以及我如何让它发挥作用将不胜感激。

谢谢

【问题讨论】:

    标签: r ggplot2 levels factors


    【解决方案1】:

    在调查了一段时间后,这是我的发现和建议。简而言之,我认为解决方案是在unclass()中将值2赋值为0。

    foo <- data.frame(split = rep(c("0", "1"), each = 5),
                 a = rep(1:5,2), 
                 b = c(7,8,9,10,11,6,8,9,10,12),
                 x = c(1:5, 1:5),
                 y = c(1:3,5,6,1.1,2.1,4.1,5.1,7.1),
                 stringsAsFactors=F)
    

    为了将 unclass() 中的 2 分配给 split 中的 0,我做了以下操作。

    foo <- arrange(foo, desc(split))
    foo$split <- as.factor(foo$split)
    
    #> str(foo)
    #'data.frame':  10 obs. of  5 variables:
    # $ split: Factor w/ 2 levels "0","1": 2 2 2 2 2 1 1 1 1 1
    # $ a    : int  1 2 3 4 5 1 2 3 4 5
    # $ b    : num  6 8 9 10 12 7 8 9 10 11
    # $ x    : int  1 2 3 4 5 1 2 3 4 5
    # $ y    : num  1.1 2.1 4.1 5.1 7.1 1 2 3 5 6
    

    再一次,unclass() 中的 0 有 2。

    #> unclass(foo$split)
    # [1] 2 2 2 2 2 1 1 1 1 1
    #attr(,"levels")
    #[1] "0" "1"
    

    现在我运行以下命令。 q (for points) 有理想的结果。但是 q2(对于行)没有。

    q <- ggplot(data = foo, aes(x = x, y = y, colour = split))+
         geom_point(size = 6)
    
    q2 <- ggplot(data = foo, aes(x = a, y = b, colour = split))+
          geom_line()
    

    所以,我颠倒了因子顺序,看看会发生什么。

    ### Reorder the factor levels.      
    foo$split <- ordered(foo$split, rev(levels(foo$split)))
    
    #> str(foo)
    #'data.frame':  10 obs. of  5 variables:
    #$ split: Ord.factor w/ 2 levels "1"<"0": 1 1 1 1 1 2 2 2 2 2
    #$ a    : int  1 2 3 4 5 1 2 3 4 5
    #$ b    : num  6 8 9 10 12 7 8 9 10 11
    #$ x    : int  1 2 3 4 5 1 2 3 4 5
    #$ y    : num  1.1 2.1 4.1 5.1 7.1 1 2 3 5 6
    
    #> unclass(foo$split)
    #[1] 1 1 1 1 1 2 2 2 2 2
    #attr(,"levels")
    #[1] "1" "0"
    

    q3 和 q4 都得到了正确的结果。

    q3 <- ggplot(data = foo, aes(x = x, y = y, colour = split))+
          geom_point(size = 6)
    
    q4 <- ggplot(data = foo, aes(x = a, y = b, colour = split))+
          geom_line()
    

    所以,这是最终的形式。

    ggplot(data = foo)+
      geom_point(aes(x = x, y = y, colour = split), size = 6)+
      geom_line(aes(x = a, y = b, colour = split))
    

    【讨论】:

    • 您好,感谢您的帮助,我真的希望得到一个不涉及手动拆分数据的答案,因为这只是一种简化,我需要多次应用并拆分为2层以上
    • 嗨,我找到了办法。但是,花了这么长时间。我也需要解释很多。请给我一点时间。谢谢。
    • @user2738526 我现在修改了答案。
    • 哇,感谢您的详细回复。我需要一点时间来处理我所想的一切。我管理了一项不同的工作,但仍然很好奇它在做什么以及为什么希望这能帮助我弄清楚
    • @user2738526 如果您知道更快的方法,请告诉我。你的问题让我想了很多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多