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

时间:2013-03-29 15:28:54

标签: r ggplot2 rpy2

假设我正在绘制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的解决方案。感谢

4 个答案:

答案 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'))

enter image description here

更新

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

enter image description here

答案 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()

enter image description here

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)

demo chart

请注意,基础图层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))),]