Search code examples
rggplot2powerbigeom-bar

I'm having a lot of trouble trying using scale_y_datetime not show geom_bar


I'm having a lot of trouble trying using scale_y_datetime not show geom_bar show message remove 30 rows and trying coord_cartesian of trouble upside down.

Warning message:
Removed 30 rows containing missing values (geom_bar).

My raw data is character strings of the format:

> dataset
                          Date      Duration Time
1  2020-06-01T00:00:00.0000000 1899-12-31T04:43:00.0000000
2  2020-06-02T00:00:00.0000000 1899-12-31T04:37:00.0000000
3  2020-06-03T00:00:00.0000000 1899-12-31T04:25:00.0000000
4  2020-06-04T00:00:00.0000000 1899-12-31T04:48:00.0000000
5  2020-06-05T00:00:00.0000000 1899-12-31T04:52:00.0000000
6  2020-06-06T00:00:00.0000000 1899-12-31T05:19:00.0000000
7  2020-06-07T00:00:00.0000000 1899-12-31T04:25:00.0000000
8  2020-06-08T00:00:00.0000000 1899-12-31T04:43:00.0000000
9  2020-06-09T00:00:00.0000000 1899-12-31T05:26:00.0000000
10 2020-06-10T00:00:00.0000000 1899-12-31T04:26:00.0000000

https://i.sstatic.net/PjgU6.png

 Sys.setenv(TZ='UTC')
    library(scales)
    library(ggplot2)
    library(reshape2) 
        Day=format(as.POSIXct(dataset$'Date', format="%Y-%m-%dT%H:%M:%S",tz="UTC"), format="%y-%b-%d")
        Hour=as.POSIXct(dataset$'Duration Time', format="%Y-%m-%dT%H:%M:%S",tz="UTC")
        lima1 = c(as.POSIXct("1899-12-31T01:00:00",format="%Y-%m-%dT%H:%M:%S",tz="UTC"),as.POSIXct("1899-12-31T08:00:00",format="%Y-%m-%dT%H:%M:%S",tz="UTC"))
        DurationTime <- c(Hour)
        day <- c(Day)
    
    df1 <- data.frame(DurationTime, day)
    df <- melt(df1, id.vars = "day")
    head(df)
    start_time = strptime("1899-12-31 02:00:00", format = "%Y-%m-%d %H:%M:%S")
    breaks = seq(0, 6, length.out = 7)
    labels = c( "02:00", "03:00", 
               "04:00", "05:00", "06:00", "07:00", "08:00")
    dataFrame <- data.frame(df)
    names(dataFrame) <- c("day","Variable","Value")
    #dataFrame$Time <- dataFrame$Value
    #dataFrame$TimeInSeconds <- as.difftime(dataFrame$Time - start_time)
    
    ggplot(data = dataFrame,aes(x = dataFrame$'day', 
                                     y = as.POSIXct(dataFrame$'Value', format="%Y-%m-%dT%H:%M:%S",tz="UTC"),
                                     fill = Variable)) + 
      geom_bar(stat="identity",position = 'dodge') +
      geom_text(aes(label=format(as.POSIXct(dataFrame$'Value', format="%Y-%m-%dT%H:%M:%S",tz="UTC"), format="%H:%M")), position=position_dodge(width=0.9), hjust =-0.10,angle=90) + 
      #scale_y_continuous(limits = c(0, 6),breaks = breaks,labels = labels)
      #coord_cartesian(ylim=c(as.POSIXct("1899-12-31T01:00:00",format="%Y-%m-%dT%H:%M:%S"),as.POSIXct("1899-12-31T08:00:00",format="%Y-%m-%dT%H:%M:%S"))) +
      scale_y_datetime(limits=c(as.POSIXct("1899-12-31T01:00:00",format="%Y-%m-%dT%H:%M:%S"),as.POSIXct("1899-12-31T08:00:00",format="%Y-%m-%dT%H:%M:%S")),breaks=date_breaks("1 hour"),labels=date_format("%H:%M", tz = "UTC"))+
    
      theme_bw()+
    xlab("Day") +
    ylab("Time") +
    labs(fill="Legend") +
    theme(axis.text.x=element_text(angle=90))+
    theme(axis.text.y=element_text(angle=45))+
      theme(legend.position = 'bottom')+
      theme(panel.grid.major = element_blank(),panel.background = element_blank())

I'm using ylim coord_cartesian it upside down I don't want to upside down. I want the normal vertical.

coord_cartesian(ylim=c(as.POSIXct("1899-12-31T01:00:00",format="%Y-%m-%dT%H:%M:%S"),as.POSIXct("1899-12-31T08:00:00",format="%Y-%m-%dT%H:%M:%S"))) +
  scale_y_datetime(breaks=date_breaks("1 hour"),labels=date_format("%H:%M", tz = "UTC"))+

https://i.sstatic.net/JIq4Z.png


Solution

  • I think I got it.

    The reason why you see the bars upside down is because ggplot doesnt understand dates. Ggplot sees numbers: converts dates to numbers. Those duration times converted to numbers are negative. Therefore the bars are correctly towards the negative side.

    The solution is to make your duration dates to start from the "zero" date of R.

    Look at this reproducible example here: [I kept all your themes and settings of the chart]

    library(scales)
    library(ggplot2)
    library(reshape2) 
    library(lubridate) 
    library(dplyr) 
    
    
    dataset <- tibble::tribble(~Date, ~`Duration Time`,
                               "2020-06-01T00:00:00.0000000", "1899-12-31T04:43:00.0000000",
                               "2020-06-02T00:00:00.0000000", "1899-12-31T04:37:00.0000000",
                               "2020-06-03T00:00:00.0000000", "1899-12-31T04:25:00.0000000",
                               "2020-06-04T00:00:00.0000000", "1899-12-31T04:48:00.0000000",
                               "2020-06-05T00:00:00.0000000", "1899-12-31T04:52:00.0000000",
                               "2020-06-06T00:00:00.0000000", "1899-12-31T05:19:00.0000000",
                               "2020-06-07T00:00:00.0000000", "1899-12-31T04:25:00.0000000",
                               "2020-06-08T00:00:00.0000000", "1899-12-31T04:43:00.0000000",
                               "2020-06-09T00:00:00.0000000", "1899-12-31T05:26:00.0000000",
                               "2020-06-10T00:00:00.0000000", "1899-12-31T04:26:00.0000000")
    
    
    dataset <- dataset %>%
      mutate(Day = as_date(Date),
             `Duration Time` = as_datetime(`Duration Time`)) %>% 
      mutate(Time = make_datetime(hour = hour(`Duration Time`), 
                                  min = minute(`Duration Time`),
                                  sec = second(`Duration Time`)))
      
    
    ggplot(data = dataset,
           aes(x = Day, 
               y = Time)) + 
      geom_bar(fill = "steelblue", stat = "identity") +
      geom_text(aes(label = format(Time, format="%H:%M")), position=position_dodge(width=0.9), hjust =-0.10,angle=90) + 
      theme_bw() +
      xlab("Day") +
      ylab("Time") +
      labs(fill="Legend") +
      theme(axis.text.x = element_text(angle = 90))+
      theme(axis.text.y = element_text(angle = 45))+
      theme(legend.position = 'bottom')+
      theme(panel.grid.major = element_blank(),
            panel.background = element_blank())
    

    enter image description here