Synteny visualization (pairwise minimap2)
TL;DR: align two assemblies with minimap2 -c --eqx, load the PAF as a
synteny track, and read it whole-genome in a dotplot and base-level in the
linear synteny view. add-track -a takes query,target, the reverse of the
minimap2 argument order.
Prerequisites
- a JBrowse 2 instance (see the web quickstart, or the desktop quickstart; the steps below are identical on both, and on Desktop the FASTAs and alignments are local files)
- minimap2
samtools- htslib (
bgzip,tabix) unzip- the NCBI
datasetsCLI, which fetches the three assemblies and their gene annotations node, for the JBrowse CLI
On Debian/Ubuntu, apt install minimap2 samtools tabix unzip covers most of
these. The NCBI datasets CLI is a single-binary download, and node comes
from nodejs.org.
Where the data comes from
Three H. pylori RefSeq assemblies, each fetched by accession with the
datasets CLI.
-
26695: https://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/307/795/GCF_000307795.1_ASM30779v1/
-
CHC155: https://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/025/998/455/GCF_025998455.1_ASM2599845v1/
-
J99: https://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/982/695/GCF_000982695.1_ASM98269v1/
-
the 26695 strain's gene annotation, rehosted so the color-by-attribute figure loads without rerunning the pipeline: https://jbrowse.org/demos/hpylori/hpylori_26695.gff.gz
Three strains, stacked
Three Helicobacter pylori strains (26695, CHC155, and J99) go from raw assemblies to a stacked three-genome synteny view. The steps work the same on any pair of assemblies.
Aligning the assemblies
minimap2 -c -x asm20 --eqx hpylori_j99.fa hpylori_26695.fa > 26695_vs_j99.paf
-x asm20is the assembly preset for the divergence between the genomes.asm5covers up to about 5%; these strains diverge well past that.-cemits the base-level CIGAR the linear synteny view draws from.--eqxsplits CIGAR matches (=) from mismatches (X), so the same track opened in a plain linear genome view draws per-base mismatches. Color by → Identity reads the PAF's divergence tag or match counts.
JBrowse also loads MUMmer .delta and UCSC
.chain files directly, and
paftools.js has
delta2paf and chain2paf for converting them.
Loading the assemblies and the alignment
Both genomes are added as assemblies before the alignment that references them:
jbrowse add-assembly hpylori_26695.fa --load copy
jbrowse add-assembly hpylori_j99.fa --load copy
jbrowse add-track 26695_vs_j99.paf -a hpylori_26695,hpylori_j99 --load copy
The -a order is query,target, the reverse of the minimap2 argument order:
minimap2 target.fa query.fa becomes add-track -a query,target.
Reading the whole genome in a dotplot
Add → Dotplot view opens the import form in Quick start: pick the track just added and click Launch. Swap transposes the axes. Manual picks each axis and a synteny file by hand.
To open any of those pieces at base resolution, drag a box across it, then right-click inside the box and choose Linear synteny view.
Stacking the three strains
A band is drawn between adjacent rows only, so a 26695 / CHC155 / J99 stack needs the two adjacent alignments:
minimap2 -c -x asm20 --eqx hpylori_chc155.fa hpylori_26695.fa > 26695_vs_chc155.paf
minimap2 -c -x asm20 --eqx hpylori_j99.fa hpylori_chc155.fa > chc155_vs_j99.paf
Add the third assembly and both alignments the same way as above, then:
- Add → Linear synteny view, then switch to Manual.
- Pick an assembly per row, with Add row for the third.
- Click the arrow between each adjacent pair to choose that band's synteny track: 26695 against CHC155, then CHC155 against J99.
- Click Launch, and all three strains stack in one view.
Open each strain's gene track from its own track selector.
Each panel is a full linear genome view with its own search box, zoom and track selector. See Linear synteny view for ribbon options and URL parameters → linear synteny view for building one from a URL.
Coloring genes by ortholog
In bacteria the gene symbol is effectively the ortholog id, since NCBI reuses
standardized symbols across strains. On each gene track, pick Color by... →
Attribute... from the track menu and enter gene. Every distinct value gets
its own deterministic color, so an ortholog carries one color down all three
panels. Features with no value are grey; most genes here carry only a locus tag.
The dialog writes a display color expression, which is one line of config:
{
"type": "FeatureTrack",
"trackId": "hpylori_26695.gff",
"name": "H. pylori 26695 genes",
"assemblyNames": ["hpylori_26695"],
"adapter": {
"type": "Gff3TabixAdapter",
"uri": "https://jbrowse.org/demos/hpylori/hpylori_26695.gff.gz"
},
"displayDefaults": {
"showOnlyGenes": true,
"color": "jexl:randomColor(get(feature,'gene'))"
}
}
jbrowse add-track https://jbrowse.org/demos/hpylori/hpylori_26695.gff.gz \
--trackId hpylori_26695.gff \
--name "H. pylori 26695 genes" \
--assemblyNames hpylori_26695 \
--displayDefaults "{\"showOnlyGenes\":true,\"color\":\"jexl:randomColor(get(feature,'gene'))\"}"
In JBrowse Desktop, or in any running JBrowse Web session, open a view on this track’s assembly, then File → Open track..., choose Add track from pasted JSON, and paste:
{
"type": "FeatureTrack",
"trackId": "hpylori_26695.gff",
"name": "H. pylori 26695 genes",
"assemblyNames": ["hpylori_26695"],
"adapter": {
"type": "Gff3TabixAdapter",
"uri": "https://jbrowse.org/demos/hpylori/hpylori_26695.gff.gz"
},
"displayDefaults": {
"showOnlyGenes": true,
"color": "jexl:randomColor(get(feature,'gene'))"
}
}
Using PIF for large genomes
A bacterial PAF is small enough to load whole. For a large whole-genome alignment, convert it to PIF (Pairwise Indexed Format) so JBrowse fetches only the alignments in the current viewport:
jbrowse make-pif alignment.paf
jbrowse add-track alignment.pif.gz -a query,target --load copy
Troubleshooting
assemblyNames in the wrong order is the common one. JBrowse checks at view
load whether the top row's chromosome names belong to that assembly, and a
warning in the view header names the remedy when they belong to the other row.
A view that scatters its blocks randomly comes from a preset too tight for the
divergence, which leaves only short spurious anchors. Raise it, and check
-c --eqx were passed.
Reproduce it end to end
One script builds everything above,
build_hpylori_synteny.sh:
curl -fO https://raw.githubusercontent.com/GMOD/jbrowse-components/main/scripts/build_hpylori_synteny.sh
bash build_hpylori_synteny.sh # builds ./hpylori_synteny_build/jbrowse2
npx --yes serve hpylori_synteny_build/jbrowse2 # then open the printed URL
It downloads the three assemblies, aligns the strain pairs, and writes a
config.json with a gene track per strain, the pairwise synteny tracks, and a
default session stacking all three. It needs the tools under
Prerequisites.
See also
- Synteny track
- Dotplot view
- Linear synteny view
- Synteny on genomes.jbrowse.org
- Comparing one genome's two haplotypes (T2T-HG002)
- Synteny visualization (all-vs-all minimap2)
- Synteny from an ortholog table (grape, peach, cacao)
- Config guide: MAF track
References
- Diesh et al. (2024). Setting Up the JBrowse 2 Genome Browser
- Diesh et al. (2023). JBrowse 2: A Modular Genome Browser with Views of Synteny and Structural Variation
Feedback on this tutorial is welcome: contact us.