GWAS track
A GWASTrack renders association results as a Manhattan plot. The main work is
prep: a bgzipped, tabix-indexed BED-like file whose score column is in -log₁₀(p)
units (or set scoreTransform to convert). Add a PLINK .ld file to color
points by linkage disequilibrium to an index SNP. The plot is a
mark display whose default plot is a point
per SNP at its score, so its marks, scales, facets and rows all apply, and any
FeatureTrack can draw the same plot from one of its numeric columns — see
any scored feature file.
Preparing the GWAS file
GWASAdapter reads a bgzipped, tabix-indexed BED-like file with a #-prefixed
header row whose score column is in -log₁₀(p) units.
scoreTransform converts a raw
p-value column (negLog10) or a natural-log one (negLog10FromLn, a Pan-UKBB
ln P column) at read time. The name column (4th BED field) is the SNP id LD
lookups key on; without it they fall back to chr:bp (1-based).
#chrom chromStart chromEnd name neg_log_pvalue
chr1 109817590 109817591 rs4970383 1.234
chr1 110162459 110162460 rs4971059 7.891Prefix the header so tabix skips it, then sort, bgzip and index:
sed '1s/^/#/' results.tsv | jbrowse sort-bed | bgzip > results.sorted.txt.gz
tabix -p bed results.sorted.txt.gzjbrowse sort-bed is sort -k1,1 -k2,2n under LC_ALL=C with every # line
kept on top. A .txt.gz auto-detects as GWASAdapter in the Add track dialog;
another extension such as .bed.gz needs the adapter picked by hand.
Preparing the LD file
LD data is PLINK's --r2 table, from a binary fileset (--bfile study) or a
VCF (--vcf study.vcf.gz):
# "dprime" adds the D' column (DP)
plink --bfile study --r2 dprime with-freqs \
--ld-window 99999 --ld-window-kb 1000 --ld-window-r2 0 \
--out study--ld-window-r2 0keeps every pair; PLINK otherwise drops pairs below r²=0.2. The--ld-window*flags bound how far apart paired SNPs may be, so tune them to the span you want drawndprimealso switches r² to the haplotype-frequency estimate, so the R2 column of a run with it and a run without it are two different statistics- This is PLINK 1.9; plink2 replaced
--r2with--r2-phasedand--r2-unphased
A regional study.ld loads as-is with
PlinkLDAdapter. For chromosome-scale or
genome-wide LD, bgzip and tabix it and use
PlinkLDTabixAdapter, which fetches only
the pairs in view; its page has the retab, sort-bed and tabix commands and
why the header is commented with #.
Example
A plot naming r2 or ld_role joins each SNP's r² to the index SNP from the
GWASAdapter's ldAdapter; swap in PlinkLDTabixAdapter for an indexed
.ld.gz. The first mark below colors every other point by r² in LocusZoom's
five bins, and the second draws the index SNP alone as a pink diamond on top.
The track menu's LD → Color by LD to index SNP makes the same pair of each
point mark of the plot, keeping its size, steps and the other marks, and
right-clicking a point pins it as the index
(LinearManhattanDisplay):
Goes in the tracks array of config.json. See Tracks.
{
"type": "GWASTrack",
"trackId": "sle_gwas",
"name": "SLE GWAS",
"assemblyNames": ["hg19"],
"adapter": {
"type": "GWASAdapter",
"uri": "https://yourhost/sle.bed.gz",
"scoreColumn": "neg_log_pvalue",
"ldAdapter": {
"type": "PlinkLDAdapter",
"uri": "https://yourhost/sle.ld"
}
},
"displayDefaults": {
"marks": [
{
"mark": "point",
"transform": [
{ "type": "filter", "expr": "jexl:feature.ld_role != 'index'" }
],
"encoding": {
"y": "score",
"color": {
"field": "r2",
"scale": "threshold",
"domain": [0.2, 0.4, 0.6, 0.8],
"range": ["#357ebd", "#46b8da", "#5cb85c", "#eea236", "#d43f3a"],
"title": "r² to index SNP",
"descending": true,
"missingLabel": "No LD data"
}
}
},
{
"mark": "point",
"transform": [
{ "type": "filter", "expr": "jexl:feature.ld_role == 'index'" }
],
"encoding": {
"y": "score",
"color": { "value": "#c951c9" },
"shape": {
"field": "ld_role",
"domain": ["index"],
"range": ["diamond"],
"labels": ["Index SNP"],
"title": ""
}
}
}
]
}
}jbrowse add-track-json '{
"type": "GWASTrack",
"trackId": "sle_gwas",
"name": "SLE GWAS",
"assemblyNames": ["hg19"],
"adapter": {
"type": "GWASAdapter",
"uri": "https://yourhost/sle.bed.gz",
"scoreColumn": "neg_log_pvalue",
"ldAdapter": {
"type": "PlinkLDAdapter",
"uri": "https://yourhost/sle.ld"
}
},
"displayDefaults": {
"marks": [
{
"mark": "point",
"transform": [
{ "type": "filter", "expr": "jexl:feature.ld_role != '\''index'\''" }
],
"encoding": {
"y": "score",
"color": {
"field": "r2",
"scale": "threshold",
"domain": [0.2, 0.4, 0.6, 0.8],
"range": ["#357ebd", "#46b8da", "#5cb85c", "#eea236", "#d43f3a"],
"title": "r² to index SNP",
"descending": true,
"missingLabel": "No LD data"
}
}
},
{
"mark": "point",
"transform": [
{ "type": "filter", "expr": "jexl:feature.ld_role == '\''index'\''" }
],
"encoding": {
"y": "score",
"color": { "value": "#c951c9" },
"shape": {
"field": "ld_role",
"domain": ["index"],
"range": ["diamond"],
"labels": ["Index SNP"],
"title": ""
}
}
}
]
}
}'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": "GWASTrack",
"trackId": "sle_gwas",
"name": "SLE GWAS",
"assemblyNames": ["hg19"],
"adapter": {
"type": "GWASAdapter",
"uri": "https://yourhost/sle.bed.gz",
"scoreColumn": "neg_log_pvalue",
"ldAdapter": {
"type": "PlinkLDAdapter",
"uri": "https://yourhost/sle.ld"
}
},
"displayDefaults": {
"marks": [
{
"mark": "point",
"transform": [
{ "type": "filter", "expr": "jexl:feature.ld_role != 'index'" }
],
"encoding": {
"y": "score",
"color": {
"field": "r2",
"scale": "threshold",
"domain": [0.2, 0.4, 0.6, 0.8],
"range": ["#357ebd", "#46b8da", "#5cb85c", "#eea236", "#d43f3a"],
"title": "r² to index SNP",
"descending": true,
"missingLabel": "No LD data"
}
}
},
{
"mark": "point",
"transform": [
{ "type": "filter", "expr": "jexl:feature.ld_role == 'index'" }
],
"encoding": {
"y": "score",
"color": { "value": "#c951c9" },
"shape": {
"field": "ld_role",
"domain": ["index"],
"range": ["diamond"],
"labels": ["Index SNP"],
"title": ""
}
}
}
]
}
}Any scored feature file
LinearManhattanDisplay is also a display of FeatureTrack, so a selection
scan, a QTL table or any BED-like file with a numeric column draws as a
Manhattan plot without a GWASTrack or a GWASAdapter. Name the display in the
track's displays (it is also offered under the track menu's Display
types), and its point mark chooses what it reads:
encoding.y— the column plotted as y. The defaultscoreis the BED score column (or what the adapter'sscoreColumnrewrote it to); an explicit name reaches a raw column of the file. A feature with no finite value there is skipped.encoding.color: { "field": "population" }— gives each distinct value of a column its own color and draws a key of the values met. A value takes the same color in every region and session. Itsdomainis the order those values take, in the key and in the colors: the values it lists come first, in that order, and the rest follow sorted, andrangehands them colors.
The track menu's Edit plot... edits both, and encoding.size is the point
diameter in px. A point stands at the middle of its window; "mark": "rule"
draws the window across its extent, encoding.size px thick.
Goes in the tracks array of config.json. See Tracks.
{
"type": "FeatureTrack",
"trackId": "fst_scan",
"name": "Fst scan",
"uri": "https://yourhost/fst.bed.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearManhattanDisplay",
"marks": [
{
"mark": "point",
"encoding": { "y": "fst", "color": { "field": "population" } }
}
],
"scales": { "y": { "rules": [0.25] } }
}
]
}jbrowse add-track-json '{
"type": "FeatureTrack",
"trackId": "fst_scan",
"name": "Fst scan",
"uri": "https://yourhost/fst.bed.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearManhattanDisplay",
"marks": [
{
"mark": "point",
"encoding": { "y": "fst", "color": { "field": "population" } }
}
],
"scales": { "y": { "rules": [0.25] } }
}
]
}'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": "fst_scan",
"name": "Fst scan",
"uri": "https://yourhost/fst.bed.gz",
"assemblyNames": ["hg38"],
"displays": [
{
"type": "LinearManhattanDisplay",
"marks": [
{
"mark": "point",
"encoding": { "y": "fst", "color": { "field": "population" } }
}
],
"scales": { "y": { "rules": [0.25] } }
}
]
}