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:

ma plot gradient

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) 

enter image description here

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:

enter image description here

if unclear please let me know.


Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -