-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
guide
vs. show.legend
with new_scale()
#59
Comments
The issues are fixed in the development version of ggnewscale ( I probably won't be sending it to CRAN soon because I think I rather publish a rewrite of the internals that fixes other bugs and makes the code much more easy to follow. But it requires a change in ggplot2 which is not available yet. # Make up some values
library(ggplot2)
library(ggnewscale)
nn <- 6
n <- 3 * 5 * nn
m <- data.frame(
id1 = factor(rep(8:10, each = n / 3)), # No overlap to distinguish them more easily
id2 = factor(rep(1:5, each = n / 5)),
x = runif(n, 1, 80)
)
m[["y"]] <- 10 + m[["x"]] * runif(n, 1, 2)
ggplot(m, aes(x, y)) +
geom_line(aes(color = id2), show.legend = FALSE) +
geom_point(aes(color = id1), show.legend = TRUE) +
scale_color_viridis_d() Here, the line doesn’t contribute to the legend so the legend is only drawn with points instead of points and lines. The title of the legend inherits from the first layer. The legend is not drawn “for id2” nor id1, it’s drawn for the colour aesthetic, which combines all the unique values of id1 and id2. The following examples work in the development version of ggnewscale Default: shows both legends with lines ggplot(m, aes(x, y)) +
geom_line(aes(color = id1)) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2)) +
scale_color_viridis_d(name = "id2") Remove legend for first layer: shows only legend for second layer ggplot(m, aes(x, y)) +
geom_line(aes(color = id1), show.legend = FALSE) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2)) +
scale_color_viridis_d(name = "id2") Remove legend for second layer: shows only legend for first layer ggplot(m, aes(x, y)) +
geom_line(aes(color = id1)) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2), show.legend = FALSE) +
scale_color_viridis_d(name = "id2") Remove legends for both layers: shows no legend. ggplot(m, aes(x, y)) +
geom_line(aes(color = id1), show.legend = FALSE) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2), show.legend = FALSE) +
scale_color_viridis_d(name = "id2") Adds a smooth layer: shows legend only for that layer, with correct width. ggplot(m, aes(x, y)) +
geom_line(aes(color = id1), show.legend = FALSE) +
geom_smooth(aes(color = id1)) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2), show.legend = FALSE) +
scale_color_viridis_d(name = "id2")
#> `geom_smooth()` using method = 'loess' and formula = 'y ~ x' Created on 2023-11-28 with reprex v2.0.2 |
This is great, thanks so much for the fix and response! I installed the dev-version and the examples work nicely. In your example "Remove legend for first layer: shows only legend for second layer", if I drop in an (unnecessary but possible) library(ggplot2)
library(ggnewscale)
nn <- 6
n <- 3 * 5 * nn
m <- data.frame(
id1 = factor(rep(8:10, each = n / 3)),
id2 = factor(rep(1:5, each = n / 5)),
x = runif(n, 1, 80)
)
m[["y"]] <- 10 + m[["x"]] * runif(n, 1, 2)
# Remove legend for first layer: shows only legend for second layer
# this works
ggplot(m, aes(x, y)) +
geom_line(aes(color = id1), show.legend = FALSE) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2)) +
scale_color_viridis_d(name = "id2") # Remove legend for first layer: shows only legend for second layer
# this doesn't work
ggplot(m, aes(x, y)) +
geom_line(aes(color = id1), show.legend = FALSE) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2), show.legend = TRUE) +
scale_color_viridis_d(name = "id2") Created on 2023-11-28 with reprex v2.0.2 |
Thank you for the last example. I'll take it into account for the future refactoring. I suspect is something that could be fixed by the new logic. |
Looking into this, ggplot(m, aes(x, y)) +
geom_line(aes(color = id1)) +
scale_color_viridis_d(name = "id1") +
new_scale_color() +
geom_line(aes(color = id2), show.legend = TRUE) +
scale_color_viridis_d(name = "id2") The So in fact it seems that this is all working as written. The issue is that the default guide takes "any" aes, so this part doesn't do anything. ggnewscale/R/bump-aes-scales.R Lines 30 to 32 in 51ad375
I could replace and make it take only the |
Maybe I am misunderstanding the expected behavior of the argument
show.legend
in"ggplot2"
It appears that
show.legend
behaves surprisingly with multiple geoms/layers in"ggplot2"
(see first example below);similarly, it does not work with
ggnewscale::new_scale()
(see further examples below).Questions/problems related to
show.legend
have been documented by others: #31 and #32.Instead of using
show.legend
, #31 (comment) provides a solution (or hack) viaguide = "none"
(see last examples below).Could be helpful for users of the package to document the behavior of
show.legend
in combination withggnewscale::new_scale()
and provide examples usingguide = "none"
?Thanks!
Created on 2023-11-28 with reprex v2.0.2
The text was updated successfully, but these errors were encountered: