Skip to content
Home›INSIGHTS & RESOURCES›15 Bioinformatics Projects Using Python (with Starter Code)
INSIGHTS & RESOURCES

15 Bioinformatics Projects Using Python (with Starter Code)

6 November 2026Articles

Python is one of the most useful languages a biologist can learn. It’s easy to read, has powerful libraries such as Biopython, pandas, Scanpy and scikit-learn, and is used everywhere — from simple sequence analysis to single-cell genomics and AI-driven drug discovery.

But the fastest way to learn Python for bioinformatics isn’t reading tutorials — it’s building projects. In this guide, we share 15 bioinformatics projects using Python, from beginner to advanced, each with the libraries you’ll need, the skills you’ll gain and a starter code snippet to get you going.

Before you start: set up your Python environment

We recommend using Conda (or Mamba) to install Python and bioinformatics libraries in a clean environment:

conda create -n bioproj -c conda-forge -c bioconda python=3.11 biopython pandas matplotlib seaborn pysam scikit-learn scanpy rdkit jupyterlab
conda activate bioproj

Use Jupyter notebooks to explore, then move finished code into .py scripts and push everything to GitHub.

Beginner Python bioinformatics projects

1. DNA sequence toolkit

Build your own functions for GC content, reverse complement, transcription and translation — the classic first bioinformatics project.

  • Libraries: Biopython (or pure Python)
  • You’ll learn: Strings, functions, Biopython Seq objects
from Bio.Seq import Seq
from Bio.SeqUtils import gc_fraction

dna = Seq("ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG")
print("GC content:", round(gc_fraction(dna) * 100, 2), "%")
print("Reverse complement:", dna.reverse_complement())
print("mRNA:", dna.transcribe())
print("Protein:", dna.translate(to_stop=True))

2. FASTA file statistics reporter

Read a multi-FASTA file and report the number of sequences, lengths, N50 and GC content — useful for checking genome assemblies.

  • Libraries: Biopython, pandas, matplotlib
  • You’ll learn: File parsing, loops, summary statistics, plotting
from Bio import SeqIO
from Bio.SeqUtils import gc_fraction

lengths = []
for record in SeqIO.parse("sequences.fasta", "fasta"):
    lengths.append(len(record.seq))
    print(record.id, len(record.seq), round(gc_fraction(record.seq) * 100, 1))

lengths.sort(reverse=True)
half, running = sum(lengths) / 2, 0
for L in lengths:
    running += L
    if running >= half:
        print("N50:", L)
        break

3. Download sequences from NCBI automatically

Fetch gene or protein sequences from NCBI using their accession numbers — no manual downloading.

  • Libraries: Biopython (Bio.Entrez)
  • You’ll learn: Working with APIs and online databases
from Bio import Entrez, SeqIO

Entrez.email = "[email protected]"   # NCBI requires an email
handle = Entrez.efetch(db="nucleotide", id="NM_000546",
                       rettype="fasta", retmode="text")   # TP53 mRNA
record = SeqIO.read(handle, "fasta")
handle.close()
print(record.description)
print(len(record.seq), "bp")

4. Open Reading Frame (ORF) finder

Find all potential protein-coding regions in all six reading frames of a DNA sequence.

  • Libraries: Biopython
  • You’ll learn: Reading frames, translation, algorithm design
from Bio.Seq import Seq

def find_orfs(seq, min_len=100):
    orfs = []
    for strand, s in [("+", seq), ("-", seq.reverse_complement())]:
        for frame in range(3):
            sub = s[frame:]
            sub = sub[:len(sub) - len(sub) % 3]
            protein = str(sub.translate())
            for fragment in protein.split("*"):
                if "M" in fragment:
                    orf = fragment[fragment.index("M"):]
                    if len(orf) >= min_len:
                        orfs.append((strand, frame, orf))
    return orfs

seq = Seq(open("gene.txt").read().strip())
for strand, frame, orf in find_orfs(seq):
    print(strand, frame, len(orf), orf[:30] + "...")

5. Codon usage analyser

Calculate codon frequencies in a gene or genome and compare codon bias between organisms — useful for gene expression and synthetic biology.

  • Libraries: Python (collections.Counter), pandas, matplotlib
  • You’ll learn: Dictionaries, counting, data visualisation
from collections import Counter
from Bio import SeqIO

counts = Counter()
for rec in SeqIO.parse("cds.fasta", "fasta"):
    s = str(rec.seq).upper()
    counts.update(s[i:i+3] for i in range(0, len(s) - 2, 3))

total = sum(counts.values())
for codon, c in counts.most_common(10):
    print(codon, round(c / total * 100, 2), "%")

Intermediate Python bioinformatics projects

6. FASTQ quality checker

