How to improve a spatial raster map using ggplot when compared to spplot?
How can I improve the legend of spatial raster map plot using ggplot when compared to a spplot() legend?
I would like plot spatial maps using ggplot() instead of ssplot() however there are a few things that I would like to improve when compared to the spplot:
- create a ggplot legend that goes from small (bottom) to large values (top)
- Have the breaks in the ggplot legend similar to the ssplot() legend so that I know what the boundaries are of each color.
## load packages
require(raster)
require(ggplot2)
require(rgdal)
require(RColorBrewer)
set.seed(1)
r <- raster(xmn=-110, xmx=-90, ymn=40, ymx=60, ncols=40, nrows=40,
crs="开发者_开发技巧+proj=lcc +lat_1=48 +lat_2=33 +lon_0=-100
+ellps=WGS84")
r <- setValues(r,matrix(rnorm(1600, mean=0.4,sd=0.2)))
## 1. spatial map with spplot
cuts <-seq(minValue(r),maxValue(r),length.out=8)
cuts = round(cuts,digits=2)
col.regions = brewer.pal(length(cuts)+3-1, "RdYlGn")
print(
spplot(as(r, 'SpatialGridDataFrame'),at=cuts,
col.regions=col.regions,
colorkey=list(labels=list(at=cuts),at=cuts), pretty=TRUE,
scales=list(draw=T)
)
)
## 2. spatial map with ggplot
p = rasterToPoints(r); df = data.frame(p)
colnames(df) = c("x", "y", "NDVI")
p <- ggplot(data=df) + geom_tile(aes(x, y, fill=NDVI)) +
coord_equal() + labs(x=NULL, y=NULL) +
scale_fill_gradient2(low="red", mid="yellow",high="green",
limits=c(minValue(r),maxValue(r)), midpoint = 0.4) + theme_bw() +
scale_x_continuous(expand=c(0,0)) + scale_y_continuous(expand=c(0,0))
print(p)
ssplot() result
ggplot() result
thanks @joran for the pointer to that.
here is an example code and output using the dev version:
br <- seq(min(df$NDVI), max(df$NDVI), len=8)
ggplot(data=df) +
geom_tile(aes(x, y, fill=NDVI)) +
scale_fill_gradient(low="red", high="green",
breaks=br, labels=sprintf("%.02f", br),
guide=guide_colorbar(title=NULL, nbin=100, barheight=unit(0.75, "npc"), label.hjust=1)) +
scale_x_continuous(expand=c(0,0)) +
scale_y_continuous(expand=c(0,0))
you can probably try this by:
# from Hadley's instruction
install.packages("devtools")
library(devtools)
dev_mode() # to avoid interfering with your existing install
install_github("ggplot2", username="kohske", branch = "feature/new-guides-with-gtable")
library(ggplot2)
UPDATED:
here is the instruction for the installation from scratch:
install.packages(
c('devtools', 'digest', 'memoise', 'plyr', 'reshape2', 'RColorBrewer', 'stringr', 'dichromat', 'munsell', 'plyr', 'colorspace'),
dep=TRUE)
library(devtools)
dev_mode()
install_github("scales")
install_github("ggplot2", username="kohske", branch = "feature/new-guides-with-gtable")
I'm not sure how to address (1) off the top of my head. But here are some possible solutions for (2) and (3).
I don't believe that ggplot2
currently is capable of labeling the legend in that manner. However, Koske has been working on some code that may be rolled into ggplot2
in the future that creates legends that are styled in this manner. Here is a link, although it will require installing some additional packages and is only alpha.
To get the specific breaks you're looking for, try this:
br <- c(-0.25,-0.05,0.15,0.35,0.56,0.76,0.96,1.16)
p <- ggplot(data=df) + geom_tile(aes(x, y, fill=NDVI)) +
coord_equal() + labs(x=NULL, y=NULL) +
scale_fill_gradient(low="red", mid="yellow",high="green",
breaks = br) + theme_bw() +
scale_x_continuous(expand=c(0,0)) + scale_y_continuous(expand=c(0,0))
print(p)
which produced this graph on my machine:
I have not tested what this would look like using the experimental code mentioned above.
Re: (2)
First cut()
your data to get a binned dataset. Use breaks
and labels
options in cut()
to obtain the correct labels, e.g.:
dat$col <- cut(
df$NDVI,
breaks=c(-Inf, -0.25, 0.05, ...whatever..., Inf),
labels=c(-0.25, 0.05, ...whatever..., "")
)
Then you can plot using ggplot and shifting the labels so that they are right on the color boudaries using:
scale_fill_manual (your options...) + guides(fill=guide_legend(label.vjust = 1.2)) #1.2= what fits your legend best. Use label.hjust if using an horizontal color bar
See also: Generating a color legend with shifted labels using ggplot2
Alternatively, you can create the color legend with an external script (e.g. GrADS makes nice color legends using the right scripts) and specify the same colors manually in scale_fill_manual.
精彩评论