AllanCameron / geomtextpath

Create curved text paths in ggplot2
https://allancameron.github.io/geomtextpath
Other
627 stars 25 forks source link

Feature Request: Set angle for geom_labelvline #102

Open adamkemberling opened 1 year ago

adamkemberling commented 1 year ago

geom_labelvline and geom_labelhline are very useful tools for setting baselines/thresholds and annotating them. In the case of the vertical line options it seems like it would be appealing to be able to rotate text 90 degrees to appear in horizontal plane.

Currently the angle option for geom_labelvline does not change angle. Would be great to add this control to the function.

Thanks!

teunbrand commented 1 year ago

Could you give a salient example of where rotated text in geom_labelvline() would be handy? In my mind, it seems easy to replace that concept with geom_label() + geom_vline(), no?

adamkemberling commented 1 year ago

Yea certainly.

Here is a simplified example. Basically I'm leveraging geom_labelvline as a way to position the label at a set vertical position in relative coordinates using the hjust that is consistent across panels. This is useful for situations when only x or y coordinates can be known a-priori (like when facets are set as scales = "free"). Would love to be able to just turn the text 90 degrees so it can be read easier.


# Get some summary stat that you might not know a-priori
mysum <- mtcars %>% group_by(cyl) %>% summarise(mpg = mean(mpg), .groups = "drop")

# Plot the distributions across facets, with labelled midpoints 
#using labelvline makes sure label is at same relative height
# across facets without knowing y-coordinates
ggplot() +
  geom_density(data = mtcars, aes(x = mpg)) +
  geom_labelvline(
    data = mysum, 
    aes(xintercept = mpg, label = paste("Mean:", round(mpg))),
        hjust = 0.2) +
  facet_wrap(~cyl)

image

teunbrand commented 1 year ago

Ah right, so it is the relative positioning along the y-axis that adds some value? I can sympathise with that. The next version of ggplot2 might also make it easier to set relative positions by setting y = I(0.2) for example, so if that gets implemented, that might be an easier solution than properly working in an angle into all {geomtextpath}'s geoms.

adamkemberling commented 1 year ago

Yea, in my actual use-case there is value in the label and the line itself, but the relative positioning is what I can't seem to replicate otherwise. I suppose I could flip the coordinates and achieve a similar figure, but thought I would ask anyways. I appreciate your time and energy, cheers!

teunbrand commented 11 months ago

So in the current development version of ggplot2 you can do the following:

library(ggplot2)
packageVersion("ggplot2")
#> [1] '3.4.4.9000'
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

# Get some summary stat that you might not know a-priori
mysum <- mtcars %>% group_by(cyl) %>% summarise(mpg = mean(mpg), .groups = "drop")

ggplot() +
  geom_density(data = mtcars, aes(x = mpg)) +
  geom_vline(data = mysum, aes(xintercept = mpg)) +
  geom_label(aes(x = mpg, y = I(0.2), label = paste("Mean:", round(mpg))),
             data = mysum) +
  facet_wrap(~cyl)

Created on 2023-12-14 with reprex v2.0.2

I suppose this gets you want you want, no?

adamkemberling commented 11 months ago

Yes, that's exactly what I had been leveraging the function for. This solution is much less round-about than what I had implemented with geom_text() and using Inf and vjust to buffer away from the plot limits. I will just add (in case you were considering implementing the rotation eventually), that having the label text appear in a gap in the line as it does with geom_textvline is a really nice touch and might still be the route I go. But yes, this largely solves the feature I was requesting. Thank you again for your work on the package, for being responsive, and have a happy holiday.