Description
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
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))
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)))
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))
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)))
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.