I'd like to propose another possible solution here. The prior solutions either require you to use an alpha scale or require you to hard code some values that are relative to the range of your data. The alpha scale is hard to get right if you really only want the low values to be transparent but not the mid/high. The hardcoding is problematic if you are making multiple graphs or using different inputs (e.g. a lower bound of .01 might look good on one dataset, but cut off important values on another).
The solution is to create a custom color map that begins with 'transparent'
. You can do this using existing color ramps like viridis.
Calling viridis::viridis_pal()(n)
will give you a vector of colors from the viridis scale. You can also access others with something like viridis::viridis_pal(option='magma')(10)
which will you give you 10 colors from the range of the magma palette .
To create your new color ramp, use scale_fill_gradientn()
and concatenate 'transparent'
in front of a range of colors from your desired scale:
scale_fill_gradientn(colors = c('transparent',viridis::viridis_pal()(10)))
Now you have a scale that is transparent on the smallest end of the range but then proceeds through the viridis color ramp. You can also choose your own colors here as desired rather than relying on a built-in scale.
TEST <- data.frame(X = rnorm(10000, -700, 50),
Y = rnorm(10000, -450, 50))
ggplot(TEST, aes(x = X, y = Y)) +
stat_density_2d(geom = "raster", aes(fill = ..density..*10e04), contour = F,
h = c(5, 5),
n = 300) +
ggtitle("7387")+
theme(plot.title = element_text(lineheight=.8, face="bold"))+
scale_y_reverse()+
scale_fill_gradientn(colors = c('transparent',viridis::viridis_pal()(10)))

You can also attenuate this effect by adjusting how many colors you use to build your ramp. The effect is subtle, but more colors means more of the "background" is filled in, while fewer colors will allow more of the background to fade away. The below compares viridis::viridis_pal()(5)
and viridis::viridis_pal()(30)
:

This effect is independent of the scaling of your data--if you multiply density by 10, the result will be identical (which it would not be if you use the methods based on hard-coded limits).