jbrowsemsa

A notebook widget for react-msaview: a multiple sequence alignment beside its phylogenetic tree, in JupyterLab, Jupyter Notebook, VS Code and any other host anywidget supports. The distribution and the import are both jbrowsemsa.

The globin alignment and tree

Install

The wheel ships the widget’s JavaScript, which a checkout builds first:

pnpm install
pnpm --filter jbrowsemsa build
pip install packages/python

Quick start

from jbrowsemsa import MSAView

view = MSAView(msa="globin.aln", tree="globin.nh", hide_header=True)
view

Setting a trait updates the widget in place and keeps its scroll and zoom:

view.color_scheme = "clustal"
view.highlights = [{"row": "Human_beta", "start": 64, "end": 64, "label": "distal His"}]

Traits

The traits are the MSAViewer props in USAGE.md, in snake case. highlights and column_tracks take the JSON shapes in docs/layers.md.

TraitValue
msa, tree, gffdocument text or a file path
msa_url, tree_url, gff_urla URL the viewer fetches
msa_filehandle, tree_filehandle, gff_filehandlea JBrowse FileLocation dict, which wins over the URL
color_schemea scheme name, such as "clustal", or a dict of residue letter to color
heightpixels
col_width, row_heightpixels per column and per row
highlightslist of {start, end}, {row, start, end} or {rows}
featureslist of {row, start, end, ...} features, or a DataFrame with those columns
cladeslist of {mrca or range, tips, mark} clades of the tree to mark
highlight_columnscolumns (1-based, like highlights), one band per run of adjacent columns
residue_mappingswhich structure residue each row residue is
column_trackslist of bar, text or arc tracks
row_dataextra fields per row name, such as a lineage or a host
encodings{channel, field, range, domain, title}: tipLabel, rowTint, branch, featureFill, featureLabel
row_panelsstrip and features panels drawn beside the tree
relative_toa row name; other rows draw as their differences from it
region{start, end} columns or {row, start, end} residues
selectionthe selected block, {start, end} columns and optional rows names (see below)
allowed_gappynesshide columns at least this percent gaps (default 100)
draw_tree, show_branch_lenbooleans, default True
tree_order"branchLength" (default), "input", "ladderize" or "ladderizeReverse"
tree_root"midpoint", or outgroup tip names: one name or a list
tree_area_widthpixels; unset fits the gutter to the labels and the tree
residue_encoding"fill" (default) paints the cell; "color" paints the letter
hide_headerboolean, default False
theme"auto" (default), "light", "dark" or MUI theme options

theme="auto" follows JupyterLab’s and Notebook 7’s data-jp-theme-light attribute, then VS Code’s data-vscode-theme-kind, then the browser’s prefers-color-scheme, and switches when the host does.

The widget sets three traits from the browser:

  • clicked: the cell a click pinned, {column, row, residue, letter}, or None after a click clears it
  • viewport: the columns on screen, {startColumn, endColumn}, once a scroll or zoom settles
  • selection: the block the person selected, {start, end, rows}, once a drag settles, or None after Escape clears it

All three are 1-based. column, start and end count every column of the alignment, residue counts the clicked row’s own letters, and rows names the selected rows, absent when the block spans every row. A shift-drag on the alignment selects a block, and a drag along a track selects columns across every row. selection is also an input: assigning it selects that block in the viewer. The widget keeps hover in the browser, since a comm message per pointer move would flood the kernel.

view.observe(lambda change: print(change["new"]), "clicked")

Saving a figure

save() writes the widget to a .svg, .png or .pdf file with every layer it draws, through react-msaview-cli:

  • It needs Node.js, and runs npx --yes react-msaview-cli unless cli= names another command, such as ["react-msaview-cli"] for an installed copy
  • PNG and PDF need rsvg-convert from librsvg
  • The figure is the entire alignment; width sets the pixel width of the view the tree and labels lay out in, and scale the pixels per SVG unit of a PNG
  • theme="auto" saves as light
view.save("globin.pdf")
view.save("globin.png", scale=3)

Python inputs

The package converts only what JSON cannot carry:

  • msa= takes a dict of name to aligned sequence, a Biopython MultipleSeqAlignment, or a Bio.Align.Alignment
  • tree= takes a Bio.Phylo tree
  • msa=, tree= and gff= take a pathlib.Path or a filename string
  • a column track’s values takes a numpy array or pandas Series, and a NaN in it draws no bar

Examples

examples/01_quickstart.ipynb opens the globin alignment from packages/examples/data. examples/02_entropy_and_clicks.ipynb draws per-column Shannon entropy as a bar track, highlights the columns above an ipywidgets slider’s threshold, and prints the letter each row has at a clicked column.

Entropy track and highlighted columns
Influenza drift in a notebook is the long version: 25 H3N2 vaccine strains from NCBI, aligned, with a per-column count of how often each column changed and a band on each antigenic site.

scripts/run_examples.py executes both notebooks in a kernel, and scripts/screenshot_examples.mjs renders the widgets they built into docs/media:

pip install -e "packages/python[examples]"
python packages/python/scripts/run_examples.py

Development

pip install -e "packages/python[dev]"
pytest packages/python/tests
pnpm vitest run packages/python