Build a mini FastQC: read a FASTQ file and plot average quality per base position.

  • Libraries: Biopython, NumPy, matplotlib
  • You’ll learn: NGS file formats, Phred scores, plotting
from Bio import SeqIO
import numpy as np
import matplotlib.pyplot as plt

quals = [rec.letter_annotations["phred_quality"]
         for rec in SeqIO.parse("reads.fastq", "fastq")]
max_len = max(len(q) for q in quals)
mean_q = [np.mean([q[i] for q in quals if len(q) > i]) for i in range(max_len)]

plt.plot(range(1, max_len + 1), mean_q)
plt.axhline(30, color="red", linestyle="--", label="Q30")
plt.xlabel("Position in read"); plt.ylabel("Mean Phred quality")
plt.legend(); plt.savefig("quality.png", dpi=150)

7. VCF variant summary and filtering

Read a VCF file, count SNPs vs indels, filter by quality and summarise variants per chromosome.

  • Libraries: pysam, pandas
  • You’ll learn: Variant formats, filtering, data aggregation
import pysam
import pandas as pd

rows = []
for rec in pysam.VariantFile("sample.vcf.gz"):
    for alt in rec.alts or []:
        vtype = "SNP" if len(rec.ref) == 1 and len(alt) == 1 else "INDEL"
        rows.append({"chrom": rec.chrom, "pos": rec.pos, "qual": rec.qual, "type": vtype})

df = pd.DataFrame(rows)
df = df[df["qual"] >= 30]
print(df["type"].value_counts())
print(df.groupby("chrom").size())

8. RNA-seq results visualisation: volcano plot and top genes

Take a differential expression results table (e.g. from DESeq2 or PyDESeq2) and create publication-quality plots.

  • Libraries: pandas, NumPy, matplotlib or seaborn
  • You’ll learn: Fold change, adjusted p-values, plotting
import pandas as pd, numpy as np
import matplotlib.pyplot as plt

df = pd.read_csv("deseq2_results.csv").dropna(subset=["padj"])
df["neglog10"] = -np.log10(df["padj"])
sig = (df["padj"] < 0.05) & (df["log2FoldChange"].abs() > 1)

plt.scatter(df["log2FoldChange"], df["neglog10"], s=5, c="grey")
plt.scatter(df.loc[sig, "log2FoldChange"], df.loc[sig, "neglog10"], s=5, c="#810D15")
plt.xlabel("log2 fold change"); plt.ylabel("-log10 adjusted p-value")
plt.savefig("volcano.png", dpi=150)
print(sig.sum(), "significant genes")

9. Protein structure explorer

Download a protein structure from PDB, list its chains and residues, and find residues near a ligand or mutation site.

  • Libraries: Biopython (Bio.PDB)
  • You’ll learn: 3D structure data, distances, structural biology
from Bio.PDB import PDBList, PDBParser, NeighborSearch

path = PDBList().retrieve_pdb_file("1TUP", file_format="pdb", pdir=".")
structure = PDBParser(QUIET=True).get_structure("p53", path)

for chain in structure[0]:
    print("Chain", chain.id, "-", len(chain), "residues")

atoms = list(structure.get_atoms())
ns = NeighborSearch(atoms)
target = structure[0]["B"][248]["CA"]          # residue R248, a p53 hotspot
nearby = {a.get_parent() for a in ns.search(target.coord, 8.0)}
print(len(nearby), "residues within 8 Å of R248")

10. k-mer analysis and genome comparison

Count k-mers in two genomes and compare their similarity — the idea behind many fast genome comparison tools.

  • Libraries: Python, Biopython, matplotlib
  • You’ll learn: Hashing, set operations, Jaccard similarity
from collections import Counter
from Bio import SeqIO

def kmers(path, k=21):
    seq = str(next(SeqIO.parse(path, "fasta")).seq).upper()
    return {seq[i:i+k] for i in range(len(seq) - k + 1)}

a, b = kmers("genome_A.fasta"), kmers("genome_B.fasta")
jaccard = len(a & b) / len(a | b)
print("Jaccard similarity:", round(jaccard, 4))

Advanced Python bioinformatics projects

11. Single-cell RNA-seq analysis with Scanpy

Cluster thousands of cells, find marker genes and identify cell types in a public PBMC dataset.

  • Libraries: Scanpy, anndata, leidenalg
  • You’ll learn: Single-cell QC, normalisation, dimensionality reduction, clustering
import scanpy as sc

adata = sc.datasets.pbmc3k()
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, n_top_genes=2000, subset=True)
sc.pp.pca(adata)
sc.pp.neighbors(adata)
sc.tl.leiden(adata)
sc.tl.umap(adata)
sc.pl.umap(adata, color="leiden", save="_clusters.png")
sc.tl.rank_genes_groups(adata, "leiden")

