Shiny app for data viz part 1

understanding the flow between inputs, variables and outputs
R
shiny
data visualization
Author

jk

Published

January 15, 2024

I’m hosting a shiny app written in R on a cloud server. Its purpose is to allow users to interactively visualize spatial gene expression data from fibrosing interstitial lung disease patients. Such interactivity is useful here because there are too many possible logical comparisons between groups than what can reasonably fit in a manuscript.

At one point, I was losing track of how inputs were being processed into intermediate/final outputs. I wrote down a pen and paper version before, but it’s gotten even more complicated than that.

Nextflow introduced me to mermaid flowcharts. I wrote down the following on the live editor:

flowchart
    input$anno_type_select -->|reactive| ROIs
    ROIs --> reactiveRun
    input$run --> |eventReactive| reactiveRun
    reactiveRun --> |renderUI| output$customization
    output$customization --> |reactive| pcaPlot
    reactiveRun --> |eventReactive| contrast
    contrast --> |reactive| efit
    input$lfc --> |reactive| lfc
    lfc --> |reactive| topTableDF
    efit --> |reactive| topTableDF
    contrast --> |reactive| topTableDF
    topTableDF --> |downloadHandler| output$downloadTable
    topTableDF --> |renderUI| output$table
    efit --> |reactive| volcano
    contrast --> |reactive| plotHeight
    plotHeight --> |reactive| volcano
    contrast --> |reactive| volcano
    reactiveRun --> |eventReactive| spe_ruv_subset
    spe_ruv_subset --> |eventReactive| pca_ruv_results_subset
    spe_ruv_subset --> |reactive| pcaPlot
    input$shapes_n --> |reactive| pcaPlot
    input$colours_n --> |reactive| pcaPlot
    pca_ruv_results_subset --> |reactive| pcaPlot
    pcaPlot --> |renderUI| output$pca
    pcaPlot --> |downloadHandler| output$downloadPCA 
    input$toggle_PCAcustom --> |observeEvent| toggle::PCAcustom
    toggle::PCAcustom --> |uiOutput| output$customization
    input$shapes_n --> |renderUI| output$customization
    input$colours_n --> |renderUI| output$customization
    input$toggle_customRange --> |observeEvent| toggle::show_customRange
    toggle::show_customRange --> |uiOutput| output$customRange
    input$customX --> |renderUI| output$customRange 
    input$customY --> |renderUI| output$customRange
    input$customX --> |reactive| customX
    input$customY --> |reactive| customY
    customY --> |reactive| volcano
    customX --> |reactive| volcano
    input$maxOverlap --> |reactive| maxOverlap
    maxOverlap --> |reactive| volcano
    volcano --> |reactive| volcanoPlots
    volcano --> |renderUI| output$volcanoUI
    volcanoPlots --> |downloadHandler| output$downloadVolcano
    input$top_n_genes --> |reactive| top_n_genes
    input$heatmap_col --> |reactive| heatmap_col
    input$heatmap_range --> |reactive| heatmap_range
    input$heatmap_size --> |reactive| heatmap_size
    input$heatmap_fontsize --> |reactive| heatmap_fontsize 
    reactiveRun --> |reactive| lcpm_subset_scale
    spe_ruv_subset --> |reactive| lcpm_subset_scale
    reactiveRun --> |reactive| colnames4heatmap
    spe_ruv_subset --> |reactive| colnames4heatmap
    colnames4heatmap --> |reactive| heatmap
    lcpm_subset_scale --> |reactive| lcpm_subset_scale_topGenes
    topTableDF --> |reactive| lcpm_subset_scale_topGenes
    top_n_genes --> |reactive| lcpm_subset_scale_topGenes
    heatmap_range --> |reactive| heatmap
    heatmap_col -->  |reactive| heatmap
    heatmap_fontsize -->  |reactive| heatmap
    heatmap_size --> |reactive| heatmap
    lcpm_subset_scale_topGenes -->  |reactive| heatmap
    heatmap --> |renderUI| output$heatmapUI
    lcpm_subset_scale_topGenes --> |downloadHandler| output$downloadHeatmap
    heatmap --> |downloadHandler| output$downloadHeatmap

