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

feature request: direction="right" ? #133

Closed
matsutakehoyo opened this issue Apr 27, 2019 · 5 comments
Closed

feature request: direction="right" ? #133

matsutakehoyo opened this issue Apr 27, 2019 · 5 comments

Comments

@matsutakehoyo
Copy link

Would it be possible to add more options to direction to limit the direction (I mean to a positive or negative value in x or y direction)? Maybe something like diraction="+x" or direction="right" to repel to the right.

I was trying to repel text label on a labels in error bars, and I would like the lower bound to be shifted to the left and the upper bound to be shifted to the right. The xlim option didn't work for me because the I am using facet, and xlim can only specify a common value for all the facets.

@slowkow
Copy link
Owner

slowkow commented Apr 27, 2019

Thanks for the request. You might consider trying nudge_x instead of direction.

If you can provide code and the image generated by the code, then we might be able to provide more detailed help.

@matsutakehoyo
Copy link
Author

matsutakehoyo commented Apr 27, 2019

@slowkow I have a bunch of distributions and I am plotting their ranges and mean like this.

library(tidyverse)
library(ggrepel)

d1 <- tibble(dist = "d1", value = rnorm(1000, -7,1)) 
d2 <- tibble(dist = "d2", value = rnorm(1000, 7,1)) 
d <- bind_rows(d1, d2)

d_sum <- d %>% 
	group_by(dist) %>%
	summarise(lower=quantile(value, c(0.1, 0.9))[1],
	          upper=quantile(value, c(0.1, 0.9))[2], 
	          mean=mean(value))

ggplot(d_sum) +
	geom_density(aes(x=value, fill=dist),d) +
	geom_errorbarh(aes(xmin=lower, xmax=upper, y=0.5), height=0.01) +
	geom_point(aes(x=mean, y=0.5)) +
	geom_text(aes(x=mean, y=0.45, label=round(mean,2)), fontface="bold") +
	geom_text(aes(x=lower, y=0.45, label=round(lower,1)))+
	geom_text(aes(x=upper, y=0.45, label=round(upper,1))) 

image

I want to leave the mean where it is and have the lower limit to be repelled to the left and the upper one to the right in the x directions, kind of like this. Using hjust is not ideal because the text will always be offset, even when it doesn't have to, and sometimes it's not enough.

ggplot(d_sum) +
	geom_density(aes(x=value, fill=dist),d) +
	geom_errorbarh(aes(xmin=lower, xmax=upper, y=0.5), height=0.01) +
	geom_point(aes(x=mean, y=0.5)) +
	geom_text(aes(x=mean, y=0.45, label=round(mean,2)), fontface="bold") +
	geom_text(aes(x=lower, y=0.45, label=round(lower,1)), hjust=1)+
	geom_text(aes(x=upper, y=0.45, label=round(upper,1)), hjust=0) 

image

Depending on how close the text is, ggrepel sometimes gets it sometimes it doesn't.

ggplot(d_sum) +
	geom_density(aes(x=value, fill=dist),d) +
	geom_errorbarh(aes(xmin=lower, xmax=upper, y=0.5), height=0.01) +
	geom_point(aes(x=mean, y=0.5)) +
	geom_text(aes(x=mean, y=0.45, label=round(mean,2)), fontface="bold") +
	ggrepel::geom_text_repel(aes(x=lower, y=0.45, label=round(lower,1)), direction="x")+
	ggrepel::geom_text_repel(aes(x=upper, y=0.45, label=round(upper,1)), direction="x") 

image

Following your suggestion I tried this which seems to work!

ggplot(d_sum) +
	geom_density(aes(x=value, fill=dist),d) +
	geom_errorbarh(aes(xmin=lower, xmax=upper, y=0.5), height=0.01) +
	geom_point(aes(x=mean, y=0.5)) +
	geom_text(aes(x=mean, y=0.45, label=round(mean,2)), fontface="bold") +
	ggrepel::geom_text_repel(aes(x=lower, y=0.45, label=round(lower,1)), 
	                         direction="x", nudge_x=-0.01 )+
	ggrepel::geom_text_repel(aes(x=upper, y=0.45, label=round(upper,1)), 
	                         direction="x", nudge_x=0.01) 

image

In my actual data, the scale is not always easy to estimate. But it looks like even very small values of nudge_x do the trick. Does it repel to the direction I nudge it no matter the amount I nudge it?

@slowkow
Copy link
Owner

slowkow commented Apr 28, 2019

@matsutakehoyo I would like to encourage you to try using reprex for sharing code snippets on the web. This ensures that your code is reproducible, so others will be able to run it. This package also automates the work of including figures in your comments on GitHub or StackOverflow.

Does it repel to the direction I nudge it no matter the amount I nudge it?

nudge_x and nudge_y adjust the initial positions of the text labels before the physical repulsion simulation starts running.

You might consider another option that does not use ggrepel at all:

d_sum$label <- sprintf(
  "%s  %s  %s",
  signif(d_sum$lower, 2),
  signif(d_sum$mean, 2),
  signif(d_sum$upper, 2)
)
d_sum

ggplot(d_sum) +
  geom_density(aes(x = value, fill = dist),d) +
  geom_errorbarh(aes(xmin = lower, xmax = upper, y = 0.5), height = 0.01) +
  geom_point(aes(x = mean, y = 0.5)) +
  geom_text(aes(x = mean, y = 0.45, label = label)) +
  geom_text(aes(x = mean, y = 0.45, label = signif(mean, 2)), fontface = "bold")

image

@matsutakehoyo
Copy link
Author

@slowkow thanks for your commend, and sorry for the delay, I was away for a while <(_ _)>
I will try to use reprex from now on.

I might be missing something, but it seems like you are using spaces to align the text, but this wouldn't work when the plot is saved with different dimensions or scale ( for example ggsave with scale=1 and scale=2). For now I will keep my solution of using just=0 and 1, but thanks for the suggestion, I had not thought of this approach.

@slowkow slowkow closed this as completed Jan 6, 2021
@slowkow
Copy link
Owner

slowkow commented Jan 6, 2021

I think this is related to #148

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants