Notes

This figure contains data from different experiments that were used demonstrate the construction of untargeted and orthogonal double mutants with ORBIT. Data figures were made in R notebooks and exported as pdfs. Cosmetic improvements were made in Adobe Illustrator. Note that Fig. 5A, and 5D-E were made in Adobe Illustrator.


Setup packages and plotting for the notebook:

# Check packages
source("../tools/package_setup.R")
# Load packages
library(tidyverse)
library(cowplot)
library(kableExtra)
# Code display options
knitr::opts_chunk$set(tidy.opts=list(width.cutoff=60),tidy=FALSE, echo = TRUE, message=FALSE, warning=FALSE, fig.align="center", fig.retina = 2)
# Load plotting tools
source("../tools/plotting_tools.R")
#Modify the plot theme
theme_set(theme_notebook())

Fig. 5B - Orthogonal heatmap

Read in the data.

df_heatmap <- read_csv("../../data/low_throughput_experiments/2022_10_14_chlor_orth_2_data.csv") %>% mutate(eff = Chlor_count / LB_count)

df_heatmap %>% kable() %>% kable_styling() %>% scroll_box(height = '250px')
condition attB attP match LB_count Chlor_count eff
attB1_attP1 B1 P1 TRUE 2100000 2900 0.0013810
attB1_attP2 B1 P2 FALSE 2400000 220 0.0000917
attB1_attP3 B1 P3 FALSE 2200000 550 0.0002500
attB1_attP4 B1 P4 FALSE 1200000 3100 0.0025833
attB1_attP5 B1 P5 FALSE 1700000 280 0.0001647
attB1_attP6 B1 P6 FALSE 1700000 860 0.0005059
attB2_attP1 B2 P1 FALSE 1300000 60 0.0000462
attB2_attP2 B2 P2 TRUE 1400000 20000 0.0142857
attB2_attP3 B2 P3 FALSE 1600000 390 0.0002438
attB2_attP4 B2 P4 FALSE 1600000 4200 0.0026250
attB2_attP5 B2 P5 FALSE 1400000 310 0.0002214
attB2_attP6 B2 P6 FALSE 1200000 1400 0.0011667
attB3_attP1 B3 P1 FALSE 1400000 56 0.0000400
attB3_attP2 B3 P2 FALSE 1200000 370 0.0003083
attB3_attP3 B3 P3 TRUE 1600000 7400 0.0046250
attB3_attP4 B3 P4 FALSE 1830000 8400 0.0045902
attB3_attP5 B3 P5 FALSE 1300000 1190 0.0009154
attB3_attP6 B3 P6 FALSE 2400000 680 0.0002833
attB4_attP1 B4 P1 FALSE 1420000 63 0.0000444
attB4_attP2 B4 P2 FALSE 1900000 260 0.0001368
attB4_attP3 B4 P3 FALSE 1200000 610 0.0005083
attB4_attP4 B4 P4 TRUE 1600000 9900 0.0061875
attB4_attP5 B4 P5 FALSE 1900000 400 0.0002105
attB4_attP6 B4 P6 FALSE 1500000 1320 0.0008800
attB5_attP1 B5 P1 FALSE 1200000 53 0.0000442
attB5_attP2 B5 P2 FALSE 2000000 440 0.0002200
attB5_attP3 B5 P3 FALSE 1800000 1070 0.0005944
attB5_attP4 B5 P4 FALSE 1700000 1500 0.0008824
attB5_attP5 B5 P5 TRUE 1500000 8500 0.0056667
attB5_attP6 B5 P6 FALSE 1100000 1160 0.0010545
attB6_attP1 B6 P1 FALSE 1330000 88 0.0000662
attB6_attP2 B6 P2 FALSE 1700000 370 0.0002176
attB6_attP3 B6 P3 FALSE 1300000 340 0.0002615
attB6_attP4 B6 P4 FALSE 1300000 3900 0.0030000
attB6_attP5 B6 P5 FALSE 1600000 92 0.0000575
attB6_attP6 B6 P6 TRUE 1600000 9900 0.0061875

Now we can plot:

#Plot only the att sites that worked well. The full heatmap is shown in supplement.
plot_heatmap <- ggplot(df_heatmap %>% filter(attP!='P4' & attB != 'B4')%>% filter(attP!='P6' & attB != 'B6'), aes(x = attP, y = attB, fill = eff)) + 
  geom_tile(color = 'white', size = 0.25) + 
  geom_tile(data = . %>% filter(match == T), fill = NA, color = 'black', size = 0.5)+
  geom_text(aes(label = scales::label_percent(accuracy = 0.01)(eff)), size = 2.85)+
  scale_fill_viridis_c(trans = 'log',label = scales::percent_format(), breaks = c(0.005, 0.0005,0.00005)) + 
  labs(y = 'attB version\n(∆galK targeting oligo)' , x = 'attP version\n(pInt_chlorR)', fill = 'Efficiency')

