zoowalk
zoowalk

Reputation: 2134

ggplot2: Modifying all but first axis labels via a function

I have a plot with an numeric x axis. The values are years. I want to modify the labels so that the first year is displayed in full, the subsequent instances are abbreviated. With this in mind, I wrote a function which replaces the first two digits. It works when applying it to a vector, however, not when using it in ggplot. Any idea what I am missing? Many thanks.

PS I am aware of the scales package and its related functions for date/time scales. I have also seen this SO question.

library(tidyverse)

seq_year <- seq(1970, 2010, 10)
values <- seq(10, 50, 10)
df <- tibble(seq_year, values)

df %>%
ggplot() +
geom_bar(aes(x = seq_year, 
y=values),
stat="identity")+
scale_x_continuous(label=function(x) 
str_replace(x, regex("\\d{2}"), "'"))


fn_year_label  <- function(x){
y <- str_replace(x[2:length(x)], regex("^\\d{2}"), "'")
z <- c(x[1],y)
return(z)
}

#These are the axis labels I want to have.
fn_year_label(seq_year)
#> [1] "1970" "'80"  "'90"  "'00"  "'10"

#But the plot doesn't show them
df %>%
ggplot() +
geom_bar(aes(x = seq_year, 
y=values),
stat="identity")+
scale_x_continuous(label=fn_year_label)

Created on 2022-10-31 with reprex v2.0.2

Upvotes: 0

Views: 115

Answers (2)

Julian Selke
Julian Selke

Reputation: 298

Here is a solution in case you do not want to set the first value manually.

df %>%
  ggplot() +
  geom_bar(aes(x = seq_year, 
               y = values),
           stat="identity")+
  scale_x_continuous(label=function(x) 
    c(x[1:2], str_replace(x[3:length(x)], regex("\\d{2}"), "'")))

Upvotes: 1

Limey
Limey

Reputation: 12461

Change your label function to

    label=function(x) {
        print(x)
        x
    }

and you will see

[1]   NA 1970 1980 1990 2000 2010   NA

suggesting that

df %>%
  ggplot() +
  geom_bar(aes(x = seq_year, 
               y=values),
           stat="identity")+
  scale_x_continuous(
      label=function(x) {
      y <- str_replace(x, regex("^\\d{2}"), "'")
      y[2] <- "1970"
      y
    }
  )

Will give you what you want:

enter image description here

Upvotes: 2

Related Questions