在R中控制ggplot2中点的顺序?

假设我在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中的zsorting,即什么控制哪个点在哪个顶部? 例如,如果我想让所有的“a”点位于所有标记为“point”的点上(意思是说它们有时会部分地或完全地隐藏那个点)呢? 这是否依赖于标签的字母数字顺序? 我想find一个解决scheme,可以很容易地转换为rpy2。 谢谢

ggplot2ggplot2创build图表,并且在每个图层内,绘图顺序由geomtypes定义。 默认情况下是按照它们出现在data中的顺序进行绘图。

这是不同的,这是注意到的。 例如

geom_line

连接观察值,按x值sorting。

geom_path

按照数据顺序连接观测值


还有一些关于sortingfactors已知问题 ,有趣的是要注意一揽子作者Hadley的回应

一个绘图的显示应该是不变的dataframe的顺序 – 其他任何东西都是一个错误。


这个引用记住,一个图层是按照指定的顺序绘制的,所以重叠绘图可能是一个问题,特别是在创build密集的散点图时。 所以如果你想要一个一致的图(而不是依赖于数据框中的顺序),你需要多思考一下。


创build第二个图层

如果您希望某些值出现在其他值之上,则可以使用subset参数来创build第二个图层,以后肯定会绘制该图层。 你将需要明确加载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来selectdata参数中指定的相关数据。 而且不需要加载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)) 

在这里输入图像说明

2016更新:

顺序审美已被弃用 ,所以在这一点上,最简单的方法是对数据框架进行sorting,使绿色点位于底部,并绘制在最后。 如果你不想改变原始的data.frame,你可以在ggplot调用中对它进行sorting – 这里是一个使用%>%的例子,并且从dplyr包中进行sorting以进行即时sorting:

 library(dplyr) ggplot(df %>% arrange(label), aes(x = x, y = y, color = label, size = size)) + geom_point() 

在这里输入图像说明

ggplot2版本的原始2015年答案<2.0.0

在ggplot2中,您可以使用美学顺序来指定绘制点的顺序。 最后的绘图将出现在上面。 要应用这个,你可以创build一个variables来保存你想要绘制点的顺序。

把绿点放在最上面,把它画在别人之后:

 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)) 

对于这个简单的例子,你可以跳过创build一个新的sortingvariables,只是将labelvariables强制为一个因子,然后是一个数字:

 ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size, order=as.numeric(factor(df$label)))) 

这里的基本问题可以这样改写:

我如何控制我的情节的层次?

在'ggplot2'软件包中,可以通过将每个不同的图层分成不同的命令来快速完成此操作。 从层面上来看,需要一点练习,但实质上是归结于你想在其他东西上绘制的东西。 你从背景向上build立。

准备 :准备样本数据。 这个步骤只对这个例子是必要的,因为我们没有真正的数据来处理。

 # 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'function之前,一定要这样做。 太多的人通过尝试使用“ggplot”函数进行数据处理而陷入困境。 在这里,我们要创build两个图层:一个带有“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”function中的任何规格都将被放入图例中,这可能是无用的。

最后一点 :在这个例子中,你可以通过很多方式来获得想要的结果,但是了解'ggplot2'图层是如何工作的,以便充分利用'ggplot'图表是很重要的。 只要在调用'ggplot'函数之前将数据分成不同的层,就可以很好地控制屏幕上的事物。

它按照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))),]