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 bioprojUse 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
Seqobjects
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)
break3. 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.ymlorrequirements.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:
- Python for Biologists: A Complete Programming Course for Beginners
- Linux and Command Line for Bioinformatics
- Single-Cell RNA-Seq Data Analysis
- AI and Machine Learning for Bioinformatics
- Reproducible Pipelines with Nextflow, Snakemake, Docker and HPC
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


