Skip to content

Track catalogue

Every track type karyon draws, grouped by what it shows, with the Rust call that builds it and the command line flag that reads it. Each name links to its full entry: options, defaults and pitfalls.

All 38 work the same way. A track says how tall it wants to be and draws inside the band the figure gives it, on the shared horizontal scale, so any of them stacks with any other. Each has an add_ method on plot(), and each is also a type you can build yourself and hand over with add_track, or push onto a Figure, which is the way in for an alternative constructor or a track you want to query before it is drawn:

use karyon::{plot, read, CoverageTrack, Region};

let region = Region::parse("NC_000962.3:761,001-763,000")?;
let text = std::fs::read_to_string("depth.bedgraph")?;
let depth = CoverageTrack::from_spans(&region, read::signal::spans(&text, &region, None)?);

// genes: Vec<Feature>
plot("NC_000962.3:761,001-763,000")?
    .add_track(depth.label("depth"))
    .add_features(genes)
    .label("genes")
    .save("rpoB.svg")?;

On the command line, 35 of the 38 have a flag. Each flag starts a track, the options after it describe that track, and every track takes --label.

Signal and sequence

Signal and sequence tracks: values along the sequence, and the sequence itself.

Track Draws Rust Command line
CoverageTrack A value per base: depth, GC content, mappability .add_coverage(values) --coverage
WindowTrack A statistic in windows, either side of a baseline .add_windows(windows) --windows
MethylationTrack Methylation per site, one lane per strand .add_methylation(sites) --methylation
SequenceTrack The reference bases .add_sequence(seq) --sequence
LogoTrack A sequence logo, scored seven ways .add_logo(columns) --logo
DynseqTrack Model attribution as bases sized by their score .add_dynseq(start, seq, scores) --dynseq with --with-sequence

Annotation

Annotation tracks: what is annotated on the sequence.

Track Draws Rust Command line
FeatureTrack Genes and other intervals, packed into rows .add_features(features) --features
TranscriptionUnitTrack Transcripts from start site to terminator .add_transcription_units(units) none
OrfTrack Stops and open reading frames in six frames .add_orfs(seq) --orfs

Variation

Variation tracks: how samples differ from the reference and from each other.

Track Draws Rust Command line
VariantTrack Point calls as lollipops or ticks .add_variants(variants) --variants
GenotypeTrack The call of each sample at each site of a VCF, a row per sample .add_genotypes(samples, sites) --genotypes
StructuralTrack Structural calls as arcs between breakpoints .add_structural(variants) --structural
CopyNumberTrack Segmented copy number and lost heterozygosity .add_copy_number(segments, ploidy) --copy-number with --ploidy
SnpTrack The variable sites of an alignment, one row per sample .add_snps(names, sites) --snps
MatrixTrack A value per sample per site, or per window as a heatmap .add_matrix(sites, rows) --matrix, --heatmap
ManhattanTrack Association statistics against a threshold, or coloured by linkage with a lead .add_manhattan(points) --manhattan, with --ld
PairTrack Pairs of places as a triangle or as arcs: linkage, contacts, epistasis .add_pairs(pairs) --pairs
SelectionTrack Selection evidence above, the ω effect below .add_selection(sites) --selection

Reads and molecules

Read and molecule tracks: the evidence behind a call.

Track Draws Rust Command line
PileupTrack Aligned reads, with mismatches painted .add_pileup(reads) --pileup
SplitReadTrack Molecules that aligned in pieces .add_split_reads(reads) --split-reads
BisulfiteTrack Methylation one molecule at a time .add_bisulfite(sites, molecules) --bisulfite
JunctionTrack Splice junctions as arcs with read counts .add_junctions(junctions) --junctions
SquiggleTrack Raw nanopore current for one read .add_squiggle(signal) --squiggle

Comparison

Comparison tracks: one sequence against others.

