-
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
scale_x_binned() doesn't work with geom_tile() #5294
Comments
Thanks for the report. Lines 16 to 21 in f7246d4
|
Sure, but that doesn't quite cover it. The size of the tiles isn't being determined after transformation... it's being determined wrongly, and then the tiles aren't being displayed. I think this is a real bug. ggp <- ggplot(data.frame(x = 2:4 + 0.5, y = 2:4), aes(x, y)) + geom_tile(width = .8, height = .25)
ggp # These should bin to 2, 3 and 4...
# but in fact...
ggp + scale_x_binned(breaks = 2:4) |
I'm sorry I don't quite understand. How are they displayed wrongly? I've rendered an example below. library(ggplot2)
tiled <- ggplot(data.frame(x = 2:4 + 0.5, y = 2:4), aes(x, y)) +
geom_tile(width = .8, height = .25)
tiled tiled + scale_x_binned(breaks = 2:4) To me, it seems that rects <- ggplot(data.frame(xmin = 2:4 + 0.1, xmax = 2:4 + 0.9,
ymin = 2:4 - 0.125, ymax = 2:4 + 0.125)) +
geom_rect(aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax))
rects rects + scale_x_binned(breaks = 2:4) Created on 2023-05-04 with reprex v2.0.2 |
So my thought was: "2.5 - 0.4 = 2.1, should bin to 2; 2.5 + 0.4 = 2.9, should bin to 3". Actually I think the bins ought to be 2.5, 3.5 etc. i.e. midpoints of the breaks. But neither of those things are happening. Indeed, Here's a more extreme example: ggp <- ggplot(data = NULL, aes(x, y)) +
geom_tile(data = data.frame(x = c(0, 5, 10), y = 1:3), width = 2, height = .25) +
geom_point(data = data.frame(x = c(-1, 1, 4, 6, 9, 11), y = rep(1:3, each = 2)), color = "red")
ggp ggp + scale_x_binned(breaks = c(0, 5, 10)) My expectation would be that the rectangle limits would be (-1, +1); (4,6) and (9, 11). The first and last ones have edges which are out of the limits of the binned scale, so maybe they are dropped, or maybe like the points they are just left alone. The second one would bin to (2.5, 7.5). In fact: the first rectangle disappears. The second one goes to (-0.5, 7.5). The third one goes to (2.5, 10.5). I don't think anyone would expect that - why would a rectangle (4,6) be mapped to (-0.5, 7.5) by binning to two bins from 0 to 5 and 5 to 10? The real reason is that the first call to I don't think anyone who hasn't read the source code will understand this, or be able to use it for any practical purpose. So yeah, the disclaimer in the documentation is better than nothing, but I think it would be simpler to just put "geom_tile doesn't work with binned scales". Similar concerns apply with a logged scale: ggp <- ggplot(data = NULL, aes(x, y)) + ylim(0,2)+
geom_tile(data = data.frame(x = 10, y = 1), width = 2, height = .25) +
geom_point(data = data.frame(x = c(9, 11), y = 1), color = "green")
ggp ggp + scale_x_log10() This makes it look as if 9 is 1 and 11 is 100. Again, you can say that it is working according to the documentation, but the point is, how is it meant to represent data? My expectation as a user would be that I can use geom_tile to represent some data. Then if I choose to put that data on a log scale, or bin it or whatever, |
Does this also mean that geom_tile does not work with discrete scales (scale_x_discrete)? I'm struggling to get my plotted data into the correct categories on the X axis. |
I think that binning works slightly different than you're expecting here. It is more of a The underlying reason that @jfmusso It works for discrete scales because you can combine continuous values on a discrete scale (but not the other way around). Discrete position scales are esstentially |
Perhaps is one issue that there are different potential users for Perhaps it might be helpful to separate the two functionalities, and provide a public-facing version of geom_tile that indeed works in data coordinates. |
The following code works, producing output with
xmin
andxmax
aligned to bins:But this code, which ought to do the same thing, produces an empty plot:
The underlying reason is in the second call to
layout$map_position()
inggplot_build()
.x
variables back from a factor to (the binned version of) their original values. ForGeomRect
which hasxmax
andxmin
from the start, this works.GeomTile
calculatesxmin
andxmax
fromx
andwidth
. By the time it gets tolayer$compute_geom_1
,x
has been transformed to a "factor"-style numeric of bins. The geom doesn't realise this and happily adds the original width to the bin.layout$map_position()
takes this wonky data and turns it back, typically toNA
.xmin
andxmax
are removed.In other words,
GeomTile$setup_data()
is being called after the firstmap_position()
, but in this case at least, it needs to be called before it.This bug exists in ggplot2 3.4.2, and also on github main as of today.
The text was updated successfully, but these errors were encountered: