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
),这在之前的图中并不明显。
关于您的代码的其他几点:
- 使用
ggplot(df, aes(x=df$a, y=df$b, ...), ...)
等是非常糟糕的做法。而是使用:ggplot(df, aes(x=a, y=b, ...), ...)
。映射的全部要点是将美学(x、y、颜色等)与 df 中的列相关联,使用列名称。您将列作为独立向量传递。
- 在示例中,我将
df$PfamA_ID
设置为 data.frame 中的一个因子,而不是 aes(...)
的调用中的一个因子。这很重要,因为事实证明特殊点子集缺少一些因子水平。如果反之,特殊图层中的填充颜色将不会与主图层中的点颜色对齐。
当您设置 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)
我有大约 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
),这在之前的图中并不明显。
关于您的代码的其他几点:
- 使用
ggplot(df, aes(x=df$a, y=df$b, ...), ...)
等是非常糟糕的做法。而是使用:ggplot(df, aes(x=a, y=b, ...), ...)
。映射的全部要点是将美学(x、y、颜色等)与 df 中的列相关联,使用列名称。您将列作为独立向量传递。 - 在示例中,我将
df$PfamA_ID
设置为 data.frame 中的一个因子,而不是aes(...)
的调用中的一个因子。这很重要,因为事实证明特殊点子集缺少一些因子水平。如果反之,特殊图层中的填充颜色将不会与主图层中的点颜色对齐。 当您设置
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)