JeffCJ
JeffCJ

Reputation: 15

Align time series ggplot

I need to align the x axes on these plots, I think if I could change the width so they had the same width would work but I haven't been able to do it. misaligned plots

my data looks like this:

> x<-as.data.frame(table(casosbog$fis))
> dput(x[1:10,c('Var1','Freq')])
structure(list(Var1 = structure(1:10, .Label = c("2020-02-27", 
"2020-02-28", "2020-03-01", "2020-03-04", "2020-03-05", "2020-03-06", 
"2020-03-07", "2020-03-08", "2020-03-09", "2020-03-10", "2020-03-11", 
"2020-03-12", "2020-03-13", "2020-03-14", "2020-03-15", "2020-03-16", 
"2020-03-17", "2020-03-18", "2020-03-19", "2020-03-20", "2020-03-21", 
"2020-03-22", "2020-03-23", "2020-03-24", "2020-03-25", "2020-03-26", 
"2020-03-27", "2020-03-28", "2020-03-29", "2020-03-30", "2020-03-31", 
"2020-04-01", "2020-04-02", "2020-04-03", "2020-04-04", "2020-04-05", 
"2020-04-06", "2020-04-07", "2020-04-08", "2020-04-09", "2020-04-10", 
"2020-04-11", "2020-04-12", "2020-04-13", "2020-04-14", "2020-04-15", 
"2020-04-16", "2020-04-17", "2020-04-18", "2020-04-19", "2020-04-20", 
"2020-04-21", "2020-04-22", "2020-04-23", "2020-04-24", "2020-04-25", 
"2020-04-26", "2020-04-27", "2020-04-28", "2020-04-29", "2020-04-30", 
"2020-05-01", "2020-05-02", "2020-05-03", "2020-05-04", "2020-05-05", 
"2020-05-06", "2020-05-07", "2020-05-08", "2020-05-09", "2020-05-10", 
"2020-05-11", "2020-05-12", "2020-05-13", "2020-05-14", "2020-05-15", 
"2020-05-16", "2020-05-17", "2020-05-18", "2020-05-19", "2020-05-20", 
"2020-05-21", "2020-05-22", "2020-05-23", "2020-05-24", "2020-05-25", 
"2020-05-26", "2020-05-27", "2020-05-28", "2020-05-29", "2020-05-30", 
"2020-05-31", "2020-06-01", "2020-06-02", "2020-06-03", "2020-06-04", 
"2020-06-05", "2020-06-06", "2020-06-07", "2020-06-08", "2020-06-09", 
"2020-06-10", "2020-06-11", "2020-06-12", "2020-06-13", "2020-06-14", 
"2020-06-15", "2020-06-16", "2020-06-17", "2020-06-18", "2020-06-19", 
"2020-06-20", "2020-06-21", "2020-06-22", "2020-06-23", "2020-06-24", 
"2020-06-25", "2020-06-26", "2020-06-27", "2020-06-28", "2020-06-29", 
"2020-06-30", "2020-07-01", "2020-07-02", "2020-07-03", "2020-07-04", 
"2020-07-05", "2020-07-06", "2020-07-07", "2020-07-08", "2020-07-09", 
"2020-07-10", "2020-07-11", "2020-07-12", "2020-07-13", "2020-07-14", 
"2020-07-15", "2020-07-16", "2020-07-17", "2020-07-18", "2020-07-19", 
"2020-07-20", "2020-07-21", "2020-07-22", "2020-07-23", "2020-07-24", 
"2020-07-25", "2020-07-26", "2020-07-27", "2020-07-28", "2020-07-29", 
"2020-07-30", "2020-07-31", "2020-08-01", "2020-08-02", "2020-08-03", 
"2020-08-04", "2020-08-05", "2020-08-06", "2020-08-07", "2020-08-08", 
"2020-08-09", "2020-08-10", "2020-08-11", "2020-08-12", "2020-08-13", 
"2020-08-14", "2020-08-15", "2020-08-16", "2020-08-17", "2020-08-18", 
"2020-08-19", "2020-08-20", "2020-08-21", "2020-08-22", "2020-08-23", 
"2020-08-24", "2020-08-25", "2020-08-26", "2020-08-27", "2020-08-28", 
"2020-08-29", "2020-08-30", "2020-08-31", "2020-09-01", "2020-09-02", 
"2020-09-03", "2020-09-04", "2020-09-05", "2020-09-06", "2020-09-07", 
"2020-09-08", "2020-09-09", "2020-09-10", "2020-09-11", "2020-09-12", 
"2020-09-13", "2020-09-14", "2020-09-15", "2020-09-16", "2020-09-17"
), class = "factor"), Freq = c(1L, 1L, 3L, 1L, 5L, 6L, 10L, 5L, 
5L, 11L)), row.names = c(NA, 10L), class = "data.frame")

and

> movilcolbog[1:10,c('date','MovilidadProm')]
         date MovilidadProm
1  2020-02-15     7.0000000
2  2020-02-16     4.6666667
3  2020-02-17     5.3333333
4  2020-02-18     7.5000000
5  2020-02-19     2.6666667
6  2020-02-20    -0.3333333
7  2020-02-21     5.0000000
8  2020-02-22     1.8333333
9  2020-02-23    -7.3333333
10 2020-02-24     3.5000000

as you can see both dataframes have different starting dates and dates frequencies, the rest of the code is as follows

library(ggplot2)
library(gridExtra)

