【问题标题】:color lines ggplot by last value r颜色线ggplot按最后一个值r
【发布时间】:2017-11-27 15:40:56
【问题描述】:

我需要关于在 ggplot 中绘制 > 741 行的帮助。

  1. 一个特定行的颜色不应改变,例如颜色线应仅由 eci 的最终值分配。
  2. 我想在每行的开头和结尾显示每行的名称(在代码示例中为“单元”)
  3. 当然,超过 700 条线很难用肉眼区分,但是有什么建议可以让这些线更容易区分吗?

    df <- data.frame(unit=rep(1:741, 4),  
                     year=rep(c(2012, 2013, 2014, 2015), each=741),
                     eci=round(runif(2964, 1, 741), digits = 0))
    
     g = ggplot(data = df, aes(x=year, y=eci, group=unit)) + 
          geom_line(aes(colour=eci), size=0.01) + 
          scale_colour_gradientn(colours = terrain.colors(10)) +
          geom_point(aes(colour=eci), size=0.04) 
       # The colour of the line should be determined by all eci for which year=2015
    

【问题讨论】:

  • 很抱歉 - 我现在无法将代码格式化为正确的格式。

标签: r ggplot2 colors line


【解决方案1】:

实现所需结果的一种方法是创建带有额外信息的新列,以便在使用ggplot2 进行绘图时使用。

使用dplyr,我们将数据按单元分组,然后排列,这样我们就可以创建一个存储最后一个eci的值的列,以及第一年和最后一年的两个带有标签的列,这样我们就可以添加它们作为情节的文本。

df_new <- df %>% 
  group_by(unit) %>% 
  arrange(unit, year, eci) %>% 
  mutate(last_eci = last(eci),
         first_year = ifelse(year == 2012, unit, ""),
         last_year  = ifelse(year == 2015, unit, "")) 

然后,我们绘制它。

ggplot(data = df_new, 
       aes(x = year, y = eci, group = unit, colour = last_eci)) + 
  geom_line(size = 0.01) + 
  geom_text(aes(label = first_year), nudge_x =  -0.05, color = "black") +
  geom_text(aes(label = last_year),  nudge_x =   0.05, color = "black") +
  scale_colour_gradientn(colours = terrain.colors(10)) +
  geom_point(aes(colour = eci), size = 0.04) 

当然,查看结果图很容易看出,尝试在单个图中绘制 >700 条不同颜色的线和 >1400 个标签并不是很可取的。

我会使用 df 的相关子集,因此我们生成的图表有助于我们更好地理解数据。

df_new %>% 
  filter(unit %in% c(1:10)) %>% 
  ggplot(data = ., 
         aes(x = year, y = eci, group = unit, colour = last_eci)) + 
  geom_line(size = 0.01) + 
  geom_text(aes(label = first_year), nudge_x =  -0.05, color = "black") +
  geom_text(aes(label = last_year),  nudge_x =   0.05, color = "black") +
  scale_colour_gradientn(colours = terrain.colors(10)) +
  geom_point(aes(colour = eci), size = 0.04)  

【讨论】:

    【解决方案2】:

    为了更好的可读性,我选择了一个 10 行的示例,使用了 directlabels-package。

    library(ggplot2)
    library(dplyr)
    library(directlabels)
    
    set.seed(95)
    
    
    l <- 10
    
    df1 <- data.frame(unit=rep(1:l, 4),  
                     year=rep(c(2012, 2013, 2014, 2015), each=l),
                     eci=round(runif(4*l, 1, l), digits = 0))
    
    
    df2 <- df1 %>% filter (year == 2015) %>% select(-year, end = eci)
    
    df <- left_join(df1,df2, by = "unit")
    
    g <- 
      ggplot(data = df, aes(x=year,
                              y=eci, 
                              group=unit)) + 
      geom_line(aes(colour=end), size=0.01) + 
      scale_colour_gradientn(colours = terrain.colors(10)) +
      geom_point(aes(colour=eci), size=0.04) +
      geom_dl(aes(label = unit,color = end), method = list(dl.combine("first.points", "last.points"), cex = 0.8)) 
    
    g
    

    【讨论】:

    • 出色的 1line 解决方案!不幸的是,geom_dl 在处理超过 200 个值的数据时非常慢。
    【解决方案3】:

    半年后,我认为基于parcoord() 应用于宽df 有一个更简单的解决方案。

    set.seed(95)
    
    l <- 1000 # really 1000 observations per year this time
    
    df1 <- data.frame(unit=rep(1:l, 4),  
                      year=rep(c(2012, 2013, 2014, 2015), each=l),
                      eci=round(runif(4*l, 1, l), digits = 0))
    
    df1 <- tidyr::spread(df1, year, eci) # change from long to wide
    
    df1 <- df1 %>%
      dplyr::arrange(desc(`2015`)) # Assign after which column (year) rows should be ordered
    
    # create 10 different colrs which are repeated 100 times
    my_colors=rep(terrain.colors(11)[-1], each=100) 
    
    parcoord(df1[, c(2:5)] , col= my_colors)
    

    这更有效且易于扩展。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      • 2018-06-11
      • 1970-01-01
      相关资源
      最近更新 更多