Eliomys
Eliomys

Reputation: 13

How to change time-order on x-axis?

I have a question to this specific code:

ggplot(MAGS)+
  geom_col(aes(x = Photo.time@hour + Photo.time@minute/60, y = Number.of.Animals), lwd = 1) + ylab("total amount") +
  scale_x_continuous(breaks = seq(0,24,4), name = "time", labels = c( "0:00", "4:00", "8:00", "12:00", "16:00", "20:00", "23:59")) +
  theme_bw() + theme_classic() 

scale_y_continuous(breaks = seq(0,10,2), name = "total amount", labels = c( "o","2","4","6","8","10"))

With this code I created the attached plot. This plot is okay but I guess it would look better if I changed the x axis so that it starts with 12:00pm, has 00:00am in the middle and ends with 11:59am. Kind of like in the attached plot but flipped. The data set comes from a nocturnal animal with high activity around midnight so it would be better to have 00:00 in the center of the x axis. I tried several things but i always ended up with a mess. I can't figure out where my mistake is.

Thank you very much for helping :)

I tried several things to rearrange the x axis but I can't find the problem.

enter image description here

Upvotes: 0

Views: 266

Answers (1)

Jon Spring
Jon Spring

Reputation: 66490

I'd suggest making a helper column that is ordered the way you want -- in this case I have added 24 hours to the first 12 hours of the day, to make hours 0:12 appear in hours 24:36, and then adjusting the labeling accordingly.

df1 <- data.frame(x = seq(0, 24 - 1/60, 1/60), y = 1:1440)
df1$x_order = df1$x + ifelse(df1$x < 12, 24, 0)

ggplot(df1, aes(x_order, y)) +
  geom_col() +
  scale_x_continuous(breaks = 12 + seq(0,24,4), name = "time", 
                     labels = c("12:00", "16:00", "20:00", "00:00am", "4:00", "8:00", "12:00")) 

enter image description here


EDIT - Based on the sample data you added in a comment, I've made some fake data that shows the overall pattern you have in your full data:

structure(list(Photo.time = new("Period", 
  .Data = c(51, 52, 54, 55, 56, 58, 0, 58, 56, 57), 
  year = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
  month = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
  day = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
  hour = c(1, 2, 3, 4, 5, 6, 7, 12, 15, 20), 
  minute = c(48, 48, 48, 49, 49, 49, 58, 49, 0, 0)), 
  Number.of.Animals = c(10L, 8L, 6L, 5L, 2L, 1L, 0L, 2L, 6L, 10L)), 
  class = "data.frame", row.names = c(NA, 10L)) |>
  
ggplot() + 
  geom_col(aes(x = Photo.time@hour + Photo.time@minute/60, y = Number.of.Animals), lwd = 1) + ylab("total amount") +
  scale_x_continuous(breaks = seq(0,24,4), name = "time", labels = c( "0:00", "4:00", "8:00", "12:00", "16:00", "20:00", "23:59")) +
  theme_bw() + theme_classic() 

enter image description here

I had trouble manipulating your time data, so I converted to decimal hours and applied my adjustment from above:

structure(list(Photo.time = new("Period", .Data = c(51, 52, 54, 55, 56, 58, 0, 58, 56, 57), year = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), month = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), day = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), hour = c(1, 2, 3, 4, 5, 6, 7, 12, 15, 20), minute = c(48, 15, 48, 30, 49, 49, 58, 49, 0, 0)), Number.of.Animals = c(10L, 8L, 6L, 5L, 2L, 1L, 0L, 2L, 6L, 10L)), class = "data.frame", row.names = c(NA, 10L)) |>
  mutate(time_hr_dec = as.numeric(Photo.time)/(60*60),
         time_hr_dec2 = time_hr_dec + ifelse(time_hr_dec < 12, 24, 0)) |> 
ggplot() + 
  geom_col(aes(x = time_hr_dec2, y = Number.of.Animals), lwd = 1) + ylab("total amount") +
  scale_x_continuous(breaks = 12 + seq(0,24,4), name = "time", 
                     labels = c("12:00", "16:00", "20:00", "00:00am", "4:00", "8:00", "12:00")) +
  theme_bw() + theme_classic() 

Yay, look! It has the expected shape and labels.

enter image description here

Upvotes: 1

Related Questions