1

Here's a reproductible example taken from the R Graph Gallery:

library(ggplot2)
library(dplyr) 
library(viridis) 
library(Interpol.T) 
library(lubridate) 
library(ggExtra) 
library(tidyr) 


data <- data(Trentino_hourly_T,package = "Interpol.T")

names(h_d_t)[1:5]<- c("stationid","date","hour","temp","flag")
df <- as_tibble(h_d_t) %>%
  filter(stationid =="T0001")

df$date<-ymd(df$date)

df <- df %>% mutate(date = ymd(date),
                    year = year(date),
                    month = month(date, label=TRUE),
                    day = day(date))

rm(list=c("h_d_t","mo_bias","Tn","Tx",
          "Th_int_list","calibration_l",
          "calibration_shape","Tm_list"))

df <- df %>%
  filter(between(date, as.Date("2004-02-13"), as.Date("2004-04-29")) | between(date, as.Date("2005-02-13"), as.Date("2005-04-29")))

df <-df %>% select(stationid,day,hour,month,year,temp)%>%
  fill(temp)

statno <-unique(df$stationid)


######## Plotting starts here#####################
p <-ggplot(df, aes(day,hour,fill=temp))+
  geom_tile(color= "white",size=0.1) + 
  scale_fill_viridis(name="Hrly Temps C",option ="C") + 
  facet_grid(year~month, scales = "free") +
  scale_y_continuous(trans = "reverse", breaks = unique(df$hour)) + 
  theme_minimal(base_size = 8) + 
  labs(title= paste("Hourly Temps - Station",statno), x="Day", y="Hour Commencing") + 
  theme(legend.position = "bottom",
        plot.title=element_text(size = 14, hjust = 0),
        axis.text.y=element_text(size=6),
        strip.background = element_rect(colour="white"),
        axis.ticks=element_blank(),
        axis.text=element_text(size=7),
        legend.text=element_text(size=6))+
  removeGrid()

Default x axes breaks

What is bothering me is that the x axis breaks don't show explicitly the first and last day of each month, even worse they show a February 30th, a March 0th and a April 0th.

My goal is to use a function that automatically and explicitly shows the REAL first and last day of each ploted month (in the example February 13th - February 29th, March 1st - March 31th and April 1st - April 29th) with 4 to 6 breaks within each month.

As this plot will be shown in a shiny app where the user can change the time period ploted, the solution REALLY needs to be automated.

Here are some things I've tried:

library(scales)
p + scale_x_continuous(breaks =breaks_pretty())

breaks_pretty() axes breaks But it doesn't change much.

I've tried to write my own function but something horrible happened:

breaksFUN <- function(x){
  round(seq(min(x), max(x), length.out = 5), 0)
}

p + scale_x_continuous(breaks =breaksFUN)

breaksFUN axes breaks

Thank you in advance.

  • Maybe something like: `breaksFUN <- function(x) { c(round(seq(min(x) + 0.5, max(x) - 5.5, length.out = 4)), max(x) - 0.5) }`, and then `p + scale_x_continuous(breaks = breaksFUN, expand = c(0, 0))`. – Axeman Apr 20 '21 at 15:02

1 Answers1

0

Thank you Axeman for your contribution, it really helped! It works for my example but i've encountered some issues trying it out in my data. However, I modified it and it works properly now, here's my solution inspired by Axeman:

breaksFUN <- function(x) {
  s <- round(c(seq(min(x) + 1.5, max(x) - 5.5, length.out = 4), max(x) - 1.5))
  s[s == 0] <- 1
  s[s > 31] <- 31
  s <- round(seq(range(s)[1], range(s)[2], length.out = 5))
  unique(s)
}

p + scale_x_continuous(breaks = breaksFUN)