Variant track
A VariantTrack with a VcfTabixAdapter handles single- and multi-sample VCFs.
Color variants with a jexl: expression on the display's encoding.color; a
multi-sample VCF draws its genotypes as rows under the records, and an LD track
draws a cohort's linkage.
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "my_track",
"name": "My Variants",
"assemblyNames": ["hg19"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://yourhost/file.vcf.gz"
}
}Edits config.json in the current folder. See JBrowse CLI with Desktop.
jbrowse add-track https://yourhost/file.vcf.gz \
--trackId my_track \
--name "My Variants" \
--assemblyNames hg19In JBrowse Desktop, or in any running JBrowse Web session, open a view on this track’s assembly, then File → Open track... and, in Add a track from file or URL, enter:
- Main file:
https://yourhost/file.vcf.gz
JBrowse reads the adapter and track type off the file name. Then fill in:
- Track name:
My Variants - Assembly:
hg19
Click Add.
The uri shorthand resolves a sibling .tbi; add "csi": true for a .csi
(the uri shorthand).
Coloring variants
encoding.color takes a jexl: expression over the record. INFO fields parse
as arrays, so feature.INFO.SVTYPE[0] is the first value; the
cookbook has the SV-type lookup table and a
filter example.
Helper functions for jexl color expressions
The variants plugin registers these for encoding.color and filter:
jexl: maf(feature) // minor allele frequency over the called alleles
jexl: missingness(feature) // fraction of alleles with no call, so ./1 counts half
jexl: impact(feature) // HIGH, MODERATE, LOW or MODIFIER, from SnpEff ANN / VEP CSQ
jexl: consequence(feature) // e.g. missense_variant, from the same annotation — the MOST SEVERE one alone
jexl: 'missense_variant' in consequences(feature) // every consequence term on the record, across all transcripts (bcftools INFO/CSQ ~ "missense_variant")
jexl: impactColor(feature) // the color `encoding: { color: 'impact' }` paints the variant's most severe tier
jexl: alleleLength(feature) >= 50 // longest allele in bp, so an insertion is not measured by its reference span
jexl: svType(feature) == 'DEL' // SV class, read off a symbolic ALT before falling back to INFO/SVTYPE (bcftools INFO/SVTYPE)
jexl: nAlt(feature) == 1 // ALT alleles the record declares, i.e. biallelic-only (bcftools N_ALT)
jexl: genotypeCount(feature, 'het') > 0 // samples in a genotype class — ref, alt, hom, het or mis (bcftools N_PASS(GT="het"))With those functions available, a track colors by allele frequency with no
preprocessing. A jexl: expression as the encoding.color object's field
computes the value, and a threshold scale bins it, with a key naming each bin:
Goes in the tracks array of config.json. See Tracks.
{
"trackId": "my_maf_track",
"name": "Variants colored by allele frequency",
"uri": "https://yourhost/file.vcf.gz",
"assemblyNames": ["hg38"],
"displayDefaults": {
"encoding": {
"color": {
"field": "jexl:maf(feature)",
"scale": {
"type": "threshold",
"domain": [0.01, 0.05],
"range": ["#ccc", "#74a9cf", "#045a8d"]
},
"legend": { "title": "Minor allele frequency" }
}
}
}
}Edits config.json in the current folder. See JBrowse CLI with Desktop.
jbrowse add-track https://yourhost/file.vcf.gz \
--trackId my_maf_track \
--name "Variants colored by allele frequency" \
--assemblyNames hg38 \
--displayDefaults '{"encoding":{"color":{"field":"jexl:maf(feature)","scale":{"type":"threshold","domain":[0.01,0.05],"range":["#ccc","#74a9cf","#045a8d"]},"legend":{"title":"Minor allele frequency"}}}}'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:
{
"trackId": "my_maf_track",
"name": "Variants colored by allele frequency",
"uri": "https://yourhost/file.vcf.gz",
"assemblyNames": ["hg38"],
"displayDefaults": {
"encoding": {
"color": {
"field": "jexl:maf(feature)",
"scale": {
"type": "threshold",
"domain": [0.01, 0.05],
"range": ["#ccc", "#74a9cf", "#045a8d"]
},
"legend": { "title": "Minor allele frequency" }
}
}
}
}Variant display configuration
LinearVariantDisplay draws the records as a feature track does and, under
them, a multi-sample VCF's genotypes, one row per sample, each variant at its
genomic position or, with variantLayout: 'columns', in equal-width columns.
Preset its slots in a displays array; they are listed on
LinearVariantDisplay.
Configuring default display settings
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "diversity_panel",
"name": "Diversity Panel",
"uri": "https://yourhost/diversity.vcf.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearVariantDisplay",
"genotypes": { "reference": { "show": true } },
"filter": [{ "field": "minorAlleleFrequency", "gte": 0.05 }],
"rows": { "field": "sample", "axis": { "labels": true } }
}
]
}Edits config.json in the current folder. See JBrowse CLI with Desktop.
jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "diversity_panel",
"name": "Diversity Panel",
"uri": "https://yourhost/diversity.vcf.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearVariantDisplay",
"genotypes": { "reference": { "show": true } },
"filter": [{ "field": "minorAlleleFrequency", "gte": 0.05 }],
"rows": { "field": "sample", "axis": { "labels": true } }
}
]
}'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": "VariantTrack",
"trackId": "diversity_panel",
"name": "Diversity Panel",
"uri": "https://yourhost/diversity.vcf.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearVariantDisplay",
"genotypes": { "reference": { "show": true } },
"filter": [{ "field": "minorAlleleFrequency", "gte": 0.05 }],
"rows": { "field": "sample", "axis": { "labels": true } }
}
]
}genotypes.reference.showon paints reference alleles too; off (the default) leaves the row solid gray with only ALT alleles on top, which keeps overlapping variants readablerows.fieldissample(one row per sample, darker for homozygous) orhaplotype(one row per phased haplotype, named<sample> HP1,<sample> HP2, counting from 1). Each haplotype row is matched to its sample's name, so the rest ofrowsapplies in both modesfilteris a list of field tests:minorAlleleFrequencywithgtehides variants below an allele-frequency floor,missingnesswithltehides those above a no-call ceiling, and ajexl:string is an expression a variant must pass
Coloring cells by the variant
encoding.color paints every cell with an alt allele by the variant itself. A
value, a CSS color or a jexl expression, paints every alt cell of a variant,
the helper functions included. A
field gives each of its values a color, with a key. Three fields are the track
menu's Color by presets: impact for
consequence impact,
svType for SV type
and phaseSet for the phase set in phased mode. Any other field is read off the
record, such as INFO.CLNSIG or QUAL, and a variant with no value keeps the
default alt color.
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "diversity_panel",
"name": "Diversity Panel",
"uri": "https://yourhost/diversity.vcf.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearVariantDisplay",
"encoding": { "color": "impact" }
}
]
}Edits config.json in the current folder. See JBrowse CLI with Desktop.
jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "diversity_panel",
"name": "Diversity Panel",
"uri": "https://yourhost/diversity.vcf.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearVariantDisplay",
"encoding": { "color": "impact" }
}
]
}'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": "VariantTrack",
"trackId": "diversity_panel",
"name": "Diversity Panel",
"uri": "https://yourhost/diversity.vcf.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearVariantDisplay",
"encoding": { "color": "impact" }
}
]
}A number cuts into ranges with a threshold scale: scale.domain lists the cut
points and scale.range one color per range, one more than the cuts. Allele
frequency split into ultra-rare, rare, low-frequency and common:
"displays": [
{
"type": "LinearVariantDisplay",
"encoding": {
"color": {
"field": "INFO.AF",
"scale": {
"type": "threshold",
"domain": [0.001, 0.01, 0.05],
"range": ["#b2182b", "#ef8a62", "#67a9cf", "#2166ac"]
}
}
}
}
]Auto-coloring samples by metadata
Point the adapter's samplesTsvLocation at a TSV whose first column is name,
matching the VCF sample names, with any further columns as metadata:
name population region phenotype
SAMPLE001 EUR Western case
SAMPLE002 AFR Eastern control
SAMPLE003 EUR Western control
SAMPLE004 EAS Pacific caserows.color on the display names one of those columns, and each distinct value
gets a different palette color:
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "population_vcf",
"name": "Population VCF",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://yourhost/samples.vcf.gz",
"samplesTsvLocation": {
"uri": "https://yourhost/sample_metadata.tsv"
}
},
"displays": [
{
"type": "LinearVariantDisplay",
"rows": { "color": "population" }
}
]
}Edits config.json in the current folder. See JBrowse CLI with Desktop.
jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "population_vcf",
"name": "Population VCF",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://yourhost/samples.vcf.gz",
"samplesTsvLocation": {
"uri": "https://yourhost/sample_metadata.tsv"
}
},
"displays": [
{
"type": "LinearVariantDisplay",
"rows": { "color": "population" }
}
]
}'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": "VariantTrack",
"trackId": "population_vcf",
"name": "Population VCF",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://yourhost/samples.vcf.gz",
"samplesTsvLocation": {
"uri": "https://yourhost/sample_metadata.tsv"
}
},
"displays": [
{
"type": "LinearVariantDisplay",
"rows": { "color": "population" }
}
]
}- A column
rows.colornames that the TSV lacks logs a console warning and skips the coloring - Sample names match exactly. A TSV matching some of the VCF's samples draws
those and reports the ones it dropped; one matching none fails the track. The
usual cause is a prefixed or suffixed id,
1000GP_HG00096against a header namingHG00096
Linkage disequilibrium (LD) display
JBrowse draws a triangular heatmap of pairwise r² (or D') between variants, read from a table PLINK writes. Compute it over a single population panel: r² is a correlation across the samples in the file, so a pooled multi-population callset averages the block away.
An LDTrack draws the table. PlinkLDAdapter reads a plain .ld;
PlinkLDTabixAdapter reads a bgzipped, tabix-indexed .ld.gz and fetches only
the visible region. Filtering by allele frequency, Hardy-Weinberg or call rate
happens in plink when it writes the table. The
GWAS track guide has the
plink command, and the same file drives LD coloring on a GWAS track.
Goes in the tracks array of config.json. See Tracks.
{
"trackId": "ld_plink",
"name": "Linkage disequilibrium",
"uri": "https://yourhost/study.ld.gz",
"assemblyNames": ["hg38"]
}Edits config.json in the current folder. See JBrowse CLI with Desktop.
jbrowse add-track https://yourhost/study.ld.gz \
--trackId ld_plink \
--name "Linkage disequilibrium" \
--assemblyNames hg38In JBrowse Desktop, or in any running JBrowse Web session, open a view on this track’s assembly, then File → Open track... and, in Add a track from file or URL, enter:
- Main file:
https://yourhost/study.ld.gz
JBrowse reads the adapter and track type off the file name. Then fill in:
- Track name:
Linkage disequilibrium - Assembly:
hg38
Click Add.
Which metric, and how far to thin
encoding.color.field switches between two
reads of the same block, r2 on a red ramp and dprime on a blue one unless
encoding.color.scale.scheme names another:
- D' measures whether recombination has been seen between two markers, so it saturates near 1 wherever no recombinant haplotype has turned up. It recovers where crossing over stops, which finds an inversion's breakpoints
- r² measures how well one marker predicts the other, which also requires the two to be at similar frequency, so it draws the sharper boundary. It shows whether one marker can stand in for another
A threshold scale cuts the statistic into intervals, each one color. These are
LocusZoom's r² bins, the ones a GWAS track colors its points by
(GWAS track), so a triangle under a Manhattan plot
shares its key:
Goes in the tracks array of config.json. See Tracks.
{
"trackId": "ld_plink_bins",
"name": "Linkage disequilibrium, r² bins",
"uri": "https://yourhost/study.ld.gz",
"assemblyNames": ["hg38"],
"displayDefaults": {
"encoding": {
"color": {
"field": "r2",
"scale": {
"type": "threshold",
"domain": ["0.2", "0.4", "0.6", "0.8"],
"range": ["#357ebd", "#46b8da", "#5cb85c", "#eea236", "#d43f3a"]
},
"legend": { "descending": true }
}
}
}
}Edits config.json in the current folder. See JBrowse CLI with Desktop.
jbrowse add-track https://yourhost/study.ld.gz \
--trackId ld_plink_bins \
--name "Linkage disequilibrium, r² bins" \
--assemblyNames hg38 \
--displayDefaults '{"encoding":{"color":{"field":"r2","scale":{"type":"threshold","domain":["0.2","0.4","0.6","0.8"],"range":["#357ebd","#46b8da","#5cb85c","#eea236","#d43f3a"]},"legend":{"descending":true}}}}'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:
{
"trackId": "ld_plink_bins",
"name": "Linkage disequilibrium, r² bins",
"uri": "https://yourhost/study.ld.gz",
"assemblyNames": ["hg38"],
"displayDefaults": {
"encoding": {
"color": {
"field": "r2",
"scale": {
"type": "threshold",
"domain": ["0.2", "0.4", "0.6", "0.8"],
"range": ["#357ebd", "#46b8da", "#5cb85c", "#eea236", "#d43f3a"]
},
"legend": { "descending": true }
}
}
}
}Clicking a cell makes its SNP the index SNP: its row and column of the triangle light up, its LD to every other variant. Click empty space, or use Clear index SNP in the track menu, to clear it.
Thinning is set by plink's --maf when the table is written, reducing the dense
callset to the common, block-tagging variants. A --maf high enough to remove
the tagging variants themselves makes the block fade. Several haplotypes at one
locus fragment the block too, since no single pair of biallelic markers tags
them all, so a soft sweep reads patchier than its strength suggests.
See also
- User guide: Variant track
- User guide: Variant sample rows
- User guide: Structural variant visualization