-
-
Notifications
You must be signed in to change notification settings - Fork 94
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
flexible point.padding #83
Comments
Thank you for opening this issue and sharing a figure that demonstrates the problem. If someone is willing to volunteer their time, I'd appreciate a pull request for this feature. Here is a minimal code example that can be used to reproduce the issue. When there's an update that addresses this issue, we can re-run this code to see if it works as expected: ProblemLarge points are overlapping their text labels, so it's not possible to read the labels. library(ggrepel)
d <- data.frame(
x = c(1, 2, 2, 3),
y = c(1, 2, 3, 1),
pointsize = factor(c(1, 2, 2, 1)),
label = sprintf("label%s", 1:4)
)
ggplot(d, aes(x, y)) +
geom_point(aes(size = pointsize)) +
scale_size_manual(values = c(1, 15)) +
geom_text_repel(aes(label = label), size = 5) SolutionWe should be able to give a vector of values for ggplot(d, aes(x, y)) +
geom_point(aes(size = pointsize)) +
scale_size_manual(values = c(1, 15)) +
geom_text_repel(
aes(label = label),
size = 5,
point.padding = unit(c(1, 2, 2, 1), "lines")
)
|
Could the padding arguments be allowed within the aes() argument or be set dynamically based on geom_point size? |
@railsfanatic I would be happy to review a pull request! I think this is a great feature to add, but it is not implemented right now. |
Issue #83 mentioned that it would be nice if ggrepel would respect different point sizes when positioning text labels next to the data points. This commit is a first attempt to get this feature working. Some of the code added might be redundant, but it works well enough for now.
I need help implementing this feature. I don't know how to convert the point size to the appropriate size that is scaled to the plotting area. Does anyone have any hints? Pull requests are welcome. Here is what I have tried, but none of these options for setting Lines 418 to 428 in f7925f0
|
@hadley Could I please ask if you might have any hints on how to fix this issue? If you clone the latest GitHub version of ggrepel, I think you should be able to see similar behavior to the animated gif below. I tried to set
Here's my incorrect code, and the gif that shows the problem caused by it: point_size <- convertWidth(to_unit(x$data$point.size), "native", valueOnly = TRUE) / 14 The panel on the left assumes all points have size 0. The panel on the right shows the problem that I've described above. |
Here is the code for the figure in my gif: library(ggrepel)
set.seed(42)
d <- data.frame(
x = c(1, 2, 2, 3),
y = c(1, 2, 3, 1),
pointsize = c(0, 2, 1, 0),
label = sprintf("label%s", 1:4)
)
# point.size = 0
p1 <- ggplot(d, aes(x, y)) +
geom_point(aes(size = factor(pointsize)), color = "grey50") +
scale_size_manual(values = c(1, 8, 15), guide = FALSE) +
geom_text_repel(
aes(label = label),
# point.size = d$pointsize,
size = 5
) +
labs(title = "point.size = 0")
size_range <- c(2, 50)
p2 <- ggplot(d, aes(x, y)) +
continuous_scale(
aesthetics = c("size", "point.size"), scale_name = "point.size",
palette = scales::area_pal(size_range), guide = FALSE
) +
# scale_size_continuous(range = size_range, guide = FALSE) +
geom_point(aes(size = pointsize), color = "grey50") +
geom_text_repel(
min.segment.length = 0.1,
box.padding = 0.2,
aes(label = label, point.size = pointsize),
size = 5, max.iter = 1e5, max.time = 1
)
gridExtra::grid.arrange(p1, p2, ncol = 2) |
@thomasp85 is more likely to know the answer than me |
Simple (and possibly silly) question to start with: why are you converting point size to "native" ? why not to something that measures the same in both height and width, like "inches" ? |
@pmur002 Honestly, I don't have a good understanding of how to use the There is a good chance that I have some very silly mistakes, and I'd be delighted if you can help me to see them or if you can help to fix them. |
I tried a few things. Attempt 1point_size <- convertWidth(to_unit(x$data$point.size), "native", valueOnly = TRUE) / 14 This works well only when the plot width equals the plot height. The good news is that the output is correct regardless of how large the plot is. The bad news is that the aspect ratio of the plot determines the size of each point. This means the point size is either too big or too small when the plot width does not equal the plot height. I don't know how Attempt 2point_size <- convertWidth(to_unit(x$data$point.size), "inches", valueOnly = TRUE) / 42 This works only for plots of very specific size, so 42 is hand-tuned to match that plot size. The output is wrong if the plot size is increased, decreased, or if the aspect ratio is changed. |
To my great surprise, this hacky code seems to be the best attempt yet! I wish it weren't full of magic, though. And it needs more magic to fine-tune the distance between the segment and the edge of each large point. p_width <- convertWidth(unit(1, "npc"), "inch", TRUE)
p_height <- convertHeight(unit(1, "npc"), "inch", TRUE)
p_ratio <- (p_width / p_height)
if (p_ratio > 1) {
p_ratio <- p_ratio ^ (1 / (1.5 * p_ratio))
}
point_size <- p_ratio * convertWidth(
to_unit(x$data$point.size), "native", valueOnly = TRUE
) / 13 |
My understanding is that the grobs that you create within your geom's |
Paul, thanks for the comment! If I understand you correctly, you are suggesting:
Is that right? |
Pretty much. Though my comments are all theoretical - I have not written any code to back them up. Also, I believe it is only necessary to convert to "native" (via |
I have three groups of points with different radiuses. With fixed set of
![image](https://user-images.githubusercontent.com/12883455/29345876-3e755df0-8274-11e7-8b5c-d21f8d516dab.png)
point.padding
, the problem will look like below. The big circle will cover part of the label. But if increasepoint.padding
, the small circle's label will be too far away. Is there any work around for this? Thanks.The text was updated successfully, but these errors were encountered: