I am trying to add a relief to an interactive choropleth map. I saw that in a non-interactive setting this can be done using the alpha
scale of geom_raster
and the fill
scale of geom_polygon
. This works just fine:
library(ggplot2)
library(plotly)
# load raster data
volcano_raster <- as.data.frame(volcano)
volcano_raster <- reshape(data = volcano_raster,
direction = "long",
varying = colnames(volcano_raster),
timevar = "y",
v.names = "alpha",
idvar = "x")[,c("x", "y", "alpha")]
rownames(volcano_raster) <- NULL
volcano_raster$f <- 0
# create polygon data
volcano_polygon <- data.frame(x = c(1, 25, 25, 1, 25, 50, 50, 25, 50, 75, 75, 50, 75, 87, 87, 75),
y = rep(c(61, 61, 1, 1), 4),
order = rep(1:4, 4),
group = rep(1:4, each = 4),
fill = rep(1:4, each = 4))
# create plot (works)
p <- ggplot()
p <- p + geom_polygon(data = volcano_polygon,
aes(x = x,
y = y,
fill = fill,
group = group))
p <- p + geom_raster(data = volcano_raster,
aes(x = x, y = y, alpha = alpha))
p
But as soon as I try to make it interactive through ggplotly
, R complains that the fill
aesthetic is missing:
ggplotly(p)
Error in `[.data.frame`(g, , c("fill_plotlyDomain", "fill")) :
undefined columns selected
To avoid this error I tried to add a dummy fill
aesthetic. However, then ggplotly
does not display the alpha
shading:
# create plot (works)
p <- ggplot()
p <- p + geom_polygon(data = volcano_polygon,
aes(x = x,
y = y,
fill = fill,
group = group))
p <- p + geom_raster(data = volcano_raster,
aes(x = x, y = y, fill = 0, alpha = alpha))
ggplotly(p)
I know from here that ggplotly can combine the fill and alpha aesthetics when using one geom. This also works in my case:
p <- ggplot()
p <- p + geom_polygon(data = volcano_polygon,
aes(x = x,
y = y,
fill = fill,
group = group,
alpha = fill))
ggplotly(p)
Unfortunately, I cannot figure out how to create a plot using ggplotly
that uses the fill
aesthetic of one geom
and the alpha
aesthetic of another.
EDIT:
This post describes a workaround through using geom_point
instead of geom_raster
. However, the size
of geom_point
(unlike width
of geom_bar
) is given in pixels and not relative to the resolution. As a result it's very hard to find the correct value for the size
argument, making it rather impractical for an interactive setting.