Illustration of four people engaging in data analysis and visualization using tablets and charts, under the text 'Streamlit'. One person is sitting with a laptop, another holding a tablet, while two others discuss molecular and genetic diagrams.

Streamlit for Omics: Interactive Visualizations in Python

Table of Contents
Picture of Jonathan Alles

Jonathan Alles

EVOBYTE Digital Biology

By EVOBYTE Your partner in bioinformatics

Introduction

Omics data is vast, messy, and relentlessly multidimensional. When you’re exploring gene counts across tissues, scanning variant annotations, or comparing pathway signatures, a static plot rarely answers the “what if?” questions that drive discovery. You want to slice by cohort, toggle normalization, zoom into a subset of genes, and see the results change instantly. That interactivity shortens the path from intuition to insight.

This is where Streamlit shines. It lets you turn a plain Python script into a shareable data app in minutes, so you can iterate with colleagues instead of mailing screenshots back and forth. Because it speaks your language—pandas for tables and matplotlib for charts—you don’t need to learn a front‑end framework just to get a useful omics UI online.

Why interactive visualization accelerates omics discovery

Exploratory analysis in omics is a conversation: between a dataset and the questions you ask of it. As you inspect a volcano plot or QC metrics, you inevitably think, “What if I drop low‑depth samples?” or “What happens if I switch from TPM to CPM?” With interactive visualization, these tweaks are not extra engineering tasks; they’re a few widgets that re-run your code and reveal the impact in real time.

Streamlit’s dataframe and chart elements fit this workflow. An interactive table lets you filter rows, select columns, and copy subsets, while a linked chart updates as parameters change. That combination turns a single notebook step into a compact, repeatable analysis surface. In practice, you can surface row selections, validate edited values, and keep users focused on the subset that matters during a live review.

Streamlit for data scientists: Python‑first, fast to deploy

Most of us working in computational biology already rely on pandas, NumPy, and scikit‑learn. Streamlit sits right on top of that stack: you import streamlit as st, sprinkle a handful of UI calls, and your script becomes a web app. Because it’s open source and Python‑native, you reuse the same dataframes and figures you trust in the notebook.

Just as important, deployment is not an afterthought. With Streamlit Community Cloud, you connect a GitHub repo and click Deploy; every git push updates the app automatically. If you’re piloting a new differential expression workflow or an internal variant dashboard, this is the difference between an internal demo tomorrow and a ticket with web engineering next month.

If your team needs polish, you don’t have to write CSS from scratch. Libraries like st-styled add CSS‑free theming and component styling so you can match lab or company branding quickly, right from Python.

Plotting and wrangling omics data with pandas and matplotlib

You don’t need to abandon your plotting habits to get interactivity. Streamlit will render matplotlib figures with st.pyplot, or it can chart directly from a DataFrame with st.line_chart or st.altair_chart. If you prefer pure matplotlib, you can even layer interactivity using mpld3 so users can pan, zoom, and hover without changing your plotting code style.

Here’s a minimal, end‑to‑end example that turns a gene expression CSV into an interactive explorer. It loads a counts matrix, lets you filter samples, normalizes on the fly, and overlays selected genes in a quick chart. Paste this into streamlit_app.py and run streamlit run streamlit_app.py.

import streamlit as st
import pandas as pd
import numpy as np

st.title("Interactive Omics Explorer")

@st.cache_data
def load_counts(path):
    # Expect rows = genes, columns = samples
    df = pd.read_csv(path, index_col=0)
    return df

counts = load_counts("counts_matrix.csv")

with st.sidebar:
    st.header("Filters")
    groups = st.multiselect("Sample groups", options=counts.columns, default=list(counts.columns)[:5])
    norm = st.selectbox("Normalization", ["raw", "CPM", "log1p(CPM)"])
    genes = st.text_input("Genes (comma-separated)", value="TP53,BRCA1,ACTB")

if groups:
    X = counts[groups].copy()
    if norm in ("CPM", "log1p(CPM)"):
        X = X.div(X.sum(axis=0), axis=1) * 1e6
        if norm.startswith("log1p"):
            X = np.log1p(X)

    gene_list = [g.strip() for g in genes.split(",") if g.strip() in X.index]
    st.subheader("Selected genes")
    st.dataframe(X.loc[gene_list].round(2), use_container_width=True)
    st.line_chart(X.loc[gene_list].T)  # samples on x-axis, genes as series

    st.caption(f"{len(X)} genes x {len(X.columns)} samples after filtering.")
else:
    st.info("Pick at least one sample group in the sidebar.")

This is the everyday power move for omics: combine familiar pandas transforms with a few Streamlit widgets, then let your audience explore the data on their own terms. If someone wants a tweak—different normalization, a new subset—you add a control, not a static figure.

Molecular widgets with Streamlit Components: from editors to 3D viewers

Omics workflows often cross the boundary into structural biology and cheminformatics. Streamlit’s custom Components ecosystem fills that gap with ready‑made building blocks for molecules and genes. The official component gallery even has a “Molecules & genes” category, so you can discover tools purpose‑built for scientific apps. (streamlit.io)

Two additions are especially handy in bio/chem apps:

First, the Ketcher molecule editor embed lets users draw a structure in the browser and returns a SMILES string you can feed into RDKit, docking pipelines, or property predictors. Install streamlit-ketcher from PyPI and drop it into your app in a few lines. Streamlit’s own blog introduced it with a walkthrough, and the package provides a minimal API that keeps your code clean.

import streamlit as st
from streamlit_ketcher import st_ketcher

st.subheader("Draw a molecule")
smiles = st_ketcher("CCO")  # seed with ethanol
st.write("SMILES:", smiles or "—")

Second, for interactive 3D visualization, the stmol component wraps Py3Dmol so you can render proteins and ligands right inside Streamlit. It’s been described in the structural bioinformatics literature and has become a convenient way to preview docking poses, residue environments, or fragment overlays without leaving your analysis app.

Because components speak the same Streamlit interface as native widgets, you can chain them naturally. A typical workflow is to draw a ligand in Ketcher, convert SMILES to coordinates with RDKit, and display the pose against a protein pocket in stmol—all in one page. Your colleagues don’t need the RDKit toolchain locally; the app handles it on the server.

If you need to browse beyond these two, the component gallery is constantly updated, and you can filter by trending or most‑downloaded to gauge maturity. And if nothing fits, the component API is approachable enough to wrap your own front‑end widget and expose it to Python.

Summary / Takeaways

The fastest way to make omics results useful is to make them interactive. Streamlit gives you the shortest route from DataFrame to dashboard: write Python, add a few UI controls, and deploy in a click. Your team can then ask better questions—in real time—of the same code you trust for analysis.

For plotting, keep using pandas and matplotlib and upgrade to interactivity when it helps. For molecular tasks, lean on the components ecosystem to add editors and 3D viewers, so your analysis spans from sequences and counts to structures and ligands. And when the lab PI asks for a polished look, reach for a styling helper to brand your app without diving into CSS.

If you have a counts matrix or VCF handy, try turning one of your existing notebooks into a Streamlit app this week. Then share it with your collaborators and ask a simple question: what filter or toggle would help you decide faster? That answer is your next widget.

Further Reading

Leave a Comment