Track Draws Rust Command line
MsaTrack A multiple alignment, differences painted .add_msa(sequences) --msa
DomainTrack Domain architectures, one protein per row .add_domains(rows) --domains
DotplotTrack Two sequences on two axes .add_dotplot(blocks) --dotplot
SyntenyTrack Alignment ribbons between two bars .add_synteny(blocks) --synteny
LocusTrack Gene neighbourhoods joined by homology .add_loci(loci) --loci with --links

Phylogeny

Phylogeny tracks: trees, and what is painted on them.

Track Draws Rust Command line
TreeTrack A phylogeny in three projections .add_tree(tree) --tree
TanglegramTrack Two trees face to face, shared tips joined .add_tanglegram(left, right) --tanglegram with --against
CladeTrack Genomic spans painted onto the clades carrying them .add_clades(tree, blocks) --clades with --with-tree

Evolution and surveillance

Evolution and surveillance tracks: time on the shared axis.

Track Draws Rust Command line
PhylodynamicTrack A trajectory through time, with its interval .add_phylodynamics(points) --phylodynamics
SurveillanceTrack Lineage counts or frequencies through time .add_surveillance(observations) --frequencies

Whole genome

Whole genome tracks: where a region sits, and figures across an assembly.

Track Draws Rust Command line
IdeogramTrack A whole chromosome, with the region marked .add_ideogram(length, bands) --ideogram
GenomeTrack The sequences of an assembly, end to end .add_genome(genome) none

Scales and keys

Scale and key tracks: what a figure is read by.

Track Draws Rust Command line
AxisTrack The coordinate ruler .add_axis() --axis
CodonTrack A ruler in codons, with the residues .add_codons(start, end, strand) --codons
LegendTrack A key to the colours, as a band .add_legend(legend) none

Coordinates

Positions in Rust are 0-based and half-open, the BED convention, so a GFF3 interval 759806..763325 is Feature::new(759_805, 763_325) and a VCF POS is POS - 1; the readers convert for you. The exceptions are what a reader sees: locus strings and ruler labels are 1-based and inclusive, as samtools and IGV write them. Not every axis is genomic either. An alignment counts columns, a variable-site panel counts sites, a squiggle counts samples, a domain track counts residues, the time tracks count time points, and a tree measures branch length across. See Coordinates.

Circular sequences

A plasmid, an organelle genome or a circular chromosome is drawn with Rings, which is not a track: it maps position to an angle rather than to a horizontal scale, puts annotation, signal, markers and a ruler on concentric rings, and draws chords across the middle to join the two ends of a rearrangement. A Rings plot and a Figure can share one Panels sheet. See The Rust API.

Metadata columns

Eight tracks draw a row per named thing, and each can carry columns of metadata beside its rows: MatrixTrack, GenotypeTrack, MsaTrack, SnpTrack, CladeTrack, DomainTrack and LocusTrack through .traits(...), and TreeTrack, which draws the same columns from its own annotations through trait_column. The track answers which ones; the columns say what they were.

use karyon::read;
use karyon::track::traits::Traits;
use karyon::{plot, MatrixRow, MatrixTrack};

let sheet = read::sheet::sheet(
    "sample\tlineage\thost\tdepth\n\
     S1\tL4\thuman\t72.5\n\
     S2\tL2\tbovine\t61\n\
     S3\tL4\t\t48.2\n",
)?;
let traits = Traits::new(sheet.rows).strips(sheet.columns);

