tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.55k stars 2.03k forks source link

guide_colorsteps() from new ggplot2 version #5757

Closed dominicroye closed 8 months ago

dominicroye commented 9 months ago

I found a problem with guide_colorsteps after installing the last ggplot2 version.

I'm not sure why, but the order of classes is not correct. Some of the extreme classes are showing up in the middle. Using the function example data it seems to work, but here it doesn't.

Here is the code to reproduce the bug:

library(terra)
library(giscoR)
library(elevatr)
library(tidyverse)

ger <- gisco_get_countries(country = "Germany")

r <- get_elev_raster(ger, 5) 
r <- rast(r) |> crop(ger) |> mask(ger) 

names(r) <- "elev"

df <- as.data.frame(r, xy = T)

ggplot(df) +
  geom_tile(aes(x, y, 
                fill = cut(elev, c(-50, 0, 25, 50, 100, 250, 500, 1000, 1500, 2000, 2330)))) +
  geom_sf(data = ger, fill = NA) +
  scale_fill_viridis_d() +
  guides(fill = guide_colorsteps()) +
  labs(fill = NULL) +
  theme_void() +
  theme(legend.position = "bottom",
        legend.key.height = unit(.3, "lines"),
        legend.key.width = unit(3, "lines"))

image

teunbrand commented 9 months ago

Thanks for the report! I can confirm this is a bug. More minimal reprex below:

library(ggplot2)

ggplot(mtcars, aes(mpg, drat, colour = cut(disp, c(90, 200, 300, 400, 500)))) +
  geom_point() +
  scale_colour_viridis_d(guide = guide_colorsteps())
#> Warning: Removed 4 rows containing missing values or values outside the scale range
#> (`geom_point()`).

Created on 2024-03-07 with reprex v2.1.0

dominicroye commented 9 months ago

It's really strange because I had tried it with a more minimal dataset, and as you can see here, it's correct.

library(ggplot2)

df <- expand.grid(X1 = 1:10, X2 = 1:10)
df$value <- df$X1 * df$X2

p <- ggplot(df, aes(X1, X2)) + geom_tile(aes(fill = cut(value, c(0, 10, 25, 75, 90, 100))))

p +   scale_fill_viridis_d(guide = guide_colorsteps())

Created on 2024-03-07 with reprex v2.1.0

teunbrand commented 9 months ago

It's because of alphanumeric sorting of the breaks, which shouldn't happen for breaks parsed from cut()'s intervals, but should happen for numeric breaks.