r - ggplot2 with gradient density fill? -
i have generated ggplot2 graph , want fill showing density of points. have managed using following formula density:
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])}
and getting density of points in new "density" column based on formula, "lfc" , "pval" being x,y variables:
data.ma$density <- get_density(data.ma$pval, data.ma$lfc)
the ggplot object plotting is:
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()
this gives me following graph:
here samples of data.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
my question how can make gradient more disperse in middle, not red stripe in middle , more of gradient?
can suggest different formula density perhaps?
or way define gradient better in more separate blocks?
the data sample small try reproduce plot , check possible solutions here attempt using scale_colour_gradientn , emphasizing midpoints
#emulating solution: df = data.frame(seq = 1:1000, rnorm= rnorm(1000)+5) library(ggplot2) = 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 function making gradients colfunc = colorramppalette(c("blue", "white", "red")) #providing exponential gradient exp_seq= seq(from = 0.1, = 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)
edit
the argument values
of scale_colour_gradientn
function accepts vector of values ranging 0 - 1. there should many elements in vector there colors.
colfunc(11)
function makes vector of colors, in case output 11 colors since argument specified 11. argument values
of scale_colour_gradientn
needs have 11 values on map colors. these values relate data function scales::rescale
(https://www.rdocumentation.org/packages/scales/versions/0.4.1/topics/rescale) takes range of data , maps 0 - 1 range. if range of data instance 100 - 400 , want midpoint @ 153, than:
scales::rescale(c(100, 153, 400)) #output 0.0000000 0.1766667 1.0000000
you want map "white" color (element 6 of vector specified colors argument in above example) color @ 0.1766667, apart need specify additional 4 elements in range 0 - 0.1766667 light blue colors , additional 4 elements light red colors. example
values = c(0, 0.01, 0.03, 0.6, 0.1, 0.1766667, 0.3, 0.5, 0.7, 0.9, 1)
bit arbitrary, perhaps better strategy check data , see in range emphasize , chose values. instance:
range of data 100 400, want midpoint @ 153 , emphasize 123 - 183, provide custom range values argument:
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
in exp_seq part defined vector exp_seq= seq(from = 0.1, = 0.6, length.out = 4)^2
exp_seq #output 0.01000000 0.07111111 0.18777778 0.36000000 rev(exp_seq) #just reverse #output 0.36000000 0.18777778 0.07111111 0.01000000
and included in vector
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
and passed values argument map 11 colors defined in colors argument. if do:
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()
the result like:
if unclear please let me know.
Comments
Post a Comment