12. Machine learning classifier for cancer subtypes

Train a model to predict cancer type or subtype from gene expression data and find the most informative genes.

  • Libraries: pandas, scikit-learn
  • You’ll learn: Feature selection, cross-validation, model evaluation
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

X = pd.read_csv("expression_matrix.csv", index_col=0)   # samples x genes
y = pd.read_csv("labels.csv", index_col=0)["subtype"].loc[X.index]

model = RandomForestClassifier(n_estimators=500, random_state=42)
print("CV accuracy:", cross_val_score(model, X, y, cv=5).mean())

model.fit(X, y)
top = pd.Series(model.feature_importances_, index=X.columns).nlargest(20)
print(top)

13. Drug-likeness screening with RDKit

Screen a list of compounds against Lipinski’s Rule of Five and calculate molecular properties — a first step in drug discovery.

  • Libraries: RDKit, pandas
  • You’ll learn: Cheminformatics, SMILES, molecular descriptors
import pandas as pd
from rdkit import Chem
from rdkit.Chem import Descriptors, Lipinski

df = pd.read_csv("compounds.csv")          # columns: name, smiles
def props(smi):
    m = Chem.MolFromSmiles(smi)
    return pd.Series({"MW": Descriptors.MolWt(m), "LogP": Descriptors.MolLogP(m),
                      "HBD": Lipinski.NumHDonors(m), "HBA": Lipinski.NumHAcceptors(m)})

df = df.join(df["smiles"].apply(props))
df["violations"] = ((df.MW > 500).astype(int) + (df.LogP > 5) + (df.HBD > 5) + (df.HBA > 10))
print(df[df["violations"] <= 1])

14. Microbiome abundance analysis

Analyse a taxa abundance table: calculate diversity, compare groups and visualise the most abundant taxa.

  • Libraries: pandas, NumPy, SciPy, seaborn (or scikit-bio)
  • You’ll learn: Diversity indices, statistical testing, stacked bar plots
import pandas as pd, numpy as np
from scipy.stats import mannwhitneyu

abund = pd.read_csv("taxa_counts.csv", index_col=0)        # samples x taxa
meta = pd.read_csv("metadata.csv", index_col=0)

p = abund.div(abund.sum(axis=1), axis=0)
shannon = -(p * np.log(p.where(p > 0))).sum(axis=1)
g = meta.loc[shannon.index, "group"]
print(mannwhitneyu(shannon[g == "healthy"], shannon[g == "disease"]))

15. Build an automated pipeline with Snakemake

Snakemake is written in Python — use it to turn your scripts into a reproducible pipeline (e.g. QC → trimming → alignment).

  • Libraries: Snakemake, Conda
  • You’ll learn: Workflow automation, reproducibility, scaling to clusters
SAMPLES = ["sample1", "sample2"]

rule all:
    input: expand("qc/{s}_fastqc.html", s=SAMPLES)

rule fastqc:
    input: "data/{s}.fastq.gz"
    output: "qc/{s}_fastqc.html"
    shell: "fastqc {input} -o qc"

How to present your Python projects

  • One GitHub repository per project, with a clear README: the question, data source, how to run it and key results.
  • Add an environment file (environment.yml or requirements.txt) so others can reproduce your work.
  • Include figures in the README — plots make your work easy to understand at a glance.
  • Write clean code — functions, comments and meaningful variable names.
  • Explain the biology — what do your results mean?

Frequently asked questions

Is Python enough for bioinformatics?

Python covers most bioinformatics tasks, but you’ll also need Linux command-line skills, and many statistics and RNA-seq workflows use R. Python plus Linux is a strong foundation; add R as you go.

Which Python libraries should a bioinformatics student learn first?

Start with Biopython, pandas and matplotlib/seaborn. Then add pysam for NGS files, scikit-learn for machine learning, Scanpy for single-cell analysis and RDKit for cheminformatics.

Can I do these projects on a normal laptop?

Yes — projects 1–10, 12, 13 and 14 run fine on a laptop with small datasets. Single-cell analysis works on a laptop for small public datasets like PBMC3k; larger datasets need more memory.

Where can I get data for these projects?

NCBI (GenBank, SRA, GEO), Ensembl, UniProt, PDB, TCGA/GDC, ChEMBL and 10x Genomics public datasets are all free.

Learn Python for bioinformatics with Bio Help Learning

Want guided, hands-on training? At Bio Help Learning, you’ll build real projects with real biological data:

We also offer internships, project and dissertation support, and customised learning paths.

👉 Explore all courses at www.biohelplearning.com

📩 Email: [email protected] | 📞 WhatsApp/Call: +91 78280 25951

Related reading