ggplot XY 散点图 - 如何更改 select 点的 alpha 透明度?

ggplot XY scatter - how to change alpha transparency for select points?

我有大约 14,000 个 XY 对要绘制,并为此使用 ggplot2

由于点数高,我不得不使用非常低的点数alpha=0.025。 我想用不同的颜色和更不透明的颜色突出显示 7 个 XY 点,并附上文字图例。

目前,我的 7 个特殊数据点的颜色没有显示,因为它们也在 alpha=0.025。如何增加这些点的不透明度?

我目前的语法是:

trial <- ggplot(df, aes(x = df$SeqIdentityMean, 
                        y = df$SeqIdentityStdDev,
                        color = factor(df$PfamA_ID))) + 
            geom_point(alpha=0.025) + 
            labs(title="Mean Vs. standard deviation of PfamA seed lengths", 
                 x="Average Length (aa)",
                 y="Standard  Deviation of Length (aa)") + 
            theme(legend.title=element_blank(),
                  legend.key=element_rect(fill='NA'))

只需在数据集中创建一个 alpha 列,然后将要突出的点设置为 alpha = 1:

library(ggplot2)
alpha_vector = rep(0.025, nrow(mtcars))
alpha_vector[c(3,6,8)] = 1
mtcars$alpha = alpha_vector
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(aes(alpha = alpha))

这里的技巧是要意识到 alpha 只是另一种美学。

此外,我不会直接绘制 14k 点并依赖 alpha,我只会使用 2d binning。例如使用 hexbin:

ggplot(mtcars, aes(x = wt, y = mpg)) + geom_hexbin()

在不查看数据的情况下很难知道自己面临的挑战是什么,但是增加 14,000 分 alpha 本身不太可能使 "special points"` 足够突出。你可以试试这个:

## create artificial data set for this example
set.seed(1)     # for reproducibility
n  <- 1.4e4     # 14,000 points
df <- data.frame(SeqIdentityMean  =rnorm(n, mean=rep(-3:3, each=n/7)), 
                 SeqIdentityStdDev=rnorm(n, mean=rep(-3:3, each=n/7)),
                 PfamA_ID=rep(1:7, each=n/7))
df$PfamA_ID <- factor(df$PfamA_ID)

## you start here
library(ggplot2)
special.points <- sample(1:n, 7)
ggp <- ggplot(df, aes(x=SeqIdentityMean, y=SeqIdentityStdDev, color=PfamA_ID))+
  geom_point(alpha=0.05)+
  geom_point(data=df[special.points,], aes(fill=PfamA_ID), color="black", alpha=1, size=4, shape=21)+
  scale_color_discrete(guide=guide_legend(override.aes=list(alpha=1, size=3)))+
  scale_fill_discrete(guide="none", drop=FALSE)
ggp

通过使用shape=21(实心圆),你可以给特殊点一个黑色的轮廓,然后使用aes(fill=...)的颜色。 IMO 这让他们更加突出。最直接的方法是使用仅包含特殊点的层特定数据集额外调用 geom_point(...)

最后,即使是这个人为的例子,所有的组都混在一起了。如果你的真实数据是这样的话,我会倾向于尝试分面:

ggp + facet_wrap(~PfamA_ID)

这样做的好处是可以突出显示特殊点属于哪些组 (PfamA_ID),这在之前的图中并不明显。

关于您的代码的其他几点:

  1. 使用 ggplot(df, aes(x=df$a, y=df$b, ...), ...) 等是非常糟糕的做法。而是使用:ggplot(df, aes(x=a, y=b, ...), ...)。映射的全部要点是将美学(x、y、颜色等)与 df 中的列相关联,使用列名称。您将列作为独立向量传递。
  2. 在示例中,我将 df$PfamA_ID 设置为 data.frame 中的一个因子,而不是 aes(...) 的调用中的一个因子。这很重要,因为事实证明特殊点子集缺少一些因子水平。如果反之,特殊图层中的填充颜色将不会与主图层中的点颜色对齐。
  3. 当您设置 alpha=0.05(或其他)时,图例将使用该 alpha,这使得图例几乎毫无用处。要解决此问题,请使用:

    scale_color_discrete(guide=guide_legend(override.aes=list(alpha=1, size=3)))

编辑:对OP最后comment/request的回应。

所以听起来您想对除第一种颜色(去饱和的红色)以外的所有颜色使用 ggplot 的默认离散色标。这不是一个好主意,但这里有一个方法可以做到:

# create custom color palette containing ggplot defaults for all but first color; use black for first color
n.col <- length(levels(df$PfamA_ID))
cols  <- c("#000000", hcl(h=seq(15, 375, length=n.col+1), l=65, c=100)[2:n.col])
# set color and fill palette manually
ggp <- ggplot(df, aes(x=SeqIdentityMean, y=SeqIdentityStdDev, color=PfamA_ID))+
  geom_point(alpha=0.05)+
  geom_point(data=df[special.points,], aes(fill=PfamA_ID), color="black", alpha=1, size=4, shape=21)+
  scale_color_manual(values=cols, guide=guide_legend(override.aes=list(alpha=1, size=3)))+
  scale_fill_manual(values=cols, guide="none", drop=FALSE)
ggp

我们可以使用annotate:

ggplot(df, aes(x=SeqIdentityMean,
               y=SeqIdentityStdDev,
               color=PfamA_ID))+
  geom_point(alpha=0.05) +
  annotate("point",
           df$SeqIdentityMean[special.points],
           df$SeqIdentityStdDev[special.points])

使用@jlhoward 的示例数据:

## create artificial data set for this example
set.seed(1)     # for reproducibility
n  <- 1.4e4     # 14,000 points
df <- data.frame(SeqIdentityMean  =rnorm(n, mean=rep(-3:3, each=n/7)), 
                 SeqIdentityStdDev=rnorm(n, mean=rep(-3:3, each=n/7)),
                 PfamA_ID=rep(1:7, each=n/7))
df$PfamA_ID <- factor(df$PfamA_ID)

## you start here
library(ggplot2)
special.points <- sample(1:n, 7)

编辑 1: 我们可以添加 annotate("text",...)

ggplot(df, aes(x=SeqIdentityMean,
               y=SeqIdentityStdDev)) +
  geom_point(alpha=0.05) +
  annotate("point",
           df$SeqIdentityMean[special.points],
           df$SeqIdentityStdDev[special.points],
           col="red") +
  annotate("text",
           df$SeqIdentityMean[special.points],
           df$SeqIdentityStdDev[special.points],
           #text we want to display
           label=round(df$SeqIdentityStdDev[special.points],1),
           #adjust horizontal position of text
           hjust=-0.1)


编辑 2:

#subset of special points
df_sp <- df[special.points,]

#plot
ggplot(df, aes(x=SeqIdentityMean,
               y=SeqIdentityStdDev)) +
  geom_point(alpha=0.05) +
  #special points
  geom_point(data=df_sp,
             aes(SeqIdentityMean,SeqIdentityStdDev,col=PfamA_ID),size=3) +
  #custom legend
  scale_colour_manual(name = "Special Points",
                      values = df_sp$PfamA_ID,
                      labels = df_sp$SeqIdentityMean)