I am trying to produce a plot using geom_raster()
or geom_tile()
which includes positive and negative values with very different ranges and data distributions in the negative and positive domains. I am after a divergent scale centred around 0, but with good colour gradation across both the positive and negative values.
I can actually produce the output I want by producing two plots (code below), one of the positive domain and one in the negative, and then saving the plots and overlaying them in an image editing program, although that approach has its own problems. The code below produces these two separate plots to provide an indication of how I'd like things to look if the two layers could be stacked. Unfortunately, when I try this the fill from the second plot replaces that from the first.
I've also posted sample code that produces one of the solutions suggested here, which is clearly still not the same as the results I'm hoping to achieve in terms of the resolution in the colour gradient for the band with the much narrower range (in this case the negative values).
lastly, sorry for the large sample dataset (part of a much larger df), but it was hard to convey the issues with a smaller one.
Any suggestions much appreciated.
library(ggplot2)
library(scales)
df<-structure(list(x = c(1979, 1979, 1979, 1979, 1979, 1979, 1979,
1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979,
1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979,
1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1980,
1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
1980, 1980, 1980, 1980, 1980, 1981, 1981, 1981, 1981, 1981, 1981,
1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981,
1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981,
1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981
), y = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39), z = c(159.669, 179.469, 211.73, 217.466, 239.328, 353.454,
507.62, 656.972, 793.268, 1109.764, 1546.142, 1730.088, 1617.977,
1384.787, 1134.496, 906.544, 739.345, 614.798, 515.718, 428.918,
405.267, 466.252, 451.449, 346.907, 274.782, 220.826, 189.506,
139.73, 114.489, 101.309, 109.289, 114.041, 87.833, 65.061, 48.837,
45.621, 49.423, 198.88, 552.906, -219, -220, -221, -222, 88.223,
3303.874, 3861.382, 3540.399, 6716.934, 16477.35, 35683.23, 59065.06,
48825.8, 34849.34, 31240.76, 28330.3, 25030.27, 21862.9, 18641.04,
15372.67, 12525.73, 10198.47, 8496.241, 7267.41, 5876.377, 4155.166,
2666.032, 1786.76, 1246.569, 853.448, 624.179, 445.049, 353.794,
295.245, 262.17, 322.384, 415.967, 853.054, 1393.934, -177, -178,
-179, -180, -181, -182, -183, -184, -185, -186, -187, -188, -189,
-190, -191, -192, -193, -194, -195, 508.171, 4042.008, 6805.848,
9286.832, 13477.52, 16515.75, 17776.59, 17434.65, 15664.74, 13071.11,
10933.25, 10161.01, 11719.8, 18530.01, 33172.12, 59649.19, 62212.69,
51674, 39258.99, 32972.9)), .Names = c("x", "y", "z"), row.names = c(4384L,
4385L, 4386L, 4387L, 4388L, 4389L, 4390L, 4391L, 4392L, 4393L,
4394L, 4395L, 4396L, 4397L, 4398L, 4399L, 4400L, 4401L, 4402L,
4403L, 4404L, 4405L, 4406L, 4407L, 4408L, 4409L, 4410L, 4411L,
4412L, 4413L, 4414L, 4415L, 4416L, 4417L, 4418L, 4419L, 4420L,
4421L, 4422L, 4749L, 4750L, 4751L, 4752L, 4753L, 4754L, 4755L,
4756L, 4757L, 4758L, 4759L, 4760L, 4761L, 4762L, 4763L, 4764L,
4765L, 4766L, 4767L, 4768L, 4769L, 4770L, 4771L, 4772L, 4773L,
4774L, 4775L, 4776L, 4777L, 4778L, 4779L, 4780L, 4781L, 4782L,
4783L, 4784L, 4785L, 4786L, 4787L, 5115L, 5116L, 5117L, 5118L,
5119L, 5120L, 5121L, 5122L, 5123L, 5124L, 5125L, 5126L, 5127L,
5128L, 5129L, 5130L, 5131L, 5132L, 5133L, 5134L, 5135L, 5136L,
5137L, 5138L, 5139L, 5140L, 5141L, 5142L, 5143L, 5144L, 5145L,
5146L, 5147L, 5148L, 5149L, 5150L, 5151L, 5152L, 5153L), class = "data.frame")
#produce negative value plot and associated sensible scale and colour range
ggplot() +
geom_tile(data = subset(df, z <= 0), aes(x = x,y = y, fill = z)) +
scale_fill_gradient(low = "red", high = "white") +
scale_x_continuous(limits = c(1979, 1982)) +
scale_y_continuous(limits = c(0, 40))
#produce positive value plot and associated sensible scale and colour range
ggplot() +
geom_tile(data = subset(df, z > 0), aes(x = x, y = y, fill = z)) +
scale_fill_gradient(low = "white", high = "blue", trans = "log10") +
scale_x_continuous(limits = c(1979, 1982)) +
scale_y_continuous(limits = c(0, 40))
#one solution, but one that's inferior to what could be achieved overlaying the above plots.
ggplot(df, aes(x = x, y = y, fill = z)) + geom_tile() +
scale_fill_gradientn(colours = c("red", "white", "blue"),
values = rescale(c(min(df$z) ,0 , max(df$z))),
guide = "colorbar", limits = c(min(df$z), max(df$z))) +
scale_x_continuous(limits = c(1979, 1982)) + scale_y_continuous(limits = c(0, 40))