Skip to content

geom_bar inconsistently handling date values #2047

Closed
@nteetor

Description

@nteetor

Description

There are unexpected plot results when specifying the fill aesthetic in geom_bar when the x aesthetic is a Date or POSIXct value. Below I have listed examples using Date and POSIXct objects, respectively. Similar data represented with these two classes results in rather different plots, see below.

Date Examples

The following examples use Date objects produced with make_date().

1 month with 2 fill values

In this example January fill values are TRUE and FALSE, February and March fill values are only FALSE.

library(ggplot2)
library(lubridate)

d1 <- data.frame(
  dates = rep(make_date(year = 2017, month = 1:3), each = 2),
  highlight = c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE)
)

# this unexpectedly changes the width of one of January's bars
ggplot(d1, aes(x = dates)) +
  geom_bar(aes(fill = highlight))
## Warning: position_stack requires non-overlapping x intervals

unnamed-chunk-1-1

1 month with distinct fill value

In this example January fill values are only TRUE, both February and March are only FALSE.

library(ggplot2)
library(lubridate)

d2 <- data.frame(
  dates = make_date(year = 2017, month = 1:3),
  highlight = c(TRUE, FALSE, FALSE)
)

# only one bar for January, but as above it is thin
ggplot(d2, aes(x = dates)) +
  geom_bar(aes(fill = highlight))

unnamed-chunk-2-1

3+ fill values

This example introduces a third fill value to the highlight column.

library(ggplot2)
library(lubridate)

d3 <- data.frame(
  dates = make_date(year = 2017, month = 1:3),
  highlight = c(1, 2, 3)
)

# all bars are now equally thin, additional breaks added to x-axis
ggplot(d3, aes(x = dates)) +
  geom_bar(aes(fill = factor(highlight)))

unnamed-chunk-3-1

POSIXct Examples

The following examples use POSIXct objects produced with make_datetime().

1 month with distinct fill value

In this example, when January fill is only FALSE, February and March are only TRUE, the January bar does not show. The bar may be too thin to see.

library(ggplot2)
library(lubridate)

d4 <- data.frame(
  datetimes = make_datetime(year = 2017, month = 1:3),
  highlight = c(TRUE, FALSE, FALSE)
)

# January bar is no longer thin, instead missing 
ggplot(d4, aes(x = datetimes)) +
  geom_bar(aes(fill = highlight))

unnamed-chunk-4-1

3+ fill values

Similar the 3+ fill value example above, however in this example the bars are not equally thin, they are all missing.

library(ggplot2)
library(lubridate)

d5 <- data.frame(
  datetimes = make_datetime(year = 2017, month = 1:3),
  highlight = c(1, 2, 3)
)

# no bars
ggplot(d5, aes(x = datetimes)) +
  geom_bar(aes(fill = factor(highlight)))

unnamed-chunk-5-1

Conclusion

The geom_bar fill aesthetic is not properly handling Date and POSIXct objects. I am not weighing in yet on whether bars ought to be thin or wide, rather I am hoping to iron out geom_bar so Date and POSIXct values are handled consistently. I hope I have not misunderstood how geom_bar is intended to handle date values.

I will look under the hood to try and identify the problem. For now I am not sure of a work around.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugan unexpected problem or unintended behaviorlayers 📈

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions