Search code examples
rggplot2plotx-axis

Can we make the ticks width non linear in ggplot2?


I am trying to plot the US yield curve on a graph but I would like the ticks of the x-axis to be nearer until 1 year, then normal. I have not found how to solve it. Does anyone know?

My data set is :

Interest February August
1 Mo 2.186 0.035
3 Mo 2.626 0.279
6 Mo 3.128 0.590
1 Y 3.290 0.900
2 Y 3.214 1.368
3 Y 3.149 1.631
5 Y 2.923 1.824
10 Y 2.864 1.924
20 Y 2.774 2.323
30 Y 2.999 2.253

I have a graph so with the following code:


a$level_order <- factor(a$Interest, c('1 Mo', '3 Mo', '6 Mo','1 Y','2 Y','3 Y', '5 Y','7 Y', '10 Y', '20 Y', '30 Y'))
ggplot(a, aes(x=level_order,y=August,group=1))+
  geom_line(color="darkred")+
  geom_point(color="darkred")+
  geom_point(aes(y=February),color="darkblue")+
  geom_line(aes(y=February),color="darkblue")+

  theme_bw()

I would like to reduce the width between 1 month and 1 year

What I would like to get look like it ( a steeper slope before 1 Year) with 1 Mo 3 Mo 6 Mo pretty near.

What I would like to achieve


Solution

  • The problem is you are using as x-axis a list of factors and ggplot take them as discrete data, plotting them with equal distance.

    1. You can use scale_x_discrete() and manually write every break and every label for each break which is a bit tedious and you have to re-adapt it if you add new rows.

    2. You can create a new numeric -continuous- column from your character/factor column Interest with the same magnitude and then use scale_x_continuous().

    Example:

    example = data.frame(
      Interest = c('1 Mo', '2 Mo', '6 Mo', '1 Y', '2 Y', '5 Y'), 
      February = c(2.186,2.626,3.128,3.290,3.214,2.923),
      August = c(0.035,0.279,0.590,0.900,1.368,1.824)
    )
    
    library(dplyr)
     
    example %>% # use extract() to quickly split numbers and letters
      extract(Interest, into=c("Num", "time"), "([0-9]*)(.*)") %>% 
      mutate(Num = as.numeric(Num),
             Year_period = ifelse(time == " Mo", Num/12, Num)) %>% # change months magnitude to years
      
      ggplot(aes(x=Year_period,y=August,group=1))+
      geom_line(color="darkred")+
      geom_point(color="darkred")+
      geom_point(aes(y=February),color="darkblue")+
      geom_line(aes(y=February),color="darkblue")+
      scale_x_continuous(name="Years",breaks = seq(1,5,1), labels = str_c(seq(1,5,1),"Y"))+ # Here you re-scale the x-axis
      theme_bw()
    

    Within scale_x_continuous(), breaks= says where to tick the labels, giving an array of integers for the years, labels=str_c(seq(1,5,1),"Y")) is creating the names for each tick. Because all "Mo" rows are divided by 12, so < 1, now the x-axis is transformer to represent years.

    Output. Note I haven't use the whole data. Adapt breaks and labels for all your rows (if your max year is '30Y' then breaks = seq(1,30,1) and labels=str_c(seq(1,30,1),"Y")). Now the first values ('Mo') are closer and < '1Y' .

    enter image description here