CFU Plot Studio is an R Shiny app for publication-ready colony forming unit figures, replicate-level statistics, quality control checks, and reproducible figure export.
It was built for lab workflows where CFU counts are measured across strains, vectors, plasmids, treatments, timepoints, and replicate plates. The goal is simple: upload replicate-level data, make a clean figure, run transparent statistics, export the graph, and keep enough metadata to reproduce the result later.
Repository: mbaffour/cfu-plot-studio
Release: v0.1.0
Bug reports: open a GitHub issue
log10(CFU): Welch, Student, Wilcoxon, or model-based marginal means, with BH, Holm or Bonferroni correction — reporting confidence intervals, fold-change intervals and effect sizes, not just p values.The app connects data import, column mapping, quality checks, statistics, plot styling, and export in one workflow.
CFU Plot Studio is an R Shiny app. It runs on your machine — nothing is uploaded, and no data leaves your computer. There is no hosted version to click into, because the whole point is that your unpublished counts stay local.
Windows and macOS builds: https://cran.r-project.org/. Nothing else is required — the launcher installs the R packages for you, into a private folder beside the app.
Or clone it, if you would rather pull updates later:
git clone https://github.com/mbaffour/cfu-plot-studio.git
Windows — double-click Run CFU Plot Studio.bat. It finds R, installs anything
missing into a private .Rlibrary folder beside the app, picks a free port, and opens
your browser. Close the console window to stop it. The first run installs packages and
takes a few minutes; later runs start in seconds.
If R is installed somewhere unusual, point the launcher at it:
setx CFU_RSCRIPT "C:\Program Files\R\R-4.5.0\bin\Rscript.exe"
macOS or Linux — from the app folder:
Rscript run_app.R
run_app.R does the same dependency check and port selection, and works from any working
directory.
| Variable | Default | Purpose |
|---|---|---|
CFU_RSCRIPT |
auto-detected | Which Rscript.exe the Windows launcher uses |
CFU_APP_HOST |
127.0.0.1 |
Bind address |
CFU_APP_PORT |
first free from 4267 | Fixed port |
CFU_APP_LIB |
<app>/.Rlibrary |
Where missing packages are installed |
CFU_NO_INSTALL |
unset | Set to 1 to fail rather than install anything |
Click Load dummy example data in the sidebar, or Download dummy/template CSV to see the expected layout. The bundled dataset is synthetic, so you can learn the tool — or file a reproducible bug report — without touching unpublished results.
The launchers do this for you. If you would rather:
install.packages(c(
"shiny", "ggplot2", "dplyr", "readr", "tibble", "tidyr", "scales",
"emmeans", "broom", "DT", "colourpicker", "jsonlite", "zip"
))
Optional, each affecting only the export format named:
install.packages(c(
"officer", # PowerPoint export
"rvg", # editable vector art inside PowerPoint
"gganimate", # animated GIF export
"gifski" # GIF encoding
))
The app reports at startup which of these are absent, and what each one costs you.
Rscript tests/test_end_to_end.R # optionally: ... path/to/your.csv
Point it at your own CSV to run the whole pipeline against your data. The other suites —
test_bundle.R, test_panel_size.R, test_survival.R, test_statistics.R,
test_column_matching.R — check the figure geometry, the paired survival readout, every
statistic, and CSV column detection.
Your CSV should contain one row per replicate measurement.
| Field | Example values |
|---|---|
| Sample, strain, vector, plasmid, or group | Control strain, Test strain, Empty vector, Plasmid vector |
| Treatment, dose, condition, or concentration | Baseline, Treatment A, Treatment B, 0, 10 |
| Timepoint | Early, Late, 0 h, 24 h |
| Replicate | 1, 2, 3 |
| CFU count | 4300000, 2.1e6, 95000 |
The repository includes dummy_cfu_example.csv, a synthetic dataset that can be used as a template.
Statistics are run on log10(CFU) values. The app supports Welch t-tests, Student t-tests, and model-based comparisons with emmeans, with BH, Holm, Bonferroni, or no multiple-comparison correction.
Figure controls include exact width and height, DPI, y-axis boundaries, major and minor tick spacing, major and minor grid lines, y-axis tick marks, plot boxes, font sizes, bar width, point jitter, legend position, unit labels, and custom colors.
Download everything (.zip) collects all of it in one archive, with a README listing the contents, the figure geometry, the readout, and anything that could not be produced:
Each item is produced independently, so a missing optional package costs that one file rather than the whole archive.
The full launch article and user guide is in BLOGPOST.md.
Please report issues through GitHub:
Include your operating system, R version, browser, app version, what you clicked, the exact error message, and a small synthetic CSV if data are needed to reproduce the problem.
Please do not post private or unpublished experimental data in public issues.