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

bug: geom_text in middle of stacked bar_plot not in the middle (v2.1.0.9001) #1821

Closed
dpprdan opened this issue Oct 4, 2016 · 7 comments
Closed
Milestone

Comments

@dpprdan
Copy link

dpprdan commented Oct 4, 2016

The placement of geom_text in the middle of a stacked bar_plot is off. When I run the example from the help file of geom_text I get:

df <- data.frame(
  x = factor(c(1, 1, 2, 2)),
  y = c(1, 3, 2, 1),
  grp = c("a", "b", "a", "b")
)

df <- transform(df, mid_y = ave(df$y, df$x, FUN = function(val) cumsum(val) - (0.5 * val)))

ggplot(data = df, aes(x, y, fill = grp, label = y)) +
  geom_col() +
  geom_text(aes(y = mid_y))

stacked_text

I suppose this is due to "position_stack() and position_fill() now stack values in the reverse order of the grouping, which makes the default stack order match the legend."

@aosmith16
Copy link

The dataset will need to be arranged in the reverse order of the fill factor to calculate the positions correctly with cumsum.

df <- transform(df[order(rev(df$grp)), ], mid_y = ave(y, x, FUN = function(val) cumsum(val) - (0.5 * val)))

@dpprdan
Copy link
Author

dpprdan commented Oct 4, 2016

That's a possibility, of course, but a bad one at that, IMHO. Because reversing the order of the grouping of the bars under the hood without reversing the order of the labels is a breaking change. After all the example from the geom_text help file is working in v2.1 and will break, as it stands, in v2.2, and so will all similar bar charts created with ggplot2 v2.1 and before. So is there a chance to adapt geom_text to the new grouping order?

@hadley hadley added this to the v2.2.0 milestone Oct 5, 2016
@hadley
Copy link
Member

hadley commented Oct 5, 2016

One possible resolution would be a new position adjustment that "stacks" text like this, including an optional parameter (0-1) that lets you control where the text appears within the rectangular region. That wouldn't fix existing code the relies on the specific stacking order, but it would provide a simple fix.

@hadley
Copy link
Member

hadley commented Oct 5, 2016

Here's a quick implementation:

#' @example
#' df <- data.frame(
#' x = factor(c(1, 1, 2, 2)),
#' y = c(1, 3, 2, 1),
#' grp = c("a", "b", "a", "b")
#' )
#'
#' ggplot(data = df, aes(x, y, fill = grp, label = y)) +
#'   geom_col() +
#'   geom_text(position = "stack_point")
position_stack_point <- function(vjust = 0.5) {
  ggproto(NULL, PositionStackPoint,
    vjust = vjust
  )
}

PositionStackPoint <- ggproto("PositionStackPoint", Position,
  required_aes = c("x", "y"),
  vjust = 0.5,

  setup_params = function(self, data) {
    list(vjust = self$vjust)
  },

  compute_layer = function(self, data, params, panel) {
    data <- data[order(data$x, -data$group), ]
    data$y <- ave(data$y, data$x, FUN = function(x) cumsum(x) - ((1 - params$vjust) * x))
    data
  }
)

@hadley
Copy link
Member

hadley commented Oct 7, 2016

I now think that this should be integrated with position_stack so it does the right thing for both points and bars

@thomasp85
Copy link
Member

We could have a just argument that could control that. It works fine for points as it is now (I.e. It stacks them) but this would give users even more control

@hadley
Copy link
Member

hadley commented Oct 7, 2016

That's what I'm in the middle of implementing 😄

@hadley hadley closed this as completed in a8d62d3 Oct 7, 2016
@lock lock bot locked as resolved and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants