首页 文章

ggplot2 - 根据因子分配符号填充

提问于
浏览
0

我是R的新手,也是ggplot的新手 . 我有一个大型数据集,并且想要绘制图中任何给定数据系列的符号填充由数据集中的因子控制的图 . 下面示出了示例数据帧,其中“站”和“标志”都是因子

Day Station Value Flag
1       1   0.0    b
2       1   1.0    a
3       1   2.0    a
1       2   2.3    a
2       2   1.0    a
3       2   0.2    b
1       3   0.5    b
2       3   0.5    b
3       3   0.5    b

我可以使用因子“Station”控制符号形状和颜色,但也想使用因子“Flag”控制符号填充,例如,填充符号用于Flag =“a”,而开放符号用于Flag =“ b“ - 任何给定的电台都会混合使用填充符号和开放符号 . 我可以在R的基本绘图功能中执行此操作,但无法在ggplot2中使其工作 . 对于具有更多站点或其他感兴趣因素的真实数据集来说,这将是非常繁琐的 .

因为我是新手,系统不会让我发布图像(没有足够的信誉点),但这里是我用来生成我正在寻找的图形和失败的ggplot尝试的代码 - 未显示的是“scale_fill_manual”的众多变体“那没用 .

library(ggplot2)
data <- read.table("dfquestion.csv", header = TRUE, sep = ",", na.strings = "",
                  colClasses = c("Day" = "numeric",
                                 "Station" = "factor",
                                 "Value" = "numeric",
                                 "Flag" = "factor"
                                 )
                  )
##---------------------------------------------------
# Select parameter to graph
x.value <- "Day"
y.value <- "Value"
##---------------------------------------------------
# Subset data by Station
##---------------------------------------------------
Sta1 <- subset(data, Station == "1")
Sta2 <- subset(data, Station == "2")
Sta3 <- subset(data, Station == "3")
##---------------------------------------------------
#
# Set symbol colors and background. 
# open symbols/ clear background = value below reporting limit
# Black = Station 1
# Red = Station 2
# Green = Station 3
#
##---------------------------------------------------
bg.list1 <- rep(0,length(Sta1$Flag))
bg.list1[Sta1$Flag == "a"] <- "black"
bg.list1[Sta1$Flag == "b"] <- NA
#
bg.list2 <- rep(0,length(Sta2$Flag))
bg.list2[Sta2$Flag == "a"] <- "red"
bg.list2[Sta2$Flag == "b"] <- NA
#
bg.list3 <- rep(0,length(Sta3$Flag))
bg.list3[Sta3$Flag == "a"] <- "green"
bg.list3[Sta3$Flag == "b"] <- NA
##---------------------------------------------------
#
# Symbol type
# circle = Sta1; pch = 21
# square = Sta2; pch = 22
# triangle = Sta3; pch = 24
#
##---------------------------------------------------
opar <- par(no.readonly=TRUE)
par(oma = c(0,1,0,2.5))
plot(Sta1$Day, Sta1$Value, type = "b", pch = 24, bg = c(bg.list1), cex = 1.2, col = "black",
     xlim = c(min(Sta1$Day), max(Sta1$Day)),
     ylim = c(range(na.omit(Sta1$Value),
                na.omit(Sta2$Value),
                na.omit(Sta3$Value)
                )),
 xlab = x.value,
 ylab = y.value,
 cex.lab = 1.25, cex.axis = 1.25,
 )
points(Sta2$Day, Sta2$Value, type = "b", pch = 21, bg = c(bg.list2), cex = 1.2, col = "red")
points(Sta3$Day, Sta3$Value, type = "b", pch = 22, bg = c(bg.list3), cex = 1.2, col = "green")
###
##---------------------------------------------------
# Creates legend outside primary graph
par(fig = c(0, 1, 0, 1), oma = c(0,0,0,0), mar = c(0,0,0,0), new = TRUE)
plot(0,0, type = "n", xaxt = "n", yaxt = "n")
legend("topright", legend = c(paste("Sta1"),
                     paste("Sta2"),
                     paste("Sta3"),
                     paste(""),
                     paste("above"),
                     paste("below")
                     ),
pch = c(21, 22, 24,
    NA,
    21, 21),
lty = c(NA), lwd = c(NA),
col = c("black", "red", "green",
    NA,
    "red", "red"),
pt.bg = c("black", "red", "green", 
      NA,
      "red", NA
      ),
text.col = "black",
bty = "n", cex = 0.95,
inset=c(-0.01,0.14))
#
par(opar)
#
##---------------------------------------------------
# Attempt to do the same thing in ggplot
#
p <- ggplot(data = data, aes(x=Day, y=Value, shape = Station, color = Station, fill = Flag)) + 
  geom_line(size = 1) + 
  geom_point(size = 4) 
p <- p + scale_shape_manual(values = c(21, 22, 23)) 
p <- p + scale_color_manual(values = c("black", "red", "green"))
# Adjust legend fills - filled = detect, open = non-detect
p <- p + guides(fill = guide_legend(override.aes = list(shape = 21, fill = c("black", NA))))
print(p)

1 回答

  • 1

    我认为 alpha 可能在这里有用 . 我提出了一个解决方案,但我并不完全满意 . 我认为 alpha 只会影响 fill 对于需要 colorfill 的点,但它改变了两者的透明度 . 我最后添加了第二个 geom_point 图层作为解决方法 .

    ggplot(data = dat, aes(x=Day, y=Value, shape = Station, fill = Station, color = Station)) + 
        geom_line(size = 1, show_guide = FALSE) + 
        geom_point(size = 4, aes(fill = NULL)) +
        geom_point(size = 4, aes(alpha = Flag)) +
        scale_shape_manual(values = c(21, 22, 23)) +
        scale_color_manual(values = c("black", "red", "green")) +
        scale_fill_manual(values = c("black", "red", "green")) +
        scale_alpha_manual(values = c(1, 0)) +
        guides(alpha = guide_legend(override.aes = list(shape = 21, fill = c("black", NA), alpha = c(1,1))))
    

相关问题