0

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

JeffCJ
  • 15
  • 4
  • Try `facet_wrap`. Post a [mcve] if you would like more specific help - it's not possible to reproduce your results with the code you have posted. – andrew_reece Sep 20 '20 at 16:14
  • 1
    `facet_wrap` would do it, but it would be more work than just using `coord_cartesian()` for both plots – Matt74 Sep 20 '20 at 16:21
  • @andrew_reece I think it's more understandable now – JeffCJ Sep 20 '20 at 16:25
  • Yes, that's better - but please post `dput` output so it's easy to copy and paste. E.g. `dput(x[1:10,c('Var1','Freq')])`. – andrew_reece Sep 20 '20 at 16:27

2 Answers2

1

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.

Oliver
  • 8,169
  • 3
  • 15
  • 37
  • This is the right answer as I've already tried the patchwork package and didn't have any success, thanks! – JeffCJ Sep 20 '20 at 20:48
  • Glad i could help. It also taught me a bit that I didn't already know before creating the answer. :-) – Oliver Sep 20 '20 at 20:57
  • would it be possible to customise the x axis breaks, like show the first day of the month? I tried it on the plots using scale_x_date but it won't work @Oliver – JeffCJ Sep 20 '20 at 21:02
  • 1
    Adding `& scale_x_date(breaks = as.Date('2020-02-01') + months(seq(0, 11, 3)))` to the plot above. works for me. – Oliver Sep 20 '20 at 21:07
0

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")
Duck
  • 39,058
  • 13
  • 42
  • 84