-
Notifications
You must be signed in to change notification settings - Fork 2k
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
geom_sf mismatches when unknown aesthetic used with non-aesthetic specified colour/fill #5172
Comments
This is highly non-idiomatic code. If you want to give points different colors you need to set up an aesthetic mapping. |
@clauswilke I know. Did you not read the whole of the issue? "This can all be worked round by using ggplot() + geom_sf(data=rgn4 , aes(foo=F1, col=mapcolour), cex=10) and adding a scale_ function to map the colours as desired. I've shown the student who first showed me this bug how to do that instead." Even non-idiomatic code should not fail this way though. |
Using the API correctly is not a workaround. It's using the API as intended. We've had complaints for years that providing vectors of colors as parameters fails in unexpected ways under various circumstances, and the answer has always been that we're not guaranteeing this to work. Now on occasion we have made changes to the code that would fix such cases, but I'm not even sure that's helpful because it reinforces that this should work when really from a technical perspective it cannot be guaranteed. It's up to the geom/stat to not reshuffle the data, and the geom/stat may have good reasons to do so.
Note that I'm not closing the issue. If somebody wants to hunt this down and can find a way to fix it without breaking anything else great. But it'd be very low on my priority list. |
I shouldn't even say "gets confused". The algorithm does what it is supposed to do when proper aesthetic mappings are set up. But the internal ordering it creates may depend on additional aesthetics that are provided. For example because groupings are calculated on the basis of all aesthetics provided, even ones that aren't used by any geom. |
Simple example of how a meaningless aesthetic can mess up drawing. Just because the aesthetic is meaningless doesn't mean it isn't considered when generating the plot. The core ggplot2 engine can't know whether library(tidyverse)
df <- tibble(
x = rep(1:10, 3),
y = rep(cos(1:10), 3) + rep(1:3, each = 10),
a = rep(c('a', 'b', 'c'), each = 10),
b = rep(letters[1:6], 5)
)
ggplot(df, aes(x, y, color = a)) +
geom_line() ggplot(df, aes(x, y, color = a, foo = b)) +
geom_line() Created on 2023-02-01 with reprex v2.0.2 |
Yes I see there's lots of potential confusion because the top half of ggplot can't know what the bottom half is doing. I think another example of this is your:
which produces no warnings, since I guess
at least produces a warning:
(Side note: Its an unusual meaning of "Ignoring" in that warning, when it makes such a substantial breaking change to the graphic. I wonder if the I did try and simplify the example down as much as possible, the original problem was with complex mapped polygons and I thought it might have been related to the behaviour you've shown with lines, when unfolding polygons to a sort of fortified version (I'm not sure fortification happens with geom_sf but...), but the problem could be manifest with points which amazed me, since point features have one row per feature, no fortification needed. But yes some unpacking of I am reminded of the great clown Tommy Cooper, who waved his arm at his doctor and said "it hurts when I do that" and the doctor replied "well don't do that then". |
If its possible to fix this in documentation or code warnings that might be useful. The docs for
which doesn't explicitly say passing a vector can lead to a world of pain. The help for |
To your earlier question: If you put the aesthetic into the ggplot call, then it applies to all geoms in the plot. Geoms that don't know what to do with it just ignore it. By contrast, if you put it into a specific geom, then it applies only to that geom, and then the geom can let you know if it doesn't recognize the aesthetic. |
Yes, and given that "Explicit is better than implicit" is a Good Thing, I prefer to not put things in the |
The issue of
To my mind, you put things in the main |
This is now fixed in the dev version of ggplot2. library(sf)
#> Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
devtools::load_all("~/packages/ggplot2/")
#> ℹ Loading ggplot2
rgn4 <- st_as_sf(data.frame(expand.grid(x=1:3, y=1:4)), coords=1:2)
rgn4$F1 = 1:nrow(rgn4)
rgn4$F2 = paste0("A",rgn4$F1)
rgn4$mapcolour = "palegreen"
rgn4$mapcolour[11]="red"
rgn4$mapcolour[12]="yellow"
ggplot() + geom_sf(data=rgn4 , aes(foo=F1), col=rgn4$mapcolour, cex=10)
#> Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat =
#> stat, : Ignoring unknown aesthetics: foo ggplot() + geom_sf(data=rgn4 , aes(foo=F2), col=rgn4$mapcolour, cex=10)
#> Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat =
#> stat, : Ignoring unknown aesthetics: foo ggplot() + geom_sf(data=rgn4 , aes(foo=F1), col=1:nrow(rgn4), cex=10)
#> Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat =
#> stat, : Ignoring unknown aesthetics: foo ggplot() + geom_sf(data=rgn4 , aes(foo=F2), col=1:nrow(rgn4), cex=10)
#> Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat =
#> stat, : Ignoring unknown aesthetics: foo Created on 2023-03-27 with reprex v2.0.2 |
When controlling the colour (or fill) by a vector of colours and also specifying an unknown aesthetic in
aes
, the colours get displayed on the wrong features.Example: Make some fake data. This is a 3x4 grid of points with F1, a numeric column, F2, a character column, and mapcolour, a column of colour names.
The goal is to plot the points coloured according to the names in the
mapcolour
column, but to also specify an aestheticaes(foo=...)
which will be F1 or F2.With F1 (numeric), this works, giving a pale green grid of points but with the top middle (11th) being red and top right (12th) being yellow. There is a warning about the unknown aesthetic:
But if I try with F2 (character column), the colours are in the wrong place:
Specifying colours numerically from 1 to 12 shows the top row looking like a repeat of the previous row in the failure case, which looks to be different to the behaviour above:
Further experiments with "ignored" aesthetics that are character with different numbers of discrete values show different mismatches of expected colour locations. Try:
to see different mismatch patterns.
This can all be worked round by using
ggplot() + geom_sf(data=rgn4 , aes(foo=F1, col=mapcolour), cex=10)
and adding ascale_
function to map the colours as desired. I've shown the student who first showed me this bug how to do that instead. But I thought I'd submit an issue report because it seems something is not quite right. This also manifests with sf polygons.The unknown aesthetic is there because the
plotly
package can utilise atext
aesthetic for popup texts on web plots.I've spent some time narrowing this down and it only seems to manifest with
geom_sf
, when there's at least one unknown aesthetic, and when one aspect of the features is controlled by a parameter outside theaes
by a vector, as in the example. The problem does not show when usinggeom_point
on a converted version of thesf
data, these two looking fine:Session info follows:
The text was updated successfully, but these errors were encountered: