Skip to content

Optional segment end #5154

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

Merged
merged 4 commits into from
May 8, 2023
Merged

Conversation

teunbrand
Copy link
Collaborator

This PR aims to fix #5140, fix #3627 and fix #3617.

Briefly, it makes one of xend/yend optional in geom_segment(). The missing aesthetic gets filled by x and y respectively.

Visual demo:

devtools::load_all("~/packages/ggplot2/")
#> ℹ Loading ggplot2

df <- data.frame(x = c("a", "b", "c"), y = c(2.3, 1.9, 3.2))

ggplot(df) + geom_segment(aes(x, y, yend = 0))

ggplot(df) + geom_segment(aes(x, y, xend = 0))

set.seed(42)
df <- data.frame(
  x = rep(letters[1:3], each = 2),
  y = rpois(6, 10),
  group = rep(LETTERS[1:2], 3)
)

p <- ggplot(df, aes(x, y, colour = group))

# Want the ends stay stable? Define them.
p + geom_segment(
  aes(xend = x, yend = 0),
  position = position_dodge(width = 0.9)
)

# Want the ends to be dodged too? Omit one
p + geom_segment(aes(yend = 0), position = position_dodge(width = 0.8))

Created on 2023-01-21 with reprex v2.0.2

@thomasp85
Copy link
Member

Am I right in understanding that this does not fully fix the dodging issue - it only help for fully vertical or fully horizontal segments?

@teunbrand
Copy link
Collaborator Author

Indeed, it only helps with horizontal or vertical segments. I'm not sure what dodging with other angles should do, but that isn't addressed by this PR.

@thomasp85
Copy link
Member

intuitively dodging a segment would use the width/height of it's bounding box

Copy link
Member

@thomasp85 thomasp85 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - as discussed we will tackle dodging fully in another PR (or multiple)

Merge branch 'main' into segment_optional_end

# Conflicts:
#	man/geom_segment.Rd
@teunbrand
Copy link
Collaborator Author

Thanks for the review Thomas! I'm merging this despite a failing test on devel (explained here: #5296 (comment))

@teunbrand teunbrand merged commit d4db080 into tidyverse:main May 8, 2023
@teunbrand teunbrand deleted the segment_optional_end branch May 8, 2023 18:03
@smouksassi
Copy link

Hi I had a question regarding the automatic flipping running in current ggplot2 we get the below
do we still need to manually specify yend = 0 or xend = 0 for the new approach to work ?
or will the code automatically flip / know what we mean by x/y ends ?
(sorry unable to try the dev version at the moment)

library(patchwork)
library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.2.3
set.seed(42)
df <- data.frame(
  x = rep(letters[1:3], each = 2),
  y = rpois(6, 10),
  group = rep(LETTERS[1:2], 3)
)

a<- ggplot(df ,aes(x=x,y=y, colour = group))+
  geom_point(size=5,alpha=0.5,
             position = position_dodge(width = 0.9))+
  geom_segment(aes(yend=0,xend=x),
               position = position_dodge(width = 0.9))
b<- ggplot(df ,aes(x=y,y=x, colour = group))+
  geom_point(size=5,alpha=0.5,
             position = position_dodge(width = 0.9))+
  geom_segment(aes(xend=0,yend=x),
               position = position_dodge(width = 0.9))

a | b

Created on 2023-05-10 with reprex v2.0.2

@teunbrand
Copy link
Collaborator Author

Yes you'd still need to specify yend = 0 or xend = 0, it doesn't do anything that is not in the data.
The new thing is that you can leave out the yend = x or xend = x. Within one layer, you can leave out either xend or yend to have it filled with x and y respectively. The segment geom doesn't really have an orientation, so flipping aesthetics should just work. This filling in happens after positions adjustments, so the missing aesthetic just 'follows' the main one.

devtools::load_all("~/packages/ggplot2/")
#> ℹ Loading ggplot2
library(patchwork)

set.seed(42)
df <- data.frame(
  x = rep(letters[1:3], each = 2),
  y = rpois(6, 10),
  group = rep(LETTERS[1:2], 3)
)

a<- ggplot(df ,aes(x=x,y=y, colour = group))+
  geom_point(size=5,alpha=0.5,
             position = position_dodge(width = 0.9))+
  geom_segment(aes(yend=0), # Note, 'xend' is missing
               position = position_dodge(width = 0.9))
b<- ggplot(df ,aes(x=y,y=x, colour = group))+
  geom_point(size=5,alpha=0.5,
             position = position_dodge(width = 0.9))+
  geom_segment(aes(xend=0), # Note, 'yend' is missing
               position = position_dodge(width = 0.9))

a | b

Created on 2023-05-10 with reprex v2.0.2

@smouksassi
Copy link

thank you I will figure out how to switch
from geom_segment(aes(yend=0)) to geom_segment(aes(xend=0) depending on user input.
letting the user do lollipop plots has never been easier! thank you

@joranE
Copy link
Contributor

joranE commented Feb 23, 2024

Was this broken at some point? The examples at the top no longer work in 3.4.4 (haven't tried 3.5.0 yet), geom_segment complains about missing required aesthetics.

@teunbrand
Copy link
Collaborator Author

I don't think it was ever broken, but these examples should only work from 3.5.0 onwards

@joranE
Copy link
Contributor

joranE commented Feb 23, 2024

Gotcha, sorry for the noise. The date it was merged made me think it was incorporated earlier, sorry!

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

Successfully merging this pull request may close these issues.

Feature request: xend/yend defaults for geom_segment() Needle plots position_dodge() doesn't properly dodge segments
4 participants