Maaslin3 output linear association plots blank

Hi everyone,

I am currently using Maaslin3 tool to perform a DA analysis to determine associations between Oxygen concentrations in oil amended cultures using the following parameters:

fit_out <- maaslin3(input_data = seqtab.nochim,
                    input_metadata = sample_data[sample_data$Treatment == "Amended",],
                    output = "Amended_only",
                    formula = "~ Oxygen + time_point + (1|replicate)",
                    normalization = "TSS",
                    transform = "LOG",
                    augment = TRUE,
                    standardize = TRUE,
                    small_random_effects = TRUE,
                    reference = ("Oxygen,Ox;time_point,T1"),
                    max_significance = 0.1,
                    median_comparison_abundance = TRUE,
                    median_comparison_prevalence = FALSE,
                    max_pngs = 25)

I used small_random_effects= true due to I only have 3 replicates per condition at each time point. Maaslin3 ran without any error and generated a summary plot:

However, Maaslin3 created blank linear association plots for both Oxygen and time_point effects but logistic plots were correctly created.

Here is the sessionInfo() as a reference:

> sessionInfo()
R version 4.5.3 (2026-03-11)
Platform: x86_64-conda-linux-gnu
Running under: Fedora Linux 41 (Container Image)

Matrix products: default
BLAS/LAPACK: /home/franciscodaniel.davi/software/miniconda3/envs/maaslin3/lib/libopenblasp-r0.3.33.so;  LAPACK version 3.12.0

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
 [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
 [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
[10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

time zone: America/Edmonton
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] tibble_3.3.1   maaslin3_1.2.0 stringr_1.6.0  dplyr_1.2.1   

loaded via a namespace (and not attached):
 [1] yulab.utils_0.2.4               rappdirs_0.3.4                 
 [3] tidyr_1.3.2                     generics_0.1.4                 
 [5] SparseArray_1.10.8              stringi_1.8.7                  
 [7] lattice_0.22-9                  digest_0.6.39                  
 [9] magrittr_2.0.5                  grid_4.5.3                     
[11] jsonlite_2.0.0                  plyr_1.8.9                     
[13] Matrix_1.7-5                    ape_5.8-1                      
[15] optparse_1.8.2                  survival_3.8-6                 
[17] purrr_1.2.2                     SingleCellExperiment_1.32.0    
[19] Biostrings_2.78.0               codetools_0.2-20               
[21] lazyeval_0.2.3                  abind_1.4-8                    
[23] cli_3.6.6                       rlang_1.2.0                    
[25] crayon_1.5.3                    XVector_0.50.0                 
[27] Biobase_2.70.0                  tidytree_0.4.8                 
[29] splines_4.5.3                   DelayedArray_0.36.0            
[31] S4Arrays_1.10.1                 tools_4.5.3                    
[33] parallel_4.5.3                  BiocParallel_1.44.0            
[35] SummarizedExperiment_1.40.0     BiocGenerics_0.56.0            
[37] vctrs_0.7.3                     R6_2.6.1                       
[39] matrixStats_1.5.0               stats4_4.5.3                   
[41] lifecycle_1.0.5                 Seqinfo_1.0.0                  
[43] fs_2.1.0                        S4Vectors_0.48.0               
[45] IRanges_2.44.0                  treeio_1.34.0                  
[47] pkgconfig_2.0.3                 TreeSummarizedExperiment_2.18.0
[49] pillar_1.11.1                   glue_1.8.1                     
[51] Rcpp_1.1.1-1.1                  GenomicRanges_1.62.1           
[53] tidyselect_1.2.1                MatrixGenerics_1.22.0          
[55] nlme_3.1-169                    compiler_4.5.3    

Could you please help me to find what the problem is?

Thank you very much for such a great tool and looking forward to hearing from you.

Best,

Daniel

Hi Daniel,

If you look at the results table, how many samples had non-zero abundances for those taxa where you had blank linear association plots? Or did you get blank oxygen/time_point plots for all the taxa?

If they’re all blank, would it be possible to send me a chunk of the data that reproduces the problem either here or at willnickols@g.harvard.edu? It’s probably easier for me to debug on my end and report back.

Will

Hi Will,

Thanks for your prompt response.

All the oxygen/time_point plots are blank. Here is a chunk of the data that reproduces the problem:

asv_table.csv (2.1 MB)

full_metadata.csv (1.8 KB)

Thanks for your help and let me know if you need any further information.

Best,

Daniel

Hi Will,

Another question that I have is how to interpret the summary plot. For instance, is it correct if I interpret that ASV13 is associated with prevalence under control conditions? Is it also correct that ASV13 is significantly associated with T2 abundance regardless of the oxygen condition?
I am having a hard time fully understanding this plot. Thank you very much for all your help.
Best,
Daniel

Hi Daniel,

I fixed an issue with factorization after the metadata standardization step, so the plots should work now if you re-install MaAsLin 3 from:

devtools::install_github("biobakery/maaslin3")

Regarding the summary plot, based on the Oxygen Anox pane, I would say that, controlling for time, ASV13 prevalence is lower in Anox than Ox (the reference). I would also say that it is negatively associated with time point T2 relative to T1 (the reference), controlling for oxygen condition.

Will

1 Like

Thank you so much for your help, Will.

I will re-install MaAsLin3 and let you know if I am able to generate the plots.

Thank you for the explanation, that makes totally sense. I am wondering how should I modify the formula to ask for associations of Oxygen conditions across the time points? Should interaction ~ Oxygen * time_points + (1|replicate) would do the work?

Best,

Daniel

Yes, the interaction term would tell you the differences between the abundance/prevalence for each oxygen condition at each time point.

1 Like

Hi Will,

After the installation, MaAsLin3 generate the linear association plot. Thank you for your help.

However, I would like to kindly ask you another question regarding the summary plot of the interaction formula ~ Oxygen * time_points + (1|replicate). Here is the summary plot:

For instance, ASV151 is significantly associated with Hypox conditions compared to the reference (Ox conditions). However, if I compare this result with the summary plot from the previous formula ~ Oxygen + time_points + (1|replicate) (first posted summary plot in this thread), ASV151 displays different association results. Could you help me to better understand why I see this difference between these two analyses?

Thanks a lot for your help.

Daniel

Hi Daniel,

The difference between these two for the Hypox condition is how the various time points are being treated. In the additive model originally, the Hypox coefficient is (roughly speaking) averaged over the timepoints. That is, the coefficient answers the question: if I assert that Hypox (relative to Ox) has the same association regardless of the time point, what is the association wth Hypox? By contrast, in the interaction model, you’re allowing the Hypox coefficient to change across the different times, and the baseline Hypox coefficient is the association with Hypox only at the reference time point. That is, the coefficient answers the question: looking only at the reference time point, what is the association with Hypox? Then, the other interaction terms like Hypox:time_pointT5 tell you how much different the association with Hypox is at each other time relative to at the reference time.

Will

1 Like