let rows = vec![
    MatrixRow::new("S1", vec![1.0, 0.0]),
    MatrixRow::new("S2", vec![0.0, 1.0]),
    MatrixRow::new("S3", vec![1.0, 1.0]), // no host: its cell is an empty outline
];
plot("chr1:1-1,000")?
    .add_track(MatrixTrack::new(vec![120, 340], rows).traits(traits))
    .save("matrix.svg")?;
  • The join is by name, so the strips follow whatever order the rows are in, including the order a phylogeny put them in. A row the sheet says nothing about gets an empty outline, the one mark in a strip that cannot be mistaken for a level.
  • Traits::strips picks the mark. A column whose every stated value is a number gets a ramp; anything else gets the categorical palette, and a column with more levels than the palette has colours is drawn as TraitStyle::Symbol, which carries the level in a shape as well as a hue. That is decided in the theme the figure is drawn in, so a theme with more colours keeps it a strip, and Traits::colors or TraitColumn::colors gives levels colours of their own. Traits::colors reaches every column of its key, made before the call or after it, and the branches of a tree coloured by the key with no strip of it; from the command line it is --colors 'country=Peru:#e7298a,Kenya:#7570b3'. TraitColumn::categorical, continuous, bar, binary and symbol build a column by hand, for Traits::column.
  • Levels are coloured in the order the sheet lists them, never sorted, when the strip comes from Traits::from_sheet: a figure redrawn from the same file colours the same way, and a sample added at the end of the file does not repaint the others. Traits::new takes a map of rows and has no file order, so it deals the colours in the order the names sort. The key lists the levels as a reader looks them up, L1, L2, L4, L10, each in the colour the sheet dealt it, so the order a sheet happens to meet them in never reaches the reader.
  • One vocabulary. Every column Traits makes carries that order (TraitColumn::level_order), and a phylogeny handed the same column deals its colours the same way, so a lineage is one colour beside the tree, beside the matrix and in the key, which is most of the reason to put them in one figure. --traits does this for you.
  • Each column its own colours. Every column of words in a sheet deals its own stretch of the six colours, by its place in the sheet: two columns take three each and three take two, so a lineage and a country are never one colour while each fits its stretch. A column with more levels runs on into the next stretch, and the key names every colour by its column. The stretch goes by the sheet and not by what is drawn, so --columns never repaints, and not by how many levels come before, so an appended sample never does. TraitColumn::first_color sets where a column starts, and a phylogeny deals the columns it is given without a start, and the key its branches are coloured by, a stretch each the same way.
  • In Rust the key is yours to place. Traits::legend(&theme) builds one naming every level and both ends of every ramp, and TreeTrack::legend(&theme) does the same for a tree's branches and strips, each level drawn as its column draws it: a box, a shape, or the two dots of a binary column. Figure::key() gathers the tree's key in the figure's own theme. Where it goes, and whether the figure needs it, is yours to decide. The command line draws it under the figure, each colour once, unless --no-legend is given.

From the command line this is --traits FILE, and --columns A,B to choose and order the columns, after --matrix, --heatmap, --genotypes, --msa, --snps, --clades, --domains, --loci or --tree, with --colors COLUMN=VALUE:#HEX,... anywhere on the line for colours of your own. The sample sheet format is in File formats.

From the command line

The Command line column above maps each flag to its track. A few flags need company:

  • A second file. --dynseq needs --with-sequence, --tanglegram needs --against, --clades needs --with-tree and --loci needs --links, and each is refused without it. --pileup takes --with-sequence optionally, to find mismatches.
  • A choice inside the file. --methylation takes --modification, --bisulfite takes --context and --domains takes --analysis, for a file that holds several datasets; the command refuses to pick one for you.
  • A number the file does not hold. --copy-number needs --ploidy, since where balanced sits is not in the file.
  • A gene and its CDS. --codons reads no file of its own: it numbers the CDS the figure's annotation writes for the gene the figure is placed on, and takes its letters from the figure's --sequence.
  • Standard input. Any track file may be -, for one track per command, which is how CRAM gets in: samtools already writes the text these readers take. A BAM, a BCF, a bigWig, a bigBed, a 2bit and a .hic are named instead, since each is read out of order through an index.

Three tracks are library only. TranscriptionUnitTrack and GenomeTrack would need a table with no single standard behind it, and LegendTrack is built from what the other tracks drew rather than from a file; the command line draws that one by itself, under a figure with colours to key. The whole grammar is in Command line.

Where next

  • The Rust API

    The plot() builder and Figure, which every track here goes through.

  • Command line

    The grammar the flags above follow, and every option they take.

  • File formats

    What each reader accepts, column by column.

  • Writing a track

    What a new track type has to do, and why every track lives on the shared axis.