tylermorganwall / rayshader

R Package for 2D and 3D mapping and data visualization
https://www.rayshader.com/
2.05k stars 211 forks source link

Propper alignment of geoms when supplying multiple ggplots #281

Open DasHammett opened 1 year ago

DasHammett commented 1 year ago

Is your feature request related to a problem? Please describe. I am trying to create a 3D map based on a ggmap object with a geom_sf() layer into it, but the 3D render of the fill attribute is either not aligning or the render also computes heights for areas where there is no fill argument.

Here's the code I use (I am aware this is not a reprex)

maps_height <- ggplot() +
    geom_sf(data = mapa,
            aes(fill = pc_vots),
            inherit.aes = FALSE,
            lwd = 0.1
            ) +
    theme_void() +
    theme(legend.position = "none")

map <- ggmap(topo) +
    geom_sf(data = mapa,
            aes(fill = Partitmesvotat),
            inherit.aes = FALSE,
            lwd = 0.1,
            ) +
    scale_fill_manual(values = colors, breaks = partits) +
    theme_void() +
    theme(legend.position = "none")

plot_gg(ggobj = map,
        ggobj_height = maps_height,
        multicore = TRUE,
        scale = 150,
        pointcontract = 1,
        triangulate = TRUE)

I use 2 ggplot objects because I need to control the color of the fill in the geom_sf (that would be the map object), and then I provide another ggplot object with the height (maps_height).

When plotting this combination with the instruction above, I get this result: image

As you can see in the bottom part, the heights are not aligned with the boundaries of the geom_sf. It looks like the maps_height needs to be scaled up a bit. Perhaps this is because I am not using the topografic map from ggmap but an empty ggplot and the scales are different.

Now if I force the maps_height to be built with the topografic layer as well with:

maps_height <- ggmap(topo) +
    geom_sf(data = mapa,
            aes(fill = pc_vots),
            inherit.aes = FALSE,
            lwd = 0.1
            ) +
    theme_void() +
    theme(legend.position = "none")

I get this result: image

Where you can see a mess of lines emerging from the topografic layer that has no fill attribute

Describe the solution you'd like I would like either an automatic scale of geoms shared if multiple ggplot objects are passed or not consider the topografic layer for the 3D height, sepecially when there is no fill argument. BUT the alignment of the geom_sf is correct

Describe alternatives you've considered I have looked how I can scale up/down the ggplot objects to make sure they are the same size, but have failed to do so.

Additional context Creating a 3D plot only using the geom_sf layer, works beautifully and have no issues whatsoever

DasHammett commented 1 year ago

I might have solved the issue.

maps_height <- ggmap(topo, darken = c(1,"white")) +
    geom_sf(data = mapa,
            aes(fill = pc_vots),
            inherit.aes = FALSE,
           # color = "grey20",
            lwd = 0.1
            ) +
    theme_void() +
    theme(legend.position = "none")

I have used the darken option from ggmap to override the map with a pure white background. This is then interpreted by plot_gg as 0 height.

image

There are still some minor artifacts at the edges of the plot that with the shadows are exaggerated