【问题标题】:ggplot2: differentiate lines by both color and linetypeggplot2:通过颜色和线型区分线条
【发布时间】:2015-09-25 07:46:23
【问题描述】:

所以当我必须绘制很多线时,我可以通过颜色或线型来区分它们

library(ggplot2)
pd = cbind.data.frame(x = rep(c(1,2), each = 4), 
              y = rep(1:4, times=2), 
              type = rep(c("A", "B", "C", "D"), times=2))
ggplot(pd, aes(x=x, y=y, col=type)) + geom_line() + theme_bw()
ggplot(pd, aes(x=x, y=y, lty=type)) + geom_line() + theme_bw()

给予:

但我想要两者,并且我希望自动选择颜色和线型(即,我不想为每个 type 手动指定颜色和线型,如在这个问题中:ggplot2 manually specifying color & linetype - duplicate legend)。

这是我想要的输出的示例(加上自动生成的图例):

理想的命令是

ggplot(pd, aes(x=x, y=y, style=type)) + geom_line() + theme_bw()

但我想需要有一个解决方法。

P.S:这样做的动机是 20 多条线很难仅通过颜色或线型来区分,这就是为什么我正在寻找两者的组合。因此,红色虚线与红色实线不同,两者都与蓝色实线不同。而且我不想每次将数据提供给ggplot时自己指定和选择颜色和线型。

【问题讨论】:

  • 当你说“颜色或线型”时,你的意思是不是both?比如ggplot(pd, aes(x=x, y=y, lty=type, col=type)),就是四种线型四种颜色。
  • 所以,要明确一点,在您的第三个图中,两条蓝线之间没有特殊联系,您只想使用 2 种颜色和 2 种线型来获得 2*2 = 4 个不同的类别?
  • @Gregor 确切地说,我在 P.S. 中添加了一个动机。我的问题
  • 创建图会相当容易,只需在数据中获取一些虚拟变量。然而,获得准确、简洁的图例将非常困难。

标签: r ggplot2


【解决方案1】:

我知道您想避免手动指定,但它不必像您链接的示例那样令人生畏。以下示例为 20 行(color_lty_cross 最多可容纳 60 行):

library(ggplot2)

pd = cbind.data.frame(x = rep(c(1,2), each = 20), 
                      y = rep(1:20, times=2), 
                      type = rep(LETTERS[1:20], times=2))

# this function regenerates ggplot2 default colors
gg_color_hue <- function(n) {
  hues = seq(15, 375, length = n + 1)
  hcl(h = hues, l = 65, c = 100)[1:n]
}

color_lty_cross = expand.grid(
  ltypes = 1:6,
  colors = gg_color_hue(10)
  ,stringsAsFactors = F)


ggplot(pd, aes(x=x, y=y, col=type, lty = type)) + 
  geom_line() + 
  scale_color_manual(values = color_lty_cross$colors[1:20]) +
  scale_linetype_manual(values = color_lty_cross$ltypes[1:20]) +
  theme_bw()

您可以通过合并快速映射到 type 您可以使用更简单的颜色,然后使用映射 ggplot2 默认值的 gg_color_hue。

【讨论】:

    【解决方案2】:

    您还可以通过三角形或圆形等几何图形来区分线条。如果您的数据很少(例如 100 个样本),您可以简单地在绘图属性中选择 type = "b",但如果您有很多数据(例如 10000 个样本),您可以在生成的线上绘制几何图形,以便您可以通过使用 points() 命令随意间隔它,您可以在其中指定点的 x 和 y 坐标。否则数字将相互重叠。示例(附代码):

    #!/usr/bin/Rscript
    
    args = commandArgs(trailingOnly=TRUE)
    dataLocation = args[1]
    fileName = args[2]
    abs_path = args[3]
    
    myData <- read.csv(dataLocation, sep = ";")
    
    #paste0 concatenates two strings
    fullFileName = paste0(abs_path,fileName)
    
    #plot first line
    
    png(fullFileName, width = 1300, height = 600)
    
    plot(myData[,1], type = "l", cex = 2, cex.axis = 3.0, lty = 1 ,cex.lab = 3.0, ylim = c(0, max(myData)), xlab = "Iteração", ylab = "Valor")
    
    limit = ncol(myData)
    
    if(limit > 1){
    
        for (column in 2:limit){
            lines(myData[,column], lty = 1, type = "l")
        }
    }
    
    for(i in 1:500){
    
       if(i %% 100 == 0){
    
          points(i, myData[i,1], pch = 16, cex = 1.5)
          points(i, myData[i,2], pch = 24, cex = 1.5)
          points(i, myData[i,3], pch = 0, cex = 1.5)
          points(i, myData[i,4], pch = 15, cex = 1.5)
    
       }
    
    }
    
    dev.off()
    

    【讨论】:

    • 首先,你能展示你用来创建这个情节的代码吗?其次,恐怕它并没有真正回答我的问题,但它可能对其他偶然发现这个问题的人有用。
    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    相关资源
    最近更新 更多