flowchart
    input$anno_type_select -->|reactive| ROIs
    ROIs --> reactiveRun
    input$run --> |eventReactive| reactiveRun
    reactiveRun --> |renderUI| output$customization
    output$customization --> |reactive| pcaPlot
    reactiveRun --> |eventReactive| contrast
    contrast --> |reactive| efit
    input$lfc --> |reactive| lfc
    lfc --> |reactive| topTableDF
    efit --> |reactive| topTableDF
    contrast --> |reactive| topTableDF
    topTableDF --> |downloadHandler| output$downloadTable
    topTableDF --> |renderUI| output$table
    efit --> |reactive| volcano
    contrast --> |reactive| plotHeight
    plotHeight --> |reactive| volcano
    contrast --> |reactive| volcano
    reactiveRun --> |eventReactive| spe_ruv_subset
    spe_ruv_subset --> |eventReactive| pca_ruv_results_subset
    spe_ruv_subset --> |reactive| pcaPlot
    input$shapes_n --> |reactive| pcaPlot
    input$colours_n --> |reactive| pcaPlot
    pca_ruv_results_subset --> |reactive| pcaPlot
    pcaPlot --> |renderUI| output$pca
    pcaPlot --> |downloadHandler| output$downloadPCA 
    input$toggle_PCAcustom --> |observeEvent| toggle::PCAcustom
    toggle::PCAcustom --> |uiOutput| output$customization
    input$shapes_n --> |renderUI| output$customization
    input$colours_n --> |renderUI| output$customization
    input$toggle_customRange --> |observeEvent| toggle::show_customRange
    toggle::show_customRange --> |uiOutput| output$customRange
    input$customX --> |renderUI| output$customRange 
    input$customY --> |renderUI| output$customRange
    input$customX --> |reactive| customX
    input$customY --> |reactive| customY
    customY --> |reactive| volcano
    customX --> |reactive| volcano
    input$maxOverlap --> |reactive| maxOverlap
    maxOverlap --> |reactive| volcano
    volcano --> |reactive| volcanoPlots
    volcano --> |renderUI| output$volcanoUI
    volcanoPlots --> |downloadHandler| output$downloadVolcano
    input$top_n_genes --> |reactive| top_n_genes
    input$heatmap_col --> |reactive| heatmap_col
    input$heatmap_range --> |reactive| heatmap_range
    input$heatmap_size --> |reactive| heatmap_size
    input$heatmap_fontsize --> |reactive| heatmap_fontsize 
    reactiveRun --> |reactive| lcpm_subset_scale
    spe_ruv_subset --> |reactive| lcpm_subset_scale
    reactiveRun --> |reactive| colnames4heatmap
    spe_ruv_subset --> |reactive| colnames4heatmap
    colnames4heatmap --> |reactive| heatmap
    lcpm_subset_scale --> |reactive| lcpm_subset_scale_topGenes
    topTableDF --> |reactive| lcpm_subset_scale_topGenes
    top_n_genes --> |reactive| lcpm_subset_scale_topGenes
    heatmap_range --> |reactive| heatmap
    heatmap_col -->  |reactive| heatmap
    heatmap_fontsize -->  |reactive| heatmap
    heatmap_size --> |reactive| heatmap
    lcpm_subset_scale_topGenes -->  |reactive| heatmap
    heatmap --> |renderUI| output$heatmapUI
    lcpm_subset_scale_topGenes --> |downloadHandler| output$downloadHeatmap
    heatmap --> |downloadHandler| output$downloadHeatmap

Nodes represent input, data and/or output variables. Curves represent reactive expressions or rendering functions.

Some takeaways:

There are many other things that I could document about this app. Hosting it online for free through the Digital Alliance of Canada’s cloud was a bit of a journey. The how and why might be the topic for a part 2. In a part 3, I might document some cute tricks in R to process data with reactivity.

You can find the entire app’s code here. The raw and processed data underpinning the app are under embargo at this time.

\ (•◡•) /

Back to top