假设我正在绘制R中ggplot2中的密集散点图,其中每个点可能会用不同的颜色标记:
df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x
df$label <- c("a")
df$label[50] <- "point"
df$size <- 2
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size))
当我这样做时,标有“点”(绿色)的散点被绘制在具有标签“a”的红点之上。什么控制ggplot中的这个z排序,即控制哪个点位于哪个点之上?例如,如果我希望所有“a”点都位于标记为“point”的所有点之上(意味着它们有时会部分或完全隐藏该点),该怎么办?这取决于标签的字母数字排序吗?我想找到一个可以轻松转换为rpy2的解决方案。感谢
答案 0 :(得分:46)
ggplot2
将逐层创建绘图,在每个图层中,绘图顺序由geom
类型定义。默认设置是按照它们在data
中的显示顺序进行绘制。
如果不同,请注意。例如
geom_line
连接观察结果,按x值排序。
和
geom_path
按数据顺序连接观察
还有known issues regarding the ordering of factors
,有趣的是要注意包工作者Hadley的回应
绘图的显示应该与数据框的顺序不变 - 其他任何东西都是错误。
记住这一点,一个图层是按照指定的顺序绘制的,因此过度绘制可能是一个问题,尤其是在创建密集的散点图时。因此,如果您想要一致的图(而不是依赖于数据框中的顺序的图),您需要多考虑一下。
如果您希望某些值显示在其他值之上,则可以使用subset
参数创建第二层,以便之后明确绘制。您需要明确加载plyr
包,以便.()
可以使用。
set.seed(1234)
df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x
df$label <- c("a")
df$label[50] <- "point"
df$size <- 2
library(plyr)
ggplot(df) + geom_point(aes(x = x, y = y, color = label, size = size)) +
geom_point(aes(x = x, y = y, color = label, size = size),
subset = .(label == 'point'))
在ggplot2_2.0.0
中,不推荐使用subset
参数。使用例如base::subset
选择data
参数中指定的相关数据。而且无需加载plyr
:
ggplot(df) +
geom_point(aes(x = x, y = y, color = label, size = size)) +
geom_point(data = subset(df, label == 'point'),
aes(x = x, y = y, color = label, size = size))
alpha
避免过度绘图问题的另一种方法是设置点的alpha
(透明度)。这不会像上面明确的第二层方法那样有效,但是,通过明智地使用scale_alpha_manual
,你应该可以使某些东西起作用。
例如
# set alpha = 1 (no transparency) for your point(s) of interest
# and a low value otherwise
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size,alpha = label)) +
scale_alpha_manual(guide='none', values = list(a = 0.2, point = 1))
答案 1 :(得分:31)
2016年更新:
订单审美has been deprecated,所以此时最简单的方法是对data.frame进行排序,使绿点位于底部,并最后绘制。如果您不想更改原始data.frame,可以在ggplot调用期间对其进行排序 - 这是一个使用dplyr包中的%>%
和arrange
来执行此操作的示例飞行排序:
library(dplyr)
ggplot(df %>%
arrange(label),
aes(x = x, y = y, color = label, size = size)) +
geom_point()
ggplot2版本的原始2015年答案&lt; 2.0.0 强>
在ggplot2中,您可以使用order aesthetic指定绘制点的顺序。绘制的最后一个将显示在顶部。要应用此功能,您可以创建一个变量,其中包含您要绘制点的顺序。
通过将绿点绘制在其他绿色点之后将绿点放在顶部:
df$order <- ifelse(df$label=="a", 1, 2)
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size, order=order))
或者首先绘制绿点并将其埋葬,然后按相反顺序绘制点:
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size, order=-order))
对于这个简单的示例,您可以跳过创建新的排序变量,只需将label
变量强制转换为因子,然后强制转换为数字:
ggplot(df) +
geom_point(aes(x=x, y=y, color=label, size=size, order=as.numeric(factor(df$label))))
答案 2 :(得分:12)
这里的基本问题可以这样改写:
如何控制情节图层?
在'ggplot2'包中,您可以通过将每个不同的图层拆分为不同的命令来快速完成此操作。在层次方面进行思考需要一些练习,但它基本上归结为您想要在其他事物上绘制的内容。你是从背景向上构建的。
准备:准备样本数据。此步骤仅对此示例是必需的,因为我们没有可用的实际数据。
# Establish random seed to make data reproducible.
set.seed(1)
# Generate sample data.
df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x
# Initialize 'label' and 'size' default values.
df$label <- "a"
df$size <- 2
# Label and size our "special" point.
df$label[50] <- "point"
df$size[50] <- 4
您可能会注意到我为示例添加了不同的尺寸,以使图层区别更加清晰。
第1步:将数据分成多个层。在使用'ggplot'功能之前,请务必执行此操作。尝试使用'ggplot'函数进行数据操作会导致太多人陷入困境。在这里,我们想要创建两个层:一个带有“a”标签,另一个带有“点”标签。
df_layer_1 <- df[df$label=="a",]
df_layer_2 <- df[df$label=="point",]
您可以使用其他功能执行此操作,但我只是快速使用数据帧匹配逻辑来提取数据。
第2步:将数据绘制为图层。我们想首先绘制所有“a”数据,然后绘制所有“点”数据。
ggplot() +
geom_point(
data=df_layer_1,
aes(x=x, y=y),
colour="orange",
size=df_layer_1$size) +
geom_point(
data=df_layer_2,
aes(x=x, y=y),
colour="blue",
size=df_layer_2$size)
请注意,基础图层ggplot()
没有分配数据。这很重要,因为我们将覆盖每个图层的数据。然后,我们有两个单独的点几何图层geom_point(...)
,它们使用自己的规范。 x和y轴将被共享,但我们将使用不同的数据,颜色和大小。
将颜色和大小规格移到aes(...)
函数之外非常重要,因此我们可以按字面指定这些值。否则,'ggplot'函数通常会根据数据中的级别指定颜色和大小。例如,如果数据中的大小值为2和5,则会为值2的任何匹配项指定默认大小,并为值5的任何匹配项指定一些更大的大小。'aes'函数规范不会使用值2和5作为大小。颜色也是如此。我有精确的尺寸和颜色,所以我将这些参数移到'geom_plot'函数本身。此外,'aes'功能中的任何规范都将被放入图例中,这可能真的没用。
最后的注意事项:在这个例子中,您可以通过多种方式实现想要的结果,但了解'ggplot2'层的工作方式非常重要,以便充分利用您的'ggplot '图表。只要在调用'ggplot'函数之前将数据分成不同的层,就可以很好地控制在屏幕上绘制内容的方式。
答案 3 :(得分:7)
按照data.frame中的行顺序绘制。试试这个:
df2 <- rbind(df[-50,],df[50,])
ggplot(df2) + geom_point(aes(x=x, y=y, color=label, size=size))
如您所见,最后绘制绿点,因为它代表data.frame的最后一行。
这是一种命令data.frame首先绘制绿点的方法:
df2 <- df[order(-as.numeric(factor(df$label))),]