I have data from recordings made each evening from 21:00:00 to 5:59:59. I'm trying to make a bar plot of the compiled data, with time on the x-axis. However, I'm having trouble displaying only the times I have data for (i.e., omitting the times between 06:00:00 and 20:59:59). Furthermore, I want to represent the data as taking place over the course of the night, so starting at 21:00:00 and ending at 06:00:00.
My data look like this:
> head(songs)
Selection Begin.Time..s. End.Time..s. file date
1 1 0.0959375 0.4159375 Baldy-20240823_030000.WAV 2024-08-23
2 1 0.4799375 1.1199375 Baldy-20240825_030000.WAV 2024-08-25
3 2 1.1839375 1.5999375 Baldy-20240823_030000.WAV 2024-08-23
4 1 1.7599375 2.3359375 Quarry-20240905_030000.WAV 2024-09-05
5 3 2.1439375 2.8479375 Baldy-20240823_030000.WAV 2024-08-23
6 2 2.7199375 3.3919375 Baldy-20240825_030000.WAV 2024-08-25
Occupancy review overlap songs clock time
1 0.5 t t 21:00 2025-04-17 21:00:00
2 0.45 t t 21:00 2025-04-17 21:00:00
3 0.7692 t t 21:00 2025-04-17 21:00:00
4 0.5 overlap overlap 21:00 2025-04-17 21:00:00
5 0.6818 overlap overlap 21:00 2025-04-17 21:00:00
6 0.7619 overlap overlap 21:00 2025-04-17 21:00:00
> tail(songs)
Selection Begin.Time..s. End.Time..s. file
205490 432 32394.59 32395.01 Quarry-20240907_030000.WAV
205491 671 32395.23 32395.78 Baldy-20240902_030000.WAV
205492 672 32396.42 32396.96 Baldy-20240902_030000.WAV
205493 673 32397.70 32398.27 Baldy-20240902_030000.WAV
205494 433 32397.73 32398.11 Quarry-20240907_030000.WAV
205495 674 32399.17 32399.62 Baldy-20240902_030000.WAV
date Occupancy review overlap songs clock time
205490 2024-09-07 0.5385 t t 05:59 2025-04-17 05:59:00
205491 2024-09-02 0.8235 t t 05:59 2025-04-17 05:59:00
205492 2024-09-02 0.8824 t t 05:59 2025-04-17 05:59:00
205493 2024-09-02 0.7778 t t 05:59 2025-04-17 05:59:00
205494 2024-09-07 0.5833 t t 05:59 2025-04-17 05:59:00
205495 2024-09-02 0.9286 t t 05:59 2025-04-17 05:59:00
Using this code...
library(ggplot2)
ostf1 = ggplot(songs,aes(x=time,fill=songs)) + geom_bar() + theme_classic() +
labs(x="Time", y="Count") +
theme(legend.title = element_blank()) +
scale_fill_hue(labels = c("Overlapping", "Single")) +
scale_y_continuous(breaks=seq(0,10000,by=100), expand = c(0,0)) +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) +
scale_x_datetime(date_breaks = "1 hours", date_labels = "%H:%M", expand = c(0,0))
...I get the figure below, with the times ordered from 00:00:00 to 23:59:59, and a big gap in the middle:
How can I reorder the two blocks of data, so that the x-axis reads from 21:00:00 to 06:00:00, and get rid of the big empty space?
EDIT: I neglected to mention that, while the data are all labeled as being on the same date, these recordings actually took place each night over several months. The dates in the data are wrong - they're just the date I converted the times to dttm
. Hopefully that explains why I'm trying to eliminate the daytime hours and reorder the arrangement in the figure. Sorry for not explaining that in my original post!
You can shift the times that are between 9 PM and midnight a day back, so they appear before and adjacent to the rest of your data with no gap.
Note that in the example below, I don't have all of your data, so there are some gaps but Time axis spans from 21 to 6.
# sample data
songs <- data.frame(
Selection = c(1, 1, 2, 1, 3, 2, 432, 671, 672, 673, 433, 674),
Begin.Time..s. = c(0.0959375, 0.4799375, 1.1839375, 1.7599375, 2.1439375,
2.7199375, 32394.59, 32395.23, 32396.42, 32397.70, 32397.73, 32399.17),
End.Time..s. = c(0.4159375, 1.1199375, 1.5999375, 2.3359375, 2.8479375,
3.3919375, 32395.01, 32395.78, 32396.96, 32398.27, 32398.11, 32399.62),
file = c("Baldy-20240823_030000.WAV", "Baldy-20240825_030000.WAV", "Baldy-20240823_030000.WAV",
"Quarry-20240905_030000.WAV", "Baldy-20240823_030000.WAV", "Baldy-20240825_030000.WAV",
"Quarry-20240907_030000.WAV", "Baldy-20240902_030000.WAV", "Baldy-20240902_030000.WAV",
"Baldy-20240902_030000.WAV", "Quarry-20240907_030000.WAV", "Baldy-20240902_030000.WAV"),
date = as.Date(c("2024-08-23", "2024-08-25", "2024-08-23", "2024-09-05", "2024-08-23", "2024-08-25",
"2024-09-07", "2024-09-02", "2024-09-02", "2024-09-02", "2024-09-07", "2024-09-02")),
Occupancy = c(0.5, 0.45, 0.7692, 0.5, 0.6818, 0.7619, 0.5385, 0.8235, 0.8824, 0.7778, 0.5833, 0.9286),
review = c("t", "t", "t", "overlap", "overlap", "overlap", "t", "t", "t", "t", "t", "t"),
songs = c("t", "t", "t", "overlap", "overlap", "overlap", "t", "t", "t", "t", "t", "t"),
clock = c("21:00", "21:00", "21:00", "21:00", "21:00", "21:00", "05:59", "05:59", "05:59", "05:59", "05:59", "05:59"),
time = as.POSIXct(c("2025-04-17 21:00:00", "2025-04-17 21:10:00", "2025-04-17 21:10:00", "2025-04-17 21:20:00",
"2025-04-17 21:00:00", "2025-04-17 21:10:00", "2025-04-17 05:59:00", "2025-04-17 05:59:00",
"2025-04-17 05:39:00", "2025-04-17 05:59:00", "2025-04-17 05:49:00", "2025-04-17 05:39:00"))
)
library(ggplot2)
library(dplyr)
songs %>%
## shifting 21-24 a day back
mutate(time2 = if_else(lubridate::hour(time) < 21,
time, time - 24 * 60 * 60)) %>%
ggplot(aes(x = time2, fill = songs)) +
geom_bar() +
scale_x_datetime(name = "Time",
date_breaks = "1 hours", date_labels = "%H:%M",
expand = c(0,0)) +
scale_y_continuous(name = "Count",
## commenting out for the sample data
#breaks = seq(0, 10000, by=100),
expand = c(0, 0)) +
scale_fill_hue(labels = c("Overlapping", "Single")) +
theme_classic() +
theme(legend.title = element_blank(),
axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1))
Another method is to use ggbreak
to keep the right order, but remove the empty space.
songs %>%
ggplot(aes(x = time, fill = songs)) +
geom_bar() +
ggbreak::scale_x_break(breaks=as.POSIXct(c("2025-04-17 6:00:00",
"2025-04-17 21:00:00")),
scales = 0.5) +
scale_x_continuous(breaks = as.numeric(as.POSIXct("2025-04-17 0:00:00") +
c(0:6, 21:24) * 3600),
limits = as.numeric(as.POSIXct("2025-04-17 0:00:00") +
c(0, 24) * 3600),
labels = \(dt) {format(as.POSIXct(dt,
origin = "1970-01-01"),
"%H:%M")}) +
scale_y_continuous(## commenting out for the sample data
#breaks = seq(0, 10000, by=100),
expand = c(0,0)) +
labs(x = "Time", y = "Count") +
scale_fill_hue(labels = c("Overlapping", "Single")) +
theme_classic() +
theme(legend.title = element_blank(),
axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
axis.text.x.top = element_blank(),
axis.ticks.x.top = element_blank(),
axis.line.x.top = element_blank())