我已经生成了一个ggplot2图表,我想填写它显示点的密度。我使用以下密度公式管理它:
get_density <- function(x, y, n = 250) {
dens <- MASS::kde2d(x = x, y = y, n = n)
ix <- findInterval(x, dens$x)
iy <- findInterval(y, dens$y)
ii <- cbind(ix, iy)
return(dens$z[ii])}
然后在新的密度中获得点的密度&#34;基于公式的列,用&#34; lfc&#34;和&#34; pval&#34;是x,y变量:
data.MA$density <- get_density(data.MA$pval, data.MA$lfc)
我正在绘制的ggplot对象是:
heatmap2 <- ggplot() +
geom_point(data = filter(data.MA, chg == "unchanged"),
aes(basemean, lfc, color = density)) +
geom_point(data = filter(data.MA, chg == "changed"),
aes(basemean, lfc, fill = dir),
shape = 21, size = 2, stroke = 0.1) +
scale_fill_manual(values = c("#FFA600", "#00B2FF", "#00B2FF")) +
scale_colour_gradient2(low = "blue", mid = "white", high = "red", midpoint = 10) +
theme_bw() + scale_y_continuous() + scale_x_continuous()
这给了我以下图表:
以下是数据样本.MA:
gene pval lfc basemean density dir peakid chg
1 NXT1 41.22403 3.58 9.50 3.339690e-02 increased 1 changed
2 BEND5 23.41567 5.03 8.01 0.000000e+00 increased 2 changed
3 PLB1 23.19450 7.91 8.13 4.849746e-78 increased 3 changed
4 LYRM9 20.81531 2.35 11.43 0.000000e+00 increased 4 changed
5 MIR4464 14.73049 3.65 7.99 0.000000e+00 increased 5 changed
6 HSD17B2 14.63451 4.51 7.31 0.000000e+00 increased 6 changed
我的问题是如何让渐变在中间更加分散,所以它不仅仅是中间的红色条纹而是更多的渐变?
任何人都可以建议一个不同的密度公式吗?
或者更好地定义渐变的方法是在更单独的块中?
答案 0 :(得分:1)
数据样本太小,无法尝试重现绘图并检查可能的解决方案,但这是尝试使用scale_colour_gradientn并强调中点
#emulating your solution:
df = data.frame(seq = 1:1000, rnorm= rnorm(1000)+5)
library(ggplot2)
A = ggplot(df) +
geom_point(aes(seq, rnorm, color = rnorm)) +
scale_colour_gradient2(low = "blue", mid = "white", high = "red", midpoint = 5) +
theme_bw() + scale_y_continuous() + scale_x_continuous()
#providing a function for making gradients
colfunc = colorRampPalette(c("blue", "white", "red"))
#providing an exponential gradient
exp_seq= seq(from = 0.1, to = 0.6, length.out = 4)^2
B = ggplot(df) +
geom_point(aes(seq, rnorm, color = rnorm)) +
scale_colour_gradientn(colors=colfunc(11), values = c(0, exp_seq, rev(1-exp_seq), 1)) +
theme_bw() + scale_y_continuous() + scale_x_continuous()
library(cowplot)
plot_grid(A, B, ncol = 2)
编辑
values
函数的参数scale_colour_gradientn
接受一个值为0到1的向量。此向量中的元素应该与颜色一样多。
colfunc(11)
是一个生成颜色矢量的函数,在这种情况下,它将输出11种颜色,因为参数被指定为11.因此values
的参数scale_colour_gradientn
需要有11个值,它将映射颜色。这些值与函数scales::rescale
的数据相关
(https://www.rdocumentation.org/packages/scales/versions/0.4.1/topics/rescale)
它获取您的数据范围并将其映射到0 - 1范围。如果您的数据范围例如是100 - 400,并且您希望中点位于153,那么:
scales::rescale(c(100, 153, 400))
#output 0.0000000 0.1766667 1.0000000
你想要映射&#34; white&#34; color(在上例中为colors参数指定的向量的元素6)颜色为0.1766667,除此之外,您需要指定0 - 0.1766667范围内的其他4个元素用于浅蓝色,另外4个元素用于浅红色。例如,
values = c(0, 0.01, 0.03, 0.6, 0.1, 0.1766667, 0.3, 0.5, 0.7, 0.9, 1)
但这有点武断,也许更好的策略是检查你的数据,看看你想强调的范围,并选择这些值。例如:
数据范围为100到400,您希望中点为153并强调123 - 183,您可以为值参数提供自定义范围:
scales::rescale(c(100, 113, 123, 133, 143, 153, 163, 173, 183, 193, 400))
#output 0.00000000 0.04333333 0.07666667 0.11000000 0.14333333 0.17666667 0.21000000 0.24333333 0.27666667 0.31000000 1.00000000
在exp_seq部分我就是
定义了一个向量exp_seq= seq(from = 0.1, to = 0.6, length.out = 4)^2
exp_seq
#output 0.01000000 0.07111111 0.18777778 0.36000000
rev(exp_seq) #just the reverse
#output 0.36000000 0.18777778 0.07111111 0.01000000
并将其包含在另一个载体中
c(0, exp_seq, 1-rev(exp_seq), 1)
#output 0.00000000 0.01000000 0.07111111 0.18777778 0.36000000 0.64000000 0.81222222 0.92888889 0.99000000 1.00000000
并将其传递给values参数以映射我在colors参数中定义的11种颜色。 如果我这样做:
ggplot(df) +
geom_point(aes(seq, rnorm, color = rnorm)) +
scale_colour_gradientn(colors=colfunc(11), values = scales::rescale(c(100, 113, 123, 133, 143, 153, 163, 173, 183, 193, 400))) +
theme_bw() + scale_y_continuous() + scale_x_continuous()
结果如下:
如果有任何不清楚的地方,请告诉我。