Home > Net >  R ggplot2 Customizing date axis labels with different colors
R ggplot2 Customizing date axis labels with different colors

Time:08-26

I would like to color the date axis labels considering some conditions. Here is an example:

# Libraries
library("ggplot2")
library("lubridate")

# Create data
data0 <- data.frame(dt = seq(as.Date('2022-01-01'),as.Date('2022-01-20'),1))
data0$y <- runif(length(data0$dt))
head(data0)
###           dt          y
### 1 2022-01-01 0.99842049
### 2 2022-01-02 0.10663102
### 3 2022-01-03 0.04824916
### 4 2022-01-04 0.49312740
### 5 2022-01-05 0.01445124
### 6 2022-01-06 0.96767266

# Define color red for Saturday and Sunday
lab_col <- with(data0, ifelse(wday(dt) %in% c(1,7),"red","black"))

ggplot(data0,aes(dt,y))  
    geom_line()  
    scale_x_date(date_breaks = "1 day"
               , date_labels = "%Y-%m-%d (%a)"
                 )  
    theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust=1, colour=lab_col))

This gives what I expected:

enter image description here

But it also gives this message:

Warning message:
Vectorized input to `element_text()` is not officially supported.
Results may be unexpected or may change in future versions of ggplot2.

Indeed, using my original data the wrong weekdays are colored red.

I found a possible solution here using ggtext:

data0$dt2 <- with(data0, paste0("<i style = 'color: "
                                 , lab_col
                                 , ";'>"
                                 , dt
                                 , " (",wday(dt, label=TRUE),")"
                                 , "</i>"
                                  )
                  )
head(data0)
###           dt          y                                            dt2
### 1 2022-01-01 0.99842049   <i style = 'color: red;'>2022-01-01 (Sa)</i>
### 2 2022-01-02 0.10663102   <i style = 'color: red;'>2022-01-02 (So)</i>
### 3 2022-01-03 0.04824916 <i style = 'color: black;'>2022-01-03 (Mo)</i>
### 4 2022-01-04 0.49312740 <i style = 'color: black;'>2022-01-04 (Di)</i>
### 5 2022-01-05 0.01445124 <i style = 'color: black;'>2022-01-05 (Mi)</i>
### 6 2022-01-06 0.96767266 <i style = 'color: black;'>2022-01-06 (Do)</i>    

library("ggtext")
ggplot(data0,aes(dt2,y))  
    geom_line()  
    scale_x_date(date_breaks = "1 day")  
    theme(axis.text.x = element_markdown(angle = 90, vjust = 0.3, hjust=1))

But this gives me this error:

Error: Invalid input: date_trans works with objects of class Date only

This makes sense since dt2 is not a date. The SO-example from above link consider factor variables. How can I use the power of ggtext with date as x-variable?

CodePudding user response:

You're right about why ggtext doesn't work, but we can work around this.

You can use a function for the labels argument of the scale. This can be a function that does the label formatting for you.

# Libraries
library("ggplot2")
library("lubridate")
library("ggtext")

# Create data
data0 <- data.frame(dt = seq(as.Date('2022-01-01'),as.Date('2022-01-20'),1))
data0$y <- runif(length(data0$dt))

ggplot(data0,aes(dt,y))  
  geom_line()  
  scale_x_date(
    date_breaks = "1 day",
    labels = function(x) {
      col <- ifelse(wday(x) %in% c(1, 7), "red", "black")
      lab <- strftime(x, format = "%Y-%m-%d (%a)")
      glue::glue("<span style = 'color:{col}'>{lab}</span>")
    }
  )  
  theme(axis.text.x = element_markdown(angle = 90, vjust = 0.3, hjust=1))

Created on 2022-08-26 by the reprex package (v2.0.0)

  • Related