plot_heatmap

Fig. 5C - Double Orbit efficiency

Let’s read in the data:

df_eff <- read_csv("../../data/low_throughput_experiments/2022_11_04_double_triple_orbit_att4_data.csv") 

df_eff %>% kable() %>% kable_styling() %>% scroll_box(height = '250px')
cuvette condition replicate LB_count Kan_count Chlor_count Kan_Chlor_count Carb_count Kan_Chlor_Amp_count
1 galKattB1_hisAattB1_chlorAttP1_kanAttP1 1 1.9e+07 21000 170000 134 NA NA
2 galKattB1_hisAattB1_chlorAttP1_kanAttP1 2 1.2e+07 17100 200000 75 NA NA
3 galKattB2_hisAattB1_chlorAttP2_kanAttP1 1 1.4e+07 6400 37000 61 NA NA
4 galKattB2_hisAattB1_chlorAttP2_kanAttP1 2 9.4e+06 19000 120000 280 NA NA
5 galKattB3_hisAattB1_chlorAttP3_kanAttP1 1 9.4e+07 19000 38000 112 NA NA
6 galKattB3_hisAattB1_chlorAttP3_kanAttP1 2 6.4e+06 18000 45000 90 NA NA
7 galKattB5_hisAattB1_chlorAttP5_kanAttP1 1 1.3e+07 28000 62000 160 NA NA
8 galKattB5_hisAattB1_chlorAttP5_kanAttP1 2 1.9e+07 20000 49000 100 NA NA
9 galK_hisA_metA100_kan_chlor_amp 1 1.3e+07 29000 150000 149 250000 250
10 galK_hisA_metA100_kan_chlor_amp 2 1.8e+07 34000 132000 130 300000 120
11 p265_Kan 1 1.3e+07 16000 NA NA NA NA
12 pInt_only_Kan_Chlor 2 8.2e+06 130 1500 0 NA NA

Next we can use the single mutant frequencies to calculate the expected double mutant frequencies. We will also get the averages for plotting:

df_eff_meta <- df_eff %>% 
  mutate(kan_eff = Kan_count / LB_count,
         chlor_eff = Chlor_count / LB_count,
         kan_chlor_eff = Kan_Chlor_count / LB_count) %>% 
  mutate(expected_freq =  kan_eff * chlor_eff) %>% 
  group_by(condition) %>% 
  mutate(avg_kan_chlor_eff = mean(kan_chlor_eff))
  
df_eff_meta %>% kable() %>% kable_styling() %>% scroll_box(height = '250px')
cuvette condition replicate LB_count Kan_count Chlor_count Kan_Chlor_count Carb_count Kan_Chlor_Amp_count kan_eff chlor_eff kan_chlor_eff expected_freq avg_kan_chlor_eff
1 galKattB1_hisAattB1_chlorAttP1_kanAttP1 1 1.9e+07 21000 170000 134 NA NA 0.0011053 0.0089474 7.10e-06 9.90e-06 6.70e-06
2 galKattB1_hisAattB1_chlorAttP1_kanAttP1 2 1.2e+07 17100 200000 75 NA NA 0.0014250 0.0166667 6.30e-06 2.38e-05 6.70e-06
3 galKattB2_hisAattB1_chlorAttP2_kanAttP1 1 1.4e+07 6400 37000 61 NA NA 0.0004571 0.0026429 4.40e-06 1.20e-06 1.71e-05
4 galKattB2_hisAattB1_chlorAttP2_kanAttP1 2 9.4e+06 19000 120000 280 NA NA 0.0020213 0.0127660 2.98e-05 2.58e-05 1.71e-05
5 galKattB3_hisAattB1_chlorAttP3_kanAttP1 1 9.4e+07 19000 38000 112 NA NA 0.0002021 0.0004043 1.20e-06 1.00e-07 7.60e-06
6 galKattB3_hisAattB1_chlorAttP3_kanAttP1 2 6.4e+06 18000 45000 90 NA NA 0.0028125 0.0070313 1.41e-05 1.98e-05 7.60e-06
7 galKattB5_hisAattB1_chlorAttP5_kanAttP1 1 1.3e+07 28000 62000 160 NA NA 0.0021538 0.0047692 1.23e-05 1.03e-05 8.80e-06
8 galKattB5_hisAattB1_chlorAttP5_kanAttP1 2 1.9e+07 20000 49000 100 NA NA 0.0010526 0.0025789 5.30e-06 2.70e-06 8.80e-06
9 galK_hisA_metA100_kan_chlor_amp 1 1.3e+07 29000 150000 149 250000 250 0.0022308 0.0115385 1.15e-05 2.57e-05 9.30e-06
10 galK_hisA_metA100_kan_chlor_amp 2 1.8e+07 34000 132000 130 300000 120 0.0018889 0.0073333 7.20e-06 1.39e-05 9.30e-06
11 p265_Kan 1 1.3e+07 16000 NA NA NA NA 0.0012308 NA NA NA NA
12 pInt_only_Kan_Chlor 2 8.2e+06 130 1500 0 NA NA 0.0000159 0.0001829 0.00e+00 0.00e+00 0.00e+00

