Getting Started
# !pip install pygenomeviz
# !apt install ncbi-blast+ mummer mmseqs2
pyGenomeViz is a genome visualization python package for comparative genomics implemented based on matplotlib. This documentation introduces pyGenomeViz step by step, from basic plotting examples to advanced use cases.
1. Layout Design¶
pyGenomeViz uses a layout design composed of tracks and segments.
pyGenomeViz can set up multiple genome tracks for linear genome comparison, and each track is made up of multiple segments.
By assigning each chromosome, contig, or region of interest to a segment within a genome track, users can plot genome data flexibly.
Segments can be specified with types such as int, tuple[int, int], Sequence[int | tuple[int, int]], and Mapping[str, int | tuple[int, int]] as follows.
from pygenomeviz import GenomeViz
gv = GenomeViz(fig_track_height=0.5)
# Add tracks with different segment styles
track1 = gv.add_feature_track("segment", 1000)
track2 = gv.add_feature_track("range segment", (1000, 2500))
track3 = gv.add_feature_track("segments", (1000, 2000, 1500))
track4 = gv.add_feature_track("named segments", dict(first=1000, second=2000, third=1500))
track5 = gv.add_feature_track("range segments", ((2000, 3000), (5000, 6000), (8000, 10000)))
track6 = gv.add_feature_track("named range segments", dict(region1=(2000, 3000), region2=(5000, 6000), region3=(8000, 10000)))
# Plot segment name and range sublabels
for track in gv.feature_tracks:
for seg in track.segments:
seg.add_sublabel(f"{seg.name}: {seg.start:,} - {seg.end:,} bp")
fig = gv.plotfig()
Genomic features can be plotted on each segment. The next section introduces the plotting functions for various features.
2. Plot Features¶
User can plot various features by calling the segment.add_xxx() method for each segment that makes up a track.
To simplify method calls in cases where a track consists of a single segment, track.add_xxx() is provided as an alias for track.segments[0].add_xxx().
2-1. Features¶
User can plot a feature by specifying its start, end, and strand.
from pygenomeviz import GenomeViz
gv = GenomeViz()
gv.set_scale_xticks(ymargin=0.5)
track = gv.add_feature_track("track", 1000)
track.add_sublabel()
# Add features to track
# track.add_xxx() is alias for track.segments[0].add_xxx()
track.add_feature(50, 200, 1)
track.add_feature(250, 460, -1, fc="blue")
track.add_feature(500, 710, 1, fc="lime", lw=1.0)
track.add_feature(750, 960, 1, fc="magenta", lw=1.0, ec="grey", hatch="//")
fig = gv.plotfig()
2-2. Styled Features¶
The feature to be plotted can be assigned several plot styles, such as [big]arrow, [big]box, and [big]rbox, as shown in the example below.
from pygenomeviz import GenomeViz
gv = GenomeViz()
gv.set_scale_bar(ymargin=0.5)
track = gv.add_feature_track("track", (1000, 2000))
track.add_sublabel()
# Add styled features
# track.add_xxx() is alias for track.segments[0].add_xxx()
track.add_feature(1000, 1100, 1, label="arrow")
track.add_feature(1120, 1220, -1, plotstyle="bigarrow", label="bigarrow", fc="red", lw=1)
track.add_feature(1240, 1340, 1, plotstyle="box", label="box", fc="blue")
track.add_feature(1360, 1480, 1, plotstyle="bigbox", label="bigbox", fc="limegreen")
track.add_feature(1500, 1620, -1, plotstyle="rbox", label="rbox", fc="magenta", ec="blue", lw=1)
track.add_feature(1640, 1740, -1, plotstyle="bigrbox", label="bigrbox", fc="grey")
track.add_feature(1760, 1860, 1, fc="lime", hatch="o", arrow_shaft_ratio=0.2, label="arrow shaft = 0.2")
track.add_feature(1880, 1980, 1, fc="lime", hatch="/", arrow_shaft_ratio=1.0, label="arrow shaft = 1.0")
fig = gv.plotfig()
2-3. Exon Features¶
Exon plotting is also supported.
from pygenomeviz import GenomeViz
exon_regions1 = [(0, 210), (300, 480), (590, 800), (850, 1000), (1030, 1300)]
exon_regions2 = [(1500, 1710), (2000, 2480), (2590, 2800)]
exon_regions3 = [(3000, 3300), (3400, 3690), (3800, 4100), (4200, 4620)]
gv = GenomeViz()
track = gv.add_feature_track("track", 5000)
# Add exon features
track.add_exon_feature(exon_regions1, strand=1, plotstyle="box", label="box", text_kws=dict(rotation=0, hpos="center"))
track.add_exon_feature(exon_regions2, strand=-1, plotstyle="arrow", label="arrow", text_kws=dict(rotation=0, vpos="bottom", hpos="center"), patch_kws=dict(fc="darkgrey"), intron_patch_kws=dict(ec="red"))
track.add_exon_feature(exon_regions3, strand=1, plotstyle="bigarrow", label="bigarrow", text_kws=dict(rotation=0, hpos="center"), patch_kws=dict(fc="lime", lw=1))
fig = gv.plotfig()
2-4. Other Features¶
In addition, it provides plotting methods for promoters, lollipops, and highlights.
from pygenomeviz import GenomeViz
gv = GenomeViz()
gv.set_scale_xticks(ymargin=0.5)
track = gv.add_feature_track("track", 1000)
# Add promoter arrow
track.add_promoter(50)
track.add_promoter(150, 0.05, y=1.5, head_length=0.5, head_width=0.8)
track.add_promoter(250, 100, y=-1.0, strand=-1, fc="red")
track.add_text(150, "Promoter", size=15, ymargin=1, rotation=0, hpos="center")
# Add lollipop
track.add_lollipop(350)
track.add_lollipop(450, y=-1.0, size=10, point_kws=dict(fc="red", ec="black", lw=1.0))
track.add_lollipop(550, y=1.5, point_kws=dict(color="green"), line_kws=dict(color="green"))
track.add_text(450, "Lollipop", size=15, ymargin=1, rotation=0, hpos="center")
# Add highlight
track.add_highlight((650, 750))
track.add_highlight((750, 850), y=(0, 1.5), color="orange")
track.add_highlight((850, 950), y=(-1.0, 0), color="red")
track.add_text(800, "Highlight", size=15, ymargin=1, rotation=0, hpos="center")
fig = gv.plotfig()
from pygenomeviz import GenomeViz
genome_list = [
("genome 01", 1000, [(150, 300, 1), (500, 700, -1), (750, 950, 1)]),
("genome 02", 1300, [(50, 200, 1), (350, 450, 1), (700, 900, -1), (950, 1150, -1)]),
("genome 03", 1200, [(150, 300, 1), (350, 450, -1), (500, 700, -1), (700, 900, -1)]),
]
gv = GenomeViz(fig_track_height=0.7, track_align_type="center")
gv.set_scale_bar()
# Set tracks & features
for genome in genome_list:
name, size, features = genome[0], genome[1], genome[2]
track = gv.add_feature_track(name, size)
track.add_sublabel()
for idx, feature in enumerate(features, 1):
start, end, strand = feature
track.add_feature(start, end, strand, plotstyle="bigarrow", lw=1, label=f"gene{idx:02d}", text_kws=dict(rotation=0, vpos="top", hpos="center"))
# Add links between "genome 01" and "genome 02"
gv.add_link(("genome 01", 150, 300), ("genome 02", 50, 200))
gv.add_link(("genome 01", 700, 500), ("genome 02", 900, 700))
gv.add_link(("genome 01", 750, 950), ("genome 02", 1150, 950))
# Add links between "genome 02" and "genome 03"
gv.add_link(("genome 02", 50, 200), ("genome 03", 150, 300), color="skyblue", inverted_color="lime", curve=True)
gv.add_link(("genome 02", 350, 450), ("genome 03", 450, 350), color="skyblue", inverted_color="lime", curve=True)
gv.add_link(("genome 02", 900, 700), ("genome 03", 700, 500), color="skyblue", inverted_color="lime", curve=True)
gv.add_link(("genome 03", 900, 700), ("genome 02", 1150, 950), color="skyblue", inverted_color="lime", curve=True)
fig = gv.plotfig()
3-2. Eukaryote Example¶
from pygenomeviz import GenomeViz
from pygenomeviz.utils import ColorCycler
ColorCycler.set_cmap("tab10")
name2chr_segments = dict(
chimp=dict(chr1=224244399, chr2A=108022953, chr2B=128755405, chr3=196562556, chr4=189151597, chr5=159319378, chr6=168369391, chr7=156046543, chr8=143338810, chr9=110513671, chr10=129809613, chr11=130782606, chr12=130995916, chr13=95599650, chr14=87716528, chr15=80519282, chr16=75912362, chr17=76554115, chr18=74774469, chr19=56733099, chr20=64035432, chr21=33232379, chr22=33698415, chrX=151576176, chrY=26350515),
human=dict(chr1=248956422, chr2=242193529, chr3=198295559, chr4=190214555, chr5=181538259, chr6=170805979, chr7=159345973, chr8=145138636, chr9=138394717, chr10=133797422, chr11=135086622, chr12=133275309, chr13=114364328, chr14=107043718, chr15=101991189, chr16=90338345, chr17=83257441, chr18=80373285, chr19=58617616, chr20=64444167, chr21=46709983, chr22=50818468, chrX=156040895, chrY=57227415),
mouse=dict(chr1=195471971, chr2=182113224, chr3=160039680, chr4=156508116, chr5=151834684, chr6=149736546, chr7=145441459, chr8=129401213, chr9=124595110, chr10=130694993, chr11=122082543, chr12=120129022, chr13=120421639, chr14=124902244, chr15=104043685, chr16=98207768, chr17=94987271, chr18=90702639, chr19=61431566, chrX=171031299, chrY=91744698),
)
gv = GenomeViz(fig_track_height=0.7, feature_track_ratio=0.15, track_align_type="center")
gv.set_scale_bar(ymargin=2)
for name, chr_segments in name2chr_segments.items():
color = ColorCycler()
# Set chromosomes as segments
track = gv.add_feature_track(
name, chr_segments, space=0.01, align_label=False, label_kws=dict(color=color),
)
for seg in track.segments:
seg.add_feature(
seg.start,
seg.end,
plotstyle="bigrbox",
fc=color,
ec="black",
lw=0.5,
label=seg.name.replace("chr", ""),
text_kws=dict(rotation=0, size=8, color="white", vpos="center", hpos="center"),
)
gv.add_link(("human", "chr1", 0, 100000000), ("chimp", "chr1", 0, 100000000))
gv.add_link(("human", "chr2", 0, 120000000), ("chimp", "chr2A", 0, 108022953), color="lime", curve=True)
gv.add_link(("human", "chr2", 120000000, 242193529), ("chimp", "chr2B", 0, 128755405), color="lime", curve=True)
fig = gv.plotfig()
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Genbank
from pygenomeviz.utils import load_example_genbank_dataset
# Parse Genbank file
gbk_files = load_example_genbank_dataset("yersinia_phage")
gbk = Genbank(gbk_files[0])
gv = GenomeViz(fig_track_height=0.7)
gv.set_scale_bar(ymargin=0.5)
track = gv.add_feature_track(gbk.name, gbk.get_seqid2size())
for seg in track.segments:
# Plot CDS features
features = gbk.get_seqid2features()[seg.name]
seg.add_features(features, lw=0.5)
seg.add_sublabel()
fig = gv.plotfig()
4-1-2. Multi Records¶
If a GenBank file consists of multiple records, such as chromosomes or contigs, user can plot the features within each record onto segments.
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Genbank
from pygenomeviz.utils import load_example_genbank_dataset, is_pseudo_feature
# Parse multi-record Genbank file
gbk_files = load_example_genbank_dataset("mycoplasma_mycoides")
gbk = Genbank(gbk_files[3])
gv = GenomeViz(fig_track_height=0.7)
gv.set_scale_bar(ymargin=0.5)
track = gv.add_feature_track(gbk.name, gbk.get_seqid2size())
for seg in track.segments:
# Extract each contig record features
features = gbk.get_seqid2features(feature_type=None)[seg.name]
# Plot features with different styles
for feature in features:
if feature.type == "CDS":
color = "grey" if is_pseudo_feature(feature) else "blue"
seg.add_features(feature, color=color)
elif feature.type == "rRNA":
seg.add_features(feature, color="lime")
fig = gv.plotfig()
4-1-3. Multi Regions¶
It is also possible to plot not only the entire genome, but also by narrowing down to multiple target regions.
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Genbank
from pygenomeviz.utils import load_example_genbank_dataset
gbk_files = load_example_genbank_dataset("escherichia_coli")
gbk = Genbank(gbk_files[0])
gv = GenomeViz(fig_track_height=0.7)
gv.set_scale_bar(ymargin=0.5)
target_ranges = ((200000, 210000), (500000, 520000), (800000, 810000))
track = gv.add_feature_track(name=gbk.name, segments=target_ranges)
track.set_segment_sep()
for segment in track.segments:
segment.add_sublabel()
# Plot CDS features with gene annotation label
cds_features = gbk.extract_features(feature_type="CDS", target_range=segment.range)
segment.add_features(cds_features, label_type="gene", annotation=True, lw=1.0)
fig = gv.plotfig()
4-1-4. Multi Tracks¶
Multiple GenBank files can be assigned to individual tracks.
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Genbank
from pygenomeviz.utils import load_example_genbank_dataset
gbk_files = load_example_genbank_dataset("yersinia_phage")
gbk_list = list(map(Genbank, gbk_files))
gv = GenomeViz(fig_track_height=0.7)
gv.set_scale_xticks()
for gbk in gbk_list:
track = gv.add_feature_track(gbk.name, gbk.genome_length)
# Plot genbank features
features = gbk.extract_features()
for feature in features:
# Set user-defined feature color based on product name
product = str(feature.qualifiers.get("product", [""])[0])
color = "lightgrey" if product.startswith("hypothetical") else "limegreen"
track.add_features(feature, plotstyle="bigarrow", fc=color, lw=0.5)
fig = gv.plotfig()
4-2. GFF¶
Similarly to GenBank, user can read files with a GFF parser class and plot them based on the obtained genome size and features.
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Gff
from pygenomeviz.utils import load_example_gff_file
gff_file = load_example_gff_file("escherichia_coli.gff.gz")
gff = Gff(gff_file)
gv = GenomeViz()
gv.set_scale_bar(ymargin=0.5)
target_ranges = ((215000, 230000), (300000, 320000))
track = gv.add_feature_track(name=gff.name, segments=target_ranges)
track.set_segment_sep()
for segment in track.segments:
segment.add_sublabel()
features = gff.extract_features(feature_type=None, target_range=segment.range)
for feature in features:
if feature.type == "CDS":
segment.add_features(
feature,
label_type="gene",
fc="skyblue",
lw=1.0,
annotation=True,
text_kws=dict(bbox=dict(boxstyle="round", fc="skyblue")),
)
elif feature.type == "rRNA":
segment.add_features(
feature,
label_type="product",
fc="lime",
lw=1.0,
hatch="//",
annotation=True,
text_kws=dict(bbox=dict(boxstyle="round", fc="lime")),
)
fig = gv.plotfig()
4-3. Fasta¶
User can read files with a FASTA parser class and plot them based on the obtained genome size.
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Fasta
from pygenomeviz.utils import load_example_fasta_dataset, ColorCycler
ColorCycler.set_cmap("tab10")
fasta_files = load_example_fasta_dataset("saccharomyces")
fasta_list = list(map(Fasta, fasta_files))
gv = GenomeViz(fig_track_height=0.7, feature_track_ratio=0.15)
gv.set_scale_bar(ymargin=2.0)
for fasta in fasta_list:
color = ColorCycler()
track = gv.add_feature_track(fasta.name, fasta.get_seqid2size(), space=0.01, label_kws=dict(color=color))
track.set_label(track.name.replace("_", "\n"))
for seg in track.segments:
seg.add_feature(seg.start, seg.end, plotstyle="bigrbox", fc=color, lw=0.5)
fig = gv.plotfig()
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Genbank
from pygenomeviz.utils import load_example_genbank_dataset
from pygenomeviz.align import Blast, AlignCoord
gbk_files = load_example_genbank_dataset("yersinia_phage")
gbk_list = list(map(Genbank, gbk_files))
gv = GenomeViz(track_align_type="center")
gv.set_scale_bar()
# Plot CDS features
for gbk in gbk_list:
track = gv.add_feature_track(gbk.name, gbk.get_seqid2size(), align_label=False)
for seqid, features in gbk.get_seqid2features("CDS").items():
segment = track.get_segment(seqid)
segment.add_features(features, plotstyle="bigarrow", fc="limegreen", lw=0.5)
# Run BLAST alignment & filter by user-defined threshold
align_coords = Blast(gbk_list, seqtype="protein").run()
align_coords = AlignCoord.filter(align_coords, length_thr=100, identity_thr=30)
# Plot BLAST alignment links
if len(align_coords) > 0:
min_ident = int(min([ac.identity for ac in align_coords if ac.identity]))
color, inverted_color = "grey", "red"
for ac in align_coords:
gv.add_link(ac.query_link, ac.ref_link, color=color, inverted_color=inverted_color, v=ac.identity, vmin=min_ident)
gv.set_colorbar([color, inverted_color], vmin=min_ident)
fig = gv.plotfig()
5-2. MUMmer¶
Support nucmer(seqtype="nucleotide") and promer(seqtype="protein")
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Genbank
from pygenomeviz.utils import load_example_genbank_dataset, is_pseudo_feature
from pygenomeviz.align import MUMmer
gbk_files = load_example_genbank_dataset("mycoplasma_mycoides")
gbk_list = list(map(Genbank, gbk_files))
gv = GenomeViz()
gv.set_scale_bar()
# Plot CDS, rRNA features for each contig to tracks
for gbk in gbk_list:
track = gv.add_feature_track(gbk.name, gbk.get_seqid2size(), align_label=False)
for seqid, features in gbk.get_seqid2features(None).items():
segment = track.get_segment(seqid)
for feature in features:
if feature.type == "CDS":
# CDS: blue, CDS(pseudo): grey
color = "grey" if is_pseudo_feature(feature) else "blue"
segment.add_features(feature, fc=color)
elif feature.type == "rRNA":
# rRNA: lime
segment.add_features(feature, fc="lime")
# Run MUMmer alignment
align_coords = MUMmer(gbk_list, seqtype="nucleotide").run()
# Plot MUMmer alignment links
if len(align_coords) > 0:
min_ident = int(min([ac.identity for ac in align_coords if ac.identity]))
color, inverted_color = "grey", "red"
for ac in align_coords:
gv.add_link(ac.query_link, ac.ref_link, color=color, inverted_color=inverted_color, v=ac.identity, vmin=min_ident)
gv.set_colorbar([color, inverted_color], vmin=min_ident)
fig = gv.plotfig()
5-3. MMseqs¶
Support mmseqs easy-rbh workflow for generating Reciprocal Best Hit links between CDSs
from pygenomeviz import GenomeViz
from pygenomeviz.parser import Genbank
from pygenomeviz.utils import load_example_genbank_dataset
from pygenomeviz.align import MMseqs
gbk_files = load_example_genbank_dataset("enterobacteria_phage")
gbk_list = list(map(Genbank, gbk_files))
gv = GenomeViz(fig_track_height=0.8, feature_track_ratio=0.4)
gv.set_scale_xticks()
# Plot CDS features
for gbk in gbk_list:
track = gv.add_feature_track(gbk.name, gbk.get_seqid2size(), align_label=False)
for seqid, features in gbk.get_seqid2features("CDS").items():
segment = track.get_segment(seqid)
segment.add_features(features, fc="skyblue", lw=0.5)
# Run MMseqs RBH search
align_coords = MMseqs(gbk_list).run()
# Plot MMseqs RBH search links
if len(align_coords) > 0:
min_ident = int(min([ac.identity for ac in align_coords if ac.identity]))
color, inverted_color = "chocolate", "limegreen"
for ac in align_coords:
gv.add_link(ac.query_link, ac.ref_link, color=color, inverted_color=inverted_color, v=ac.identity, vmin=min_ident, curve=True)
gv.set_colorbar([color, inverted_color], vmin=min_ident)
fig = gv.plotfig()