I have a spatial dataset, containing values from 0 to 10. I want every number (11 numbers) to have a unique color from a gradient. The simple plot function does the trick (assigning one color to one value) but my default is ggplot, which I also want to use here. ggplot only uses ten colors for some reason and I cannot figure out why. I think I might just be using the wrong scale_x_y function.
Reproducible example:
library(raster)
#Colors
cols <- colorRampPalette(c("yellow", "red", "darkred", "black"))
# Create Raster
r <- raster(ncol=100, nrow=100)
r[] <- sample(0:10, 10000, replace = T)
# Plot simple
plot(r, col=cols(11)) # 11 colors seen here
# Convert to df
r <- as.data.frame(r, xy=T)
# Plot with ggplot
X <- ggplot(data = r) geom_raster(aes(x = x, y = y, fill = layer), interpolate = F)
scale_fill_stepsn(colors=cols(11), breaks=seq(0,10,1), show.limits=T)
print(X) # only 10 colors seen here
CodePudding user response:
In scale_fill_stepsn
the breaks are at the limits of each bin. If you have a sequence of 11 breaks, then you only have ten bins (if you have 11 fence posts you only have 10 stretches of fence between them). You need to add one to your sequence of breaks, otherwise the level 10 will be excluded:
ggplot(data = r)
geom_raster(aes(x = x, y = y, fill = layer), interpolate = FALSE)
scale_fill_stepsn(colors = cols(11), breaks = seq(0, 11, 1),
show.limits = TRUE)
coord_equal()
An alternative is to use a manual scale, which I think makes more sense here. As I understand it, you are treating the fill color as a discrete variable, and the labels should correspond to the levels rather than corresponding to the break between labels as implied by scale_fill_stepsn
ggplot(data = r)
geom_raster(aes(x = x, y = y, fill = factor(layer, 10:0)))
scale_fill_manual(values = rev(cols(11)), name = 'layer')
coord_equal()
EDIT
To get the legend at the bottom, try:
ggplot(data = r)
geom_raster(aes(x = x, y = y, fill = factor(layer, 0:10)))
scale_fill_manual(values = cols(11), name = 'layer ')
coord_equal()
guides(fill = guide_legend(label.position = 'top', nrow = 1))
theme(legend.position = 'bottom',
legend.spacing.x = unit(0, 'mm'),
legend.title = element_text(hjust = 3, vjust = 0.25))