问题
I quite like the look and feel of ggplot2
and use them often to display raster data (e.g facetting over timesteps for time-varying precipitation fields is very useful).
However, I'm still wondering whether it is easily possible to bin the continuous raster values into discrete bins and assign to each bin a single colour, that is shown in the legend (as many GIS systems do).
I tried with the guide = "legend"
, and breaks
arguments of the scale_fill_gradient
option. However these affect just the legend on the side of the graph, but the plotted values are still continuous.
library(ggplot2)
data <- data.frame(x=rep(seq(1:10),times = 10), y=rep(seq(1:10),each = 10), value = runif(100,-10,10))
ggplot(data = data, aes(x=x,y=y)) +
geom_raster(aes(fill = value)) +
coord_equal() +
scale_fill_gradient2(low = "darkred", mid = "white", high = "midnightblue",
guide = "legend", breaks = c(-8,-4,0,4,8))
My question is mainly how to discretize the data that is plotted in ggplot
, so that the reader of the graph can make quantitative conclusions on the values represented by the colors.
Secondly, how can I still use a diverging color palette (similar to scale_fill_gradient2
), that is centered around zero or another specific value?
回答1:
You should use the raster
package to work with raster data. This
package provides several function to work with categorical
rasters. For example, with reclassify
you can convert a continuous
file into a discrete raster. The next example is adapted from
this question:
library(raster)
f <- system.file("external/test.grd", package="raster")
r <- raster(f)
r <- reclassify(r, c(0, 500, 1,
500, 2000, 2))
On the other hand, if you want to use the ggplot2
functions, the
rasterVis
package provides a simple wrapper around ggplot
that
works with RasterLayer
objects:
library(rasterVis)
gplot(r) +
geom_raster(aes(fill = factor(value))) +
coord_equal()

to define your own colors you can add then:
scale_fill_manual(values=c('red','green')))
回答2:
The best is indeed to modify the underlying data set by manually discretizing it. Below answer is based on the answer by joran.
library(ggplot2)
set.seed(1)
data <- data.frame(x = rep(seq(1:10),times = 10),
y = rep(seq(1:10),each = 10),
value = runif(100,-10,10))
# Define category breaks
breaks <- c(-Inf,-3:3,Inf)
data$valueDiscr <- cut(data$value,
breaks = breaks,
right = FALSE)
# Define colors using the function also used by "scale_fill_gradient2"
discr_colors_fct <-
scales::div_gradient_pal(low = "darkred",
mid = "white",
high = "midnightblue")
discr_colors <- discr_colors_fct(seq(0, 1, length.out = length(breaks)))
discr_colors
# [1] "#8B0000" "#B1503B" "#D18978" "#EBC3B9" "#FFFFFF" "#C8C0DB" "#9184B7" "#5B4C93" "#191970"
ggplot(data = data, aes(x=x,y=y)) +
geom_raster(aes(fill = valueDiscr)) +
coord_equal() +
scale_fill_manual(values = discr_colors) +
guides(fill = guide_legend(reverse=T))
来源:https://stackoverflow.com/questions/25280763/plot-continuous-raster-data-in-binned-classes-with-ggplot2-in-r