Home > Software engineering >  Align geom_point data with geom_col data when combining with patchwork
Align geom_point data with geom_col data when combining with patchwork

Time:10-21

I am working to create two graphics and merging them into a single graphic using patchwork. The x-axis are dates and the top graph is a geom_line/geom_point graph and the bottom graph is created using geom_col. When combined, I'd like to have the points in the top graphic align with the center of columns in the bottom graphic.

I was hoping that b/c the x-axis spans the same dates, the points would align with the center of columns. In several attempts, I was unable to center the dots above the column. The resulting graphic (and the code) is below.

The dots are not centered on the column

library(patchwork)


nn<-15
p1data = tibble(date=ymd('2021-01-01')   days(0:(nn-1)), values=floor(runif(nn, 5.0, 75)))

p2data <- tibble(initdate = ymd('2021-01-01') days(0:(nn-1)), data=runif(nn,4,10))

# set up a tibble to shade in every other day
shade <- tibble(min=ymd('2021-01-01 00:00') days(0:20),max=lead(min))
# Remove every other row
toDelete <- seq(1,dim(shade)[1],by=2)
shade <- shade[-toDelete,]

plot_limits = c(ymd('2021-01-01'),ymd('2021-01-16'))

# Orginal Attempt 
p1 <- p1data %>% 
  ggplot()   
  geom_rect(data=shade, aes(xmin=min,xmax=max,ymin=-Inf,ymax=Inf),fill='grey80' )   
  geom_line(aes(x=date,y=values))   
  geom_point(aes(x=date,y=values),color='red',size=3)  
  scale_x_date(expand=c(0,0),
                   date_breaks = '1 days',
                   date_labels = '%b-%d',
                   limits=plot_limits)  
  labs(title='two plots combined')   
  theme_bw()   
  theme(plot.title=element_text(hjust=0.5), 
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.title.x=element_blank())
  

p2 <- p2data %>%  
  ggplot()   
  geom_col(aes(x=initdate,y=data, fill=data))   
  scale_x_date(expand=c(0,0),date_breaks = '1 days',date_labels = '%b-%d')  
  theme_bw()   
  theme(plot.title=element_blank(),
        axis.title.x=element_blank(),
        axis.text.x=element_text(angle=0),
        legend.direction = "horizontal", 
        legend.position = "bottom",
        legend.key.width=unit(1.25,"cm"),
        legend.key.height=unit(.25,"cm"),
        legend.box = "vertical",
        legend.box.background = element_blank(),
        legend.title = element_text(face = "bold"),
        legend.spacing = unit(1,"cm"),
        legend.justification = "center",
        legend.margin = margin(0.,0.,0.,0., unit="cm"),
        legend.background = element_blank(),
        plot.margin = margin(0, 0, 0, 0, "cm")
  )

p1/p2

Are there other ways to achieve center the dots for each day in the top graph with the column in the bottom graph?

CodePudding user response:

While working to prepare this question, I was able to develop a solution. The solution is to use datetime formats for the top graphic instead of just date. The datetimes associated with the data can then be set to YYYY-MM-DD 12:00. The data is then plotted in the middle of the day rather than at the start of each day.

The resulting graphic is: enter image description here

And the code that achieves it is:

# The solution that works
# Specify the dates in datetime format and use the hours to center the data in the day. 

# The shade data for daily shades must be in datetime asd well.
# set up a tibble to shade in every other day
shade_dtm <- tibble(min=ymd_hm('2021-01-01 00:00') days(0:20),max=as_datetime(lead(min)))
# Remove every other row
toDelete <- seq(1,dim(shade_dtm)[1],by=2)
shade_dtm <- shade_dtm[-toDelete,]

# create data
p1data_dtm = tibble(date=ymd_hm('2021-01-01 12:00')   days(0:(nn-1)), values=floor(runif(nn, 5.0, 75)))

plot_limits_dtm = c(ymd_hm('2021-01-01 00:00'),ymd_hm('2021-01-16 00:00'))

p1 <- p1data_dtm %>% 
      ggplot()   
      geom_rect(data=shade_dtm, aes(xmin=min,xmax=max,ymin=-Inf,ymax=Inf),fill='grey80' )   
      geom_line(aes(x=date,y=values))   
      geom_point(aes(x=date,y=values),color='red',size=3)  
      scale_x_datetime(expand=c(0,0),
                       date_breaks = '1 days',
                       date_labels = '%b-%d',
                       limits=plot_limits_dtm)  
      labs(title='two plots combined: data aligned')   
      theme_bw()   
      theme(plot.title=element_text(hjust=0.5), 
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.title.x=element_blank())


p2 <- p2data %>%  
      ggplot()   
      geom_col(aes(x=initdate,y=data, fill=data))   
      scale_x_date(expand=c(0,0),date_breaks = '1 days',date_labels = '%b-%d')  
      theme_bw()   
      theme(plot.title=element_blank(),
        axis.title.x=element_blank(),
        axis.text.x=element_text(angle=0),
        legend.direction = "horizontal", 
        legend.position = "bottom",
        legend.key.width=unit(1.25,"cm"),
        legend.key.height=unit(.25,"cm"),
        legend.box = "vertical",
        legend.box.background = element_blank(),
        legend.title = element_text(face = "bold"),
        legend.spacing = unit(1,"cm"),
        legend.justification = "center",
        legend.margin = margin(0.,0.,0.,0., unit="cm"),
        legend.background = element_blank(),
        plot.margin = margin(0, 0, 0, 0, "cm")
  )

p1/p2
  • Related