R ggplot2:在不同图层上绘制数据子集时保持原始颜色和组级顺序
R ggplot2: maintain original colors and group level order when plotting subsets of data on different layers
我有一个非常简单(尽管很大)的数据框,其中包含 2 个数字列和 1 个字符分组列,其中包含几个 NAs
.
我将以iris
为例。下面,我只是在Species
列中引入随机NAs
,我想用来分组和着色。
我在这里所做的是将 Species
列重新制作为末尾带有“NA”(字符)的因子。我在最后制作了一个带有 gray
的调色板,我想对应于“NA”。
data("iris")
set.seed(123)
na_rows <- sample(nrow(iris), 100, replace = F)
iris$Species <- as.character(iris$Species)
iris$Species[na_rows] <- "NA"
mylevels <- iris$Species[which(iris$Species!="NA")]
mylevels <- c(gtools::mixedsort(unique(mylevels)), "NA")
iris$Species <- factor(iris$Species, levels=mylevels)
plot_palette <- c("red","blue","green")
plot_palette <- c(plot_palette[1:length(mylevels)-1], "gray")
到这里为止一切都很好。现在我像这样制作散点图:
grDevices::pdf(file="test1.pdf", height=10, width=10)
P <- ggplot2::ggplot(data=iris, ggplot2::aes(x=Sepal.Length, y=Sepal.Width, color=Species)) +
ggplot2::scale_color_manual(values=plot_palette)
P1 <- P + ggplot2::geom_point(pch=16, size=10, alpha=0.75)
print(P1)
grDevices::dev.off()
这会产生这个情节:
到这里为止一切都很好。这非常接近我想要的,但是我的实际数据框非常大,很多 non-NA
个点隐藏在 NA
个后面。
为了避免这种情况,我试图首先绘制 NA
数据的子集,然后在上层绘制 non-NA
数据的子集。我试试下面的代码:
grDevices::pdf(file="test2.pdf", height=10, width=10)
P <- ggplot2::ggplot(data=iris, ggplot2::aes(x=Sepal.Length, y=Sepal.Width, color=Species)) +
ggplot2::scale_color_manual(values=plot_palette)
P1 <- P + ggplot2::geom_point(data=function(x){x[x$Species == "NA", ]}, pch=15, size=10, alpha=0.75) +
ggplot2::geom_point(data=function(x){x[x$Species != "NA", ]}, pch=16, size=10, alpha=0.75)
print(P1)
grDevices::dev.off()
这会产生这个情节:
我这里的问题很明显,但我不知道如何解决。
我只希望第二个情节与第一个情节完全一样,只是“分层”落后 NA
点。我想保持图例中Species
级别的原始顺序,最后是NA
,颜色对应相同,NA
关联到gray
。
请注意,我还更改了 pch
以获得 NA
点。一个好处是 NA
(在底部)只有正方形的图例,其他样本只有圆圈。
有什么帮助吗?谢谢!
不需要多层。您可以简单地重新排序您的数据集,以便首先绘制 NA
s,对于可以将 Species
映射到 shape
aes 的形状,并通过 scale_shape_manual
设置所需的形状:
iris1 <- dplyr::arrange(iris, desc(Species))
P <- ggplot2::ggplot(data=iris1, ggplot2::aes(x=Sepal.Length, y=Sepal.Width, color=Species, shape = Species)) +
ggplot2::scale_color_manual(values=plot_palette)
P + ggplot2::geom_point(size=10, alpha=0.75) + ggplot2::scale_shape_manual(values = c(16, 16, 16, 15))
我有一个非常简单(尽管很大)的数据框,其中包含 2 个数字列和 1 个字符分组列,其中包含几个 NAs
.
我将以iris
为例。下面,我只是在Species
列中引入随机NAs
,我想用来分组和着色。
我在这里所做的是将 Species
列重新制作为末尾带有“NA”(字符)的因子。我在最后制作了一个带有 gray
的调色板,我想对应于“NA”。
data("iris")
set.seed(123)
na_rows <- sample(nrow(iris), 100, replace = F)
iris$Species <- as.character(iris$Species)
iris$Species[na_rows] <- "NA"
mylevels <- iris$Species[which(iris$Species!="NA")]
mylevels <- c(gtools::mixedsort(unique(mylevels)), "NA")
iris$Species <- factor(iris$Species, levels=mylevels)
plot_palette <- c("red","blue","green")
plot_palette <- c(plot_palette[1:length(mylevels)-1], "gray")
到这里为止一切都很好。现在我像这样制作散点图:
grDevices::pdf(file="test1.pdf", height=10, width=10)
P <- ggplot2::ggplot(data=iris, ggplot2::aes(x=Sepal.Length, y=Sepal.Width, color=Species)) +
ggplot2::scale_color_manual(values=plot_palette)
P1 <- P + ggplot2::geom_point(pch=16, size=10, alpha=0.75)
print(P1)
grDevices::dev.off()
这会产生这个情节:
到这里为止一切都很好。这非常接近我想要的,但是我的实际数据框非常大,很多 non-NA
个点隐藏在 NA
个后面。
为了避免这种情况,我试图首先绘制 NA
数据的子集,然后在上层绘制 non-NA
数据的子集。我试试下面的代码:
grDevices::pdf(file="test2.pdf", height=10, width=10)
P <- ggplot2::ggplot(data=iris, ggplot2::aes(x=Sepal.Length, y=Sepal.Width, color=Species)) +
ggplot2::scale_color_manual(values=plot_palette)
P1 <- P + ggplot2::geom_point(data=function(x){x[x$Species == "NA", ]}, pch=15, size=10, alpha=0.75) +
ggplot2::geom_point(data=function(x){x[x$Species != "NA", ]}, pch=16, size=10, alpha=0.75)
print(P1)
grDevices::dev.off()
这会产生这个情节:
我这里的问题很明显,但我不知道如何解决。
我只希望第二个情节与第一个情节完全一样,只是“分层”落后 NA
点。我想保持图例中Species
级别的原始顺序,最后是NA
,颜色对应相同,NA
关联到gray
。
请注意,我还更改了 pch
以获得 NA
点。一个好处是 NA
(在底部)只有正方形的图例,其他样本只有圆圈。
有什么帮助吗?谢谢!
不需要多层。您可以简单地重新排序您的数据集,以便首先绘制 NA
s,对于可以将 Species
映射到 shape
aes 的形状,并通过 scale_shape_manual
设置所需的形状:
iris1 <- dplyr::arrange(iris, desc(Species))
P <- ggplot2::ggplot(data=iris1, ggplot2::aes(x=Sepal.Length, y=Sepal.Width, color=Species, shape = Species)) +
ggplot2::scale_color_manual(values=plot_palette)
P + ggplot2::geom_point(size=10, alpha=0.75) + ggplot2::scale_shape_manual(values = c(16, 16, 16, 15))