Now we can plot everything:

#negative control value
pInt_only_expected <- (df_eff_meta %>% filter(condition == 'pInt_only_Kan_Chlor'))$expected_freq

#filter data to only plot double mutants (single mutant was done as control, triple mutant was also attempted)
plot_eff <- ggplot(df_eff_meta %>% filter(condition != 'galK_hisA_metA100_kan_chlor_amp' & condition != 'p265_Kan' & condition != 'pInt_only_Kan_Chlor'),
       aes(x = condition, y = kan_chlor_eff , group = factor(replicate))) + 
  geom_hline(yintercept = pInt_only_expected, linetype = 2, color = 'light gray')+
  geom_linerange(aes(x = condition, ymin = expected_freq, ymax = kan_chlor_eff), position = position_dodge(width = 0.5), color = 'light gray', linetype = 3)+
   geom_point(aes(y = expected_freq), shape = 4, position = position_dodge(width = 0.5),color = 'light gray')+ #expected frequency as X
   geom_point(shape = 21, position = position_dodge(width = 0.5), fill = 'white',color = 'light gray') + #observed frequency as open circle
  geom_point(data = . %>% filter(replicate == 1), aes(y = avg_kan_chlor_eff), size = 2)+
  scale_y_log10(labels = scales::label_log())+
  scale_x_discrete(labels = c('B1-P1\nB1-P1','B2-P2\nB1-P1','B3-P3\nB1-P1','B5-P5\nB1-P1'))+
  labs(x = '∆galK∆hisA att site composition',y = 'kanR / chlorR efficiency')

plot_eff

Create Fig. 5

theme_set(theme_figure())


fig_5_multi <- plot_grid(plot_heatmap + guides(fill = 'none'), plot_eff, ncol = 1,
                   align = 'hv', axis = 'lr', scale = 1,
                   labels = c('B','C'))


fig_5_multi

save_plot("../../figures/r_pdf_figs/main_figs/fig_5_multi.pdf", fig_5_multi, base_width = 2.5, base_height = 5)
sessionInfo()
## R version 4.2.0 (2022-04-22)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Big Sur/Monterey 10.16
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] kableExtra_1.3.4  cowplot_1.1.1     viridis_0.6.2     viridisLite_0.4.1
##  [5] knitr_1.41        forcats_0.5.2     stringr_1.5.0     dplyr_1.1.0      
##  [9] purrr_0.3.5       readr_2.1.3       tidyr_1.2.1       tibble_3.1.8     
## [13] ggplot2_3.4.0     tidyverse_1.3.2  
## 
## loaded via a namespace (and not attached):
##  [1] httr_1.4.4          sass_0.4.4          bit64_4.0.5        
##  [4] vroom_1.6.0         jsonlite_1.8.3      modelr_0.1.10      
##  [7] bslib_0.4.1         assertthat_0.2.1    highr_0.9          
## [10] googlesheets4_1.0.1 cellranger_1.1.0    yaml_2.3.6         
## [13] pillar_1.8.1        backports_1.4.1     glue_1.6.2         
## [16] digest_0.6.30       rvest_1.0.3         colorspace_2.0-3   
## [19] htmltools_0.5.4     pkgconfig_2.0.3     broom_1.0.1        
## [22] haven_2.5.1         scales_1.2.1        webshot_0.5.4      
## [25] svglite_2.1.0       tzdb_0.3.0          timechange_0.1.1   
## [28] googledrive_2.0.0   generics_0.1.3      farver_2.1.1       
## [31] ellipsis_0.3.2      cachem_1.0.6        withr_2.5.0        
## [34] cli_3.4.1           magrittr_2.0.3      crayon_1.5.2       
## [37] readxl_1.4.1        evaluate_0.18       fs_1.5.2           
## [40] fansi_1.0.3         xml2_1.3.3          textshaping_0.3.6  
## [43] tools_4.2.0         hms_1.1.2           gargle_1.2.1       
## [46] lifecycle_1.0.3     munsell_0.5.0       reprex_2.0.2       
## [49] compiler_4.2.0      jquerylib_0.1.4     systemfonts_1.0.4  
## [52] rlang_1.0.6         grid_4.2.0          rstudioapi_0.14    
## [55] labeling_0.4.2      rmarkdown_2.18      gtable_0.3.1       
## [58] DBI_1.1.3           R6_2.5.1            gridExtra_2.3      
## [61] lubridate_1.9.0     fastmap_1.1.0       bit_4.0.5          
## [64] utf8_1.2.2          ragg_1.2.5          stringi_1.7.8      
## [67] parallel_4.2.0      vctrs_0.5.2         dbplyr_2.2.1       
## [70] tidyselect_1.2.0    xfun_0.35