Continuous gradient color and fixed weight heatmap ggplot2
I am switching from Mathematica to R, but I am finding some difficulty with rendering.
I am trying to make a heatmap like this:
short
penetration scc pi0
1 0 0 0.002545268
2 5 0 -0.408621176
3 10 0 -0.929432006
4 15 0 -1.121309680
5 20 0 -1.587298317
6 25 0 -2.957853131
7 30 0 -5.123329738
8 0 50 1.199748327
9 5 50 0.788581883
10 10 50 0.267771053
11 15 50 0.075893379
12 20 50 -0.390095258
13 25 50 -1.760650073
14 30 50 -3.926126679
15 0 100 2.396951386
16 5 100 1.985784941
17 10 100 1.464974112
18 15 100 1.273096438
19 20 100 0.807107801
20 25 100 -0.563447014
21 30 100 -2.728923621
mycol <- c("navy", "blue", "cyan", "lightcyan", "yellow", "red", "red4")
ggplot(data = short, aes(x = penetration, y = scc)) +
geom_tile(aes(fill = pi0)) +
scale_fill_gradientn(colours = mycol)
And I get this:
But I need something like this:
That is, I would like the color to be continuous (degraded) across the plot surface, instead of being discrete for each square. I've seen in other SO questions that some people interpolate data, but I think there should be an easier way to do this inside a ggplot call (this is the default in Mathematica).
Also, I would like to lock the color scale so that 0 is always white (thus between warm colors for positive values ββand cool for negative values), and the color distribution is always the same on the plots regardless of the data range (since I will be using one and the same plot structure for multiple datasets)
source to share
You can use geom_raster
with interpolate=TRUE
:
ggplot(short , aes(x = penetration, y = scc)) +
geom_raster(aes(fill = pi0), interpolate=TRUE) +
scale_fill_gradient2(low="navy", mid="white", high="red",
midpoint=0, limits=range(short$pi0)) +
theme_classic()
To get the same color-to-value mapping pi0
across all of your plots, set the limits
argument parameter to scale_fill_gradient2
the same in each plot. For example, if you have three data frames short
, short2
and short3
, you can do this:
# Get range of `pi0` across all data frames
pi0.rng = range(lapply(list(short, short2, short3), function(s) s$pi0))
Then set limits=pi0.rng
in scale_fill_gradient2
on all of your charts.
source to share
I would adjust your scale_fill_gradient2
:
scale_fill_gradient2('pi0', low = "blue", mid = "white", high = "red", midpoint = 0)
to make the graphs of the straight lines comparable, add a consistent one limits
to each plot:
scale_fill_gradient2('pi0', low = "blue", mid = "white", high = "red", midpoint = 0, limits=c('your lower limit','your upper limit'))
source to share