Inconsistent bar widths when month-scaling in ggpl

2019-06-14 21:09发布

I looked for a while, and was unable to locate a post discussing a similar issue. I am having an issue with date-scaling in ggplot, which I think is related to the way ggplot is handling dates. I am trying to get rid of all of the white space in between the columns because my end result will be similar to the following, which is a capacity planning chart showing projects spanning the months:

End Goal

The gap between the columns appears inconsistent even with default scaling and width parameters, which led me to believe that that ggplot may be drawing all of the columns at a set width but placing them on the x-axis relative to the number of days in each month. However, even after creating a "month length" variable to scale each column independently, I am unable to get all of the gaps to close, without causing others to overlap. Can someone provide some insight to how ggplot is handling dates?

Here is some reproducible code to play with:

library(lubridate)
library(ggplot2)
library(scales)

Months <- c("2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", "2015-05-01", 
            "2015-06-01", "2015-07-01", "2015-08-01", "2015-09-01", "2015-10-01")
Months <- as.Date(Months)
Totals <- c(1330, 1010, 950, 1110, 1020, 1160, 1320, 880, 620, 320)
df <- data.frame(Months, Totals)
df$MonthLength <- days_in_month(as.Date(df$Month))

ggplot()+
  geom_bar(data=df, aes (x = Months, y = Totals, fill = Months, width = MonthLength), 
                    position = "dodge", stat = "identity", alpha = 0.80)+
  coord_cartesian(ylim = c(0, 1600))+
  scale_x_date(breaks="1 month",limits=c(as.Date("2015-01-01"),as.Date("2015-10-01")), 
                                labels = date_format("%b-%Y"))

标签: r date ggplot2
1条回答
迷人小祖宗
2楼-- · 2019-06-14 21:31

I think what is happening, is that ggplot puts each tick mark and hence each bar at the 15th of the month. Therefore, if you make the bars larger, the february-bar overlaps with march, but falls short of january. (I would call that a bug, but who am I ;-))

The way around this, is the convert your months to a factor, and then set width=1:

df$Fmonth <- factor(month(Months))
ggplot(data=df, aes (x = Fmonth, y = Totals, fill = Months)) +
  geom_bar(position = "dodge", stat = "identity", alpha = 0.80, width=1) +
  coord_cartesian(ylim = c(0, 1600))

enter image description here

Another way around it might be to calculate the middle of the month by hand, position your data there and then follow your original route of bar width=MonthLength.

查看更多
登录 后发表回答