Skip to content
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

Support for hjust and vjust #3

Closed
srvanderplas opened this issue Jan 6, 2016 · 6 comments
Closed

Support for hjust and vjust #3

srvanderplas opened this issue Jan 6, 2016 · 6 comments

Comments

@srvanderplas
Copy link

Currently, using hjust and vjust ggplot2 parameters will cause the labels not to line up with the segments connecting them to points. It's arguable that using ggrepel should remove the need for these parameters, but in some use cases (labeling lines, for instance, and trying to reduce overlap with the line) it may be desirable to use one or both of these parameters in addition to ggrepel.

Alternately, expand the documentation for ggrepel so that it is clear that these parameters aren't supported.

@slowkow
Copy link
Owner

slowkow commented Jan 6, 2016

Thanks for the suggestion! I have been thinking about removing the hjust and vjust parameters, because I haven't yet seen an example where they could be useful with ggrepel. However, this package is a work in progress, so I left the parameters in for now while I continue thinking about this.

May I ask you to share a minimal example where you think these parameters might be useful? For example:

library(ggplot2)
library(ggrepel)
ggplot(...) + geom_line(...) + geom_text_repel(...)

If we can't find any compelling examples to support the use of these parameters, then I'll go ahead and remove them. I agree that the documentation needs to be improved, and that's on my todo list.

By the way, pull requests are very welcome! I'd be happy to review and merge changes if you wish to fork this repo.

@srvanderplas
Copy link
Author

library(ggplot2)
library(ggrepel)
library(dplyr)
groups <- c("AAAAAAA", "BBBBB", "CCCCCCC", "DDDDDDD", "EEEE")
data <- data_frame(x = rep(1:5, times = 5), y = rnorm(25, 0, 1), 
                   group = rep(groups, each = 5))

ggplot(data = data, aes(x = x, y = y, color = group)) + 
  geom_line() + 
  geom_point() + 
  geom_label_repel(data = subset(data, x == 5), 
                   aes(label = group), expand = T)

image

So if I used hjust/vjust, I might be able to indicate my preference for the labels to not overlap the line, subject to the constraints of the force-directed layout.

ggplot(data = data, aes(x = x, y = y, color = group)) + 
  geom_line() + 
  geom_point() + 
  geom_label_repel(data = subset(data, x == 5), 
                   aes(label = group), expand = T,
                   hjust = 1, vjust = 0)

image

What actually happens in this case is that

  1. The line segments from the label to the point don't align with the labels any longer, and
  2. The labels don't conform to what one would expect from the hjust/vjust parameters. Both hjust and vjust seem to have some effect, but less than what would be expected - the labels seem to be centered horizontally and aligned somewhere between (-0.5, .5) in vjust terms (that is, between vertically centered and above the point where the bottom of the label is aligned with the point).

I'm guessing that (1) is due to lack of support for hjust/vjust in the segment computation, and (2) is due to some compromise between the force-directed layout and hjust/vjust.

I can think of a couple of ways to resolve this:

  1. Drop support for hjust/vjust, or provide a warning - this is the easiest way to go.
  2. Redefine hjust/vjust so that they are parameters that influence the force direction algorithm, weighting it so that points corresponding to (h, v) on the unit square are preferred, possibly by adding small auxiliary weights to (1-h, 1-v).

I still haven't had a chance to do much digging into the code, and probably won't until Friday at the earliest, but I hope this at least makes it clearer.

@slowkow
Copy link
Owner

slowkow commented Jan 7, 2016

Thank you for the detailed examples and suggestions!

I decided to drop support for vjust, hjust, nudge_x, nudge_y, position, and check_overlap in release 0.2.0.

If you're interested to continue working on this, I'd be happy to review a pull request. I think you're right about the possibility for hjust/vjust to influence the algorithm. It'd be cool to see what you come up with.

You might consider an alternative approach to labeling lines directly by using the directlabels package for this particular use case.

Alternatively, you might also consider increasing the label.padding (or box.padding in 0.2.0) parameter to something like unit(1, "lines") and then increasing the xlim with coord_cartesian(xlim = c(0.8, 5.5)). I wonder if that will suffice.

@slowkow
Copy link
Owner

slowkow commented Jan 10, 2016

@srvanderplas, could I ask if you have any thoughts about the new (not yet implemented) feature proposed in issue #11? I'm wondering what you think about this idea. Do you think this feature is preferable to something more like hjust?

I think the new feature might address the issue you raised.

We can start with the plot you mentioned above:

p <- ggplot(data = data, aes(x = x, y = y, color = group)) + 
  geom_line() + 
  geom_point()

First, we could use coord_cartesian() to extend the plotting area to the right, giving us more room to place labels there:

p +
  coord_cartesian(xlim = c(1, 5.5)) +
  geom_label_repel(data = subset(data, x == 5), aes(label = group))

Next, we could pass a directions parameter to specify that we don't want any labels to move to the left at all:

directions <- data.frame(
  up = rep(1, 5), right = rep(1, 5), down = rep(1, 5), left = rep(0, 5))
#   up right down left
# 1  1     1    1    0
# 2  1     1    1    0
# 3  1     1    1    0
# 4  1     1    1    0
# 5  1     1    1    0

p +
  coord_cartesian(xlim = c(1, 5.5))
  geom_label_repel(
    data = subset(data, x == 5),
    aes(label = group),
    directions = directions
  )

What do you think?

@slowkow
Copy link
Owner

slowkow commented Jan 15, 2016

Hi Susan, could I ask you to try the new nudge_x and nudge_y parameters? Here's an example:

devtools::install_github("slowkow/ggrepel@0.4.2")

library(ggrepel)

set.seed(42)
groups <- c("AAAAAAA", "BBBBB", "CCCCCCC", "DDDDDDD", "EEEE")
data <- data.frame(x = rep(1:5, times = 5), y = rnorm(25, 0, 1), 
                   group = rep(groups, each = 5))

ggplot(data = data, aes(x = x, y = y, color = group)) + 
  geom_line() + 
  geom_point() + 
  coord_cartesian(xlim = c(min(data$x), max(data$x) + 0.5)) +
  geom_label_repel(
    data = subset(data, x == 5), 
    aes(label = group),
    segment.color = NA,
    size = 5,
    nudge_x = 0.25
  )

image

@slowkow
Copy link
Owner

slowkow commented Jan 24, 2016

Feel free to reopen this issue if you want to continue this discussion!

@slowkow slowkow closed this as completed Jan 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants