Closed joojala closed 6 years ago
Fair enough.
suppose we have a point cloud that is distributed in ring shape with a hole in the middle. We could do it like this:
library(ggplot2)
len <- 4000
df <-data.frame(x=runif(len, -2.5,2.5) ,y=runif(len, -2.5,2.5) )
df <- df[ sin(sqrt(df[,1]^2+df[,2]^2))>runif(len,min= 0.6, max= 1),]
ggplot(df, aes( x=x,y=y))+geom_point()+ xlim(-3, 3) + ylim(-3, 3) + coord_fixed()
This would get you something like this (being exactly same is hardly important). Note, that the data set clearly has a hole in the middle where there is no density.
Now if we now make a stat density plot out of this data
ggplot()+
stat_density2d(
data=df, aes( x=x,y=y,fill=..level..), alpha=0.2, geom="polygon"
) + xlim(-3, 3) + ylim(-3, 3) + coord_fixed()
we get:
Notice no hole in the data. In fact there is no holed region in the polygons produced. However, the polygons are laid out in the file as if they are meant to have holes. They are very easy to identify as such: If i now fix this as seems reasonable, same color slices being same compound path, i get:
Which indeed looks like what i expect it to look like. So my question is still:
Now, I have made a fix for myself but might be worth patching in the real code as well.
Too much of my time is sunk on this issue, no more time to share this will have to be enough for you.
See the broader problem in #2534 — the contouring algorithm we used was not designed to draw polygons.
Its not the same problem. So what your saying is that yiu arent interested in a fix?
Why do you think it’s not the same problem?
Because it isn't, holes in polygons are a separate problem from bounding the polygons. The bounding problem is just the fact that you leave the shape open. Holes problem is that you do not tell the rendering engine that the separate closed shapes are in fact one shape.
Both of these are very easy to fix the open shape just need to get edge vectors added, since you know on which side the value is higher you will know which way to turn. Determining side can be easily done by sampling value near the line on either side. So the algorithm for finding the edges is O(N) complexity, where N is number of shapes.
Now the inner object algorithms do not need outer edges. Just arrangement into compound paths, ie grouping together so that the renderer does knows that all lines are the same. Depending on how you want to implement then the resulting algorithm is on average O(log(N)) since the data was already in order. Where N is number of closed shapes.
Admittedly the holes problem needs the corners sewed to work for corner bits. But the fix is entirely separate. But if you do both fixes then you dont have to bother with whether the other outer shapes should be part of the shape (since the holes will take care of this.).
Sounds like two instances of the same deeper problem to me. If you have a fix, I’d be happy to review a PR.
Well every vector engine does need to tackle this problem so this one is the fundamental, you can look it up in any book on 3d or 2d graphics.
The other one is just your algorithm being a bit weak treating data outside the window as continuation, it could treat them as a padded 0 and you wouldn't end up here. Fixing the borders wont fix this one.
This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/
Is stat_density2d behaving like it should? It seems to me that it is not making holes into existing polygons when the same value region is inside another. The thing is that these areas show up as denser colors when you have alpha enabled. Yet the value of each of the shapes is the same and with fully opaque they do fill completely.
Image 1: Image with holes is probably how it should work, image on the right (without holes) is how it works.
Is this intentional or is this a limitation of the engine? Because seems to me that the engine itself can make compound paths and thus should be easy to use even odd rule to make them holes. If not one could just connect the shapes with a sliver, although i would avoid that.
The way i have fixed these images is just make every color region a compound path and then set the rule to even odd. But seems quite misleading and should be easily addressable.