Reputation: 4279
I want to simultaneously visualize the mean and error (variance) of predictions in spatial data. One possible method for doing this would be to map the mean to hue and the error to either saturation or luminance. Although I'm doing this in maps, I'll offer a much simpler minimal working example here adapted from ggplot2's documentation.
library(ggplot2)
library(RColorBrewer)
dsub <- subset(diamonds, x > 5 & x < 6 & y > 5 & y < 6)
dsub$var <- dsub$x
dsub$diff <- with(dsub, sqrt(abs(x-y))* sign(x-y))
d <- qplot(x, y, data=dsub, colour=diff)
d + scale_color_gradientn(colours=brewer.pal(7,"YlOrRd"))
What I would like to see, rather than the attached plot, is a version where the luminance or the saturation of the color ramp is mapped to the variable "var" in the data. Ideally, such a plot would include a 2-dimensional legend.
Upvotes: 4
Views: 739
Reputation: 3822
You can also just use scale_fill_identity()
, convert your data to a valid visual channel range, and then map your values with a function for the fill:
df <- expand.grid(H = c(30, 50, 230, 250),
S = seq(0, 100, by = 10),
L = seq(0, 100, by = 10))
ggplot(df) +
facet_wrap(~ H ) +
scale_x_continuous(
name = 'Luminance',
breaks = seq(0, 100, by = 20),
expand = c(0,0),
sec.axis = sec_axis(~., name = 'Hue')) +
scale_y_continuous(
name = 'Saturation',
breaks = seq(0, 100, by = 20),
expand = c(0,0)) +
scale_fill_identity() +
geom_raster(
mapping = aes(
x = L,
y = S,
fill = hcl(H, S, L)),
)
Upvotes: 1
Reputation: 514
One solution that's worked for me has been to use a couple layers to represent the data (in this example I'm more or less using hue and value as the two aesthetics, but saturation could be substituted for value by switching the black layer to white), and then generate a custom 2D legend. So, using the data you provided:
# main plot
main <- ggplot(dsub) +
geom_tile(aes(x, y, fill=diff)) +
scale_fill_gradient(high="red", low="blue") +
geom_tile(aes(x, y, alpha=var)) +
theme(legend.position="none")
# 2d legend
diff <- range(dsub$diff)
var <- range(dsub$var)
legdata <- expand.grid(diff=seq(diff[1], diff[2], (diff[2]-diff[1])/20),
var=seq(var[1], var[2], (var[2]-var[1])/20))
legend <- ggplot(legdata) +
geom_tile(aes(diff, var, fill=diff)) +
scale_fill_gradient(high="red", low="blue") +
geom_tile(aes(diff, var, alpha=var)) +
scale_x_continuous(expand=c(0,0)) +
scale_y_continuous(expand=c(0,0)) +
theme(panel.background=element_blank(), panel.grid=element_blank(),
legend.position="none") +
coord_fixed() +
labs(title="legend")
# combine plot and legend
library(gridExtra)
plt <- arrangeGrob(main, legend, nrow=1, widths=c(3, 1))
print(plt)
Upvotes: 5