plot2<-ggplot(movilcolbaq,aes(date,MovilidadProm))+geom_line(aes(color="Mov.  BAQ"),size=1)+
  geom_line(data=movilcolbog,aes(color="Mov.  BOG"),size=1)+
  labs(color="Legend text")+
labs(title='Movilidad promedio (con respecto a enero-febrero) BOG, BAQ',x='',y='Cambio de movilidad en %')+
      theme(legend.title=element_blank())

plot1<-ggplot(casosbog,aes(x=fis,fill='Casos Bog'))+geom_bar()+
geom_bar(data=casosbar,aes(x=fis,fill='Casos Bar'),alpha=0.7)+
  scale_colour_manual("", values = c("Casos Bog"="red", "Casos Baq"="blue"))+
  theme(legend.title=element_blank())+labs(x='Fecha de inicio de síntomas',
                                            y='Casos',
                                            title='Fecha de inicio síntomas BAQ vs BOG vs MED',
                                           subtitle='Fuentes: INS y www.google.com/covid19/mobility/')

grid.arrange(plot1,plot2)

I've tried changing the xlim but it hasn't worked

Upvotes: 0

Views: 795

Answers (2)

Oliver
Oliver

Reputation: 8602

It can become quite tedious to align plots with ggplot2 and it can seem that alot of manual work is necessary. But using this answer and assuming you are using ggplot2>=3.1.0 we can actually achieve this very easily with patchwork.

The core of my solution is that the scales (and limits) of a plot can be extracted from any plot from the object returned by layer_scales(ggplot). In this object we have the scales of each axis within the x and y fields which each contain a range object with a range field. In total we can extract the x axis of a plot using layer_scales(ggplot)$x$range$range. Below I'll use a dummy dataset to illustrate how we can achieve the alignment

# Setup
set.seed(1)
library(lubridate)
library(ggplot2)
library(patchwork)
library(purrr)
library(dplyr)
d1 <- data.frame(y = rnorm(10), date = as.Date('2020-01-01') + months(1:10))
d2 <- data.frame(y = rnorm(10), date = as.Date('2020-03-01') + months(1:10))
p1 <- ggplot(d1, aes(y = y, x = date)) + geom_point() + geom_line()
p2 <- ggplot(d2, aes(y = y, x = date)) + geom_point() + geom_line()
# Solution
## Extract scales
scales <- lapply(list(p1, p2), layer_scales)

## Find range from layer_scales object. It is contained in obj$x$range$range
xlim <- map(scales,~ as.numeric(.x$x$range$range)) %>%
  unlist() %>%
  range()

## Add scales. Note that scales were numeric, so here I convert them back to dates.
## origin = '1970-01-01' is the standard origin for almost all programming languages.
p1 / p2 & coord_cartesian(xlim = as.Date(xlim, origin = '1970-01-01'))

aligned-ggplot Note that in the code snippet above I used the patchwork & operator to apply the coord to each plot.

Upvotes: 1

Duck
Duck

Reputation: 39613

I would suggest you to use patchwork as this package has the feature to align the labels in the multiple plots that are combined. You have multiple data sources so a facet_wrap() approach could not work. Also the data you shared is very small. As @andrew_reece said, next time share data with a considerable size. I have used the data you shared to create similar plots like those you included. Here the code:

library(ggplot2)
library(patchwork)
#Code
plot2<-ggplot(movilcolbog,aes(date,MovilidadProm))+geom_line(aes(color="Mov.  BAQ"),size=1)+
  geom_line(data=movilcolbog,aes(color="Mov.  BOG"),size=1)+
  labs(color="Legend text")+labs(title='Movilidad promedio (con respecto a enero-febrero) BOG, BAQ',x='',y='Cambio de movilidad en %')+
  theme(legend.title=element_blank())

plot1<-ggplot(x,aes(x=Var1,fill=Freq))+geom_bar()+
  # geom_bar(data=casosbar,aes(x=fis,fill='Casos Bar'),alpha=0.7)+
  scale_colour_manual("", values = c("Casos Bog"="red", "Casos Baq"="blue"))+
  theme(legend.title=element_blank())+labs(x='Fecha de inicio de síntomas',
                                           y='Casos',
                                           title='Fecha de inicio síntomas BAQ vs BOG vs MED',
                                           subtitle='Fuentes: INS y www.google.com/covid19/mobility/')
#Final plot
Fplot <- plot2/plot1

Output:

enter image description here

You can further tune up your axis labels and patchwork will align them. And as seen in plot even with different labels the package align those with are present at same level.

Some data used:

#Data 1
x <- structure(list(Var1 = structure(c(18319, 18320, 18322, 18325, 
18326, 18327, 18328, 18329, 18330, 18331), class = "Date"), Freq = c(1L, 
1L, 3L, 1L, 5L, 6L, 10L, 5L, 5L, 11L)), row.names = c("1", "2", 
"3", "4", "5", "6", "7", "8", "9", "10"), class = "data.frame")

#Data 2
movilcolbog <- structure(list(date = structure(c(18307, 18308, 18309, 18310, 
18311, 18312, 18313, 18314, 18315, 18316), class = "Date"), MovilidadProm = c(7, 
4.6666667, 5.3333333, 7.5, 2.6666667, -0.3333333, 5, 1.8333333, 
-7.3333333, 3.5)), row.names = c("1", "2", "3", "4", "5", "6", 
"7", "8", "9", "10"), class = "data.frame")

Upvotes: 0

Related Questions