Omar Gonzales Omar Gonzales - 1 month ago 16
R Question

R: ggplot2 plot hourly data faceted by weekday

I want to plot data hourly. I've search all the questions related to this topic, without success.

Most of them tell to transform to

POSIXct
format. I've made that but the
x axis
shows months not hours.

This is the str() for the data frame:

Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 685 obs. of 3 variables:
$ dias : chr "dom" "dom" "dom" "dom" ...
$ horas : POSIXct, format: "2016-01-03 13:45:53" ...
$ conteo: int 1 1 1 1 1 1 1 1 1 1 ...
- attr(*, "spec")=List of 2
..$ cols :List of 3
.. ..$ dias : list()
.. .. ..- attr(*, "class")= chr "collector_character" "collector"
.. ..$ horas :List of 1
.. .. ..$ format: chr ""
.. .. ..- attr(*, "class")= chr "collector_datetime" "collector"
.. ..$ conteo: list()
.. .. ..- attr(*, "class")= chr "collector_integer" "collector"
..$ default: list()
.. ..- attr(*, "class")= chr "collector_guess" "collector"
..- attr(*, "class")= chr "col_spec"


I would also like to facet this graph by weekday. I've made this drawing to make my point:

enter image description here

I've made this:

enter image description here

With this code:

ggplot(data=data,aes(x=horas, y=conteo)) +
#geom_point() +
geom_bar(colour = "blue",stat = "identity") +
#facet_wrap(~ dias) +
ylab("Sismos") +
xlab("Hora") +
#opts(title = "Precipitacion acumulada horaria \n 2008-05-27 Burriana") +
scale_y_continuous(limits = c(0,2))


Data:

data <- structure(list(dias = c("dom", "dom", "dom", "dom", "dom", "dom",
"dom", "dom", "dom", "jue", "jue", "jue", "jue", "jue", "jue",
"jue", "jue", "jue", "jue", "lun", "lun", "lun", "lun", "lun",
"lun", "lun", "lun", "lun", "lun", "mar", "mar", "mar", "mar",
"mar", "mar", "mar", "mar", "mar", "mar", "mar", "mi<e9>", "mi<e9>",
"mi<e9>", "mi<e9>", "mi<e9>", "mi<e9>", "mi<e9>", "mi<e9>", "mi<e9>",
"mi<e9>", "mi<e9>", "mi<e9>", "s<e1>b", "s<e1>b", "s<e1>b", "s<e1>b",
"s<e1>b", "s<e1>b", "s<e1>b", "s<e1>b", "s<e1>b", "s<e1>b", "s<e1>b",
"s<e1>b", "s<e1>b", "s<e1>b", "vie", "vie", "vie", "vie", "vie",
"vie", "vie", "vie", "vie", "vie", "vie", "vie", "vie"), horas = c("03/01/2016 13:45",
"10/01/2016 03:57", "10/01/2016 08:22", "10/01/2016 15:43", "18/09/2016 07:05",
"18/09/2016 12:37", "25/09/2016 00:09", "25/09/2016 07:10", "25/09/2016 11:02",
"31/12/2015 21:26", "31/12/2015 23:18", "07/01/2016 09:55", "07/01/2016 21:17",
"07/01/2016 22:14", "14/01/2016 01:05", "14/01/2016 02:35", "14/01/2016 12:43",
"14/01/2016 13:30", "21/01/2016 06:44", "04/01/2016 11:36", "04/01/2016 14:01",
"04/01/2016 20:51", "04/01/2016 21:25", "04/01/2016 22:53", "11/01/2016 04:58",
"11/01/2016 17:23", "18/01/2016 20:11", "18/01/2016 21:04", "18/01/2016 22:28",
"05/01/2016 00:14", "05/01/2016 01:23", "05/01/2016 03:22", "05/01/2016 04:45",
"05/01/2016 21:00", "05/01/2016 21:13", "12/01/2016 06:50", "12/01/2016 14:12",
"19/01/2016 00:45", "19/01/2016 03:28", "19/01/2016 07:52", "13/01/2016 02:09",
"13/01/2016 02:30", "13/01/2016 02:52", "13/01/2016 03:22", "13/01/2016 04:02",
"13/01/2016 05:41", "13/01/2016 07:20", "13/01/2016 08:45", "13/01/2016 15:05",
"20/01/2016 07:01", "20/01/2016 18:20", "27/01/2016 00:49", "09/01/2016 21:19",
"09/01/2016 22:29", "16/01/2016 00:25", "16/01/2016 05:28", "16/01/2016 05:59",
"16/01/2016 16:39", "23/01/2016 02:31", "23/01/2016 03:46", "23/01/2016 19:51",
"30/01/2016 08:04", "30/01/2016 11:03", "30/01/2016 14:55", "06/02/2016 01:20",
"20/02/2016 22:51", "22/01/2016 04:19", "22/01/2016 14:11", "29/01/2016 03:41",
"29/01/2016 11:06", "29/01/2016 11:37", "29/01/2016 12:27", "05/02/2016 12:44",
"12/02/2016 01:50", "12/02/2016 08:11", "12/02/2016 22:46", "12/02/2016 23:32",
"19/02/2016 11:27", "19/02/2016 18:27"), conteo = c(1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -79L), .Names = c("dias",
"horas", "conteo"), spec = structure(list(cols = structure(list(
dias = structure(list(), class = c("collector_character",
"collector")), horas = structure(list(), class = c("collector_character",
"collector")), conteo = structure(list(), class = c("collector_integer",
"collector"))), .Names = c("dias", "horas", "conteo")), default = structure(list(), class = c("collector_guess",
"collector"))), .Names = c("cols", "default"), class = "col_spec"))

Answer

You can do the calculations outside of ggplot2 as well. This can be formatted better but it depends on the version of ggplot2 you are using (and from where). This also orders the days:

library(tidyverse)
library(ggplot2)

# `data` is a super-bad name for a variable so I used `df` which is
# only marginally better. ideally, you'd use something far more 
# descriptive so your future self doesn't hate you.

mutate(df, dias=ifelse(dias=="mi<e9>", "mie", dias)) %>%       # needed to do this on my system with your `dput()`
  mutate(dias=ifelse(dias=="s<e1>b", "sab", dias)) %>%         # needed to do this on my system with your `dput()`
  mutate(dias=factor(dias, levels=c("lun", "mar", "mie", "jue", "vie", "sab", "dom"))) %>%  # ordered days; i'd personally start them on Sunday but I have no idea what you need
  mutate(horas=as.POSIXct(horas, format="%d/%m/%Y %H:%M")) %>% 
  mutate(hour=lubridate::hour(horas)) -> df

count(df, dias, hour, wt=conteo) %>% 
  ggplot(aes(hour, n)) +
  geom_segment(aes(xend=hour, yend=0)) +
  geom_point() +
  scale_x_continuous(breaks=c(0, 12, 23),
                     labels=c("00:00", "12:00", "23:00"),
                     limits=c(0,23)) +
  facet_wrap(~dias, scales="free_x") +
  labs(x=NULL, y=NULL) +
  theme_minimal() +
  theme(strip.text=element_text(hjust=0, face="bold")) +
  theme(panel.grid.major.x=element_blank()) +
  theme(panel.grid.minor=element_blank()) +
  theme(plot.margin=margin(30,30,30,30)) +
  theme(axis.text.x=element_text(hjust=c(0, 0.5, 1)))

enter image description here