Reference

Complete prop reference for the SeqViz Dash component — every attribute, its type and default, and a Python example you can paste into a Dash app.

Try props interactively GitHub

Import: from dash_seqviz import SeqViz

All props are optional. Position and range fields (start, end) are zero-indexed base positions. Direction fields use 1 for forward strand, -1 for reverse, 0 for none. Want to drive every prop live? Open the component explorer.

Core

The minimum set to render a sequence.

id#

str

The identifier used to reference this component in Dash callbacks. Required if you intend to read or write the component's props from a callback.

SeqViz(
    id="my-seqviz",
    seq="ATGCATGCATGC",
)

seq#

str

The sequence to render. Accepts DNA, RNA, or amino-acid sequences. Case is preserved but not meaningful; whitespace is ignored.

SeqViz(seq="ATGCGTACGTTAGCGATCGATCGATAGCTAGCTAG")

name#

str

Display name for the sequence. Rendered in the center of the circular viewer, and used as a label elsewhere in the UI.

SeqViz(
    seq="...",
    name="pUC19",
)

viewer#

Literal["linear", "circular", "both", "both_flip"] default: "both"

Layout of the viewers. "both" shows circular on the left, linear on the right; "both_flip" swaps them. "linear" and "circular" render a single view.

SeqViz(seq="...", viewer="circular")

style#

dict (CSS)

CSS styles applied to the component's outer container. Almost always used to set height and width. It styles the box only, not the viewer's text: to change the font, use font.

SeqViz(
    seq="...",
    style={"height": "500px", "width": "100%", "border": "1px solid #e2e8f0"},
)

font#

dict

Viewer typography, using Dash Mantine's font style-prop keys. Applies to the sequence, labels, legend and tooltip:

  • ff (str): font-family (a CSS font stack). Use a monospace family so the linear sequence stays aligned; a proportional family shifts the per-base spacing.
  • fw (number | str): font-weight.

Font size is intentionally not here: seqviz derives it so bases line up with the ruler and feature blocks. To scale the linear view, use zoom. (seqviz sets its font inline, so font takes effect via a scoped style override, the same way the xkcd theme swaps its hand-drawn font.)

SeqViz(
    seq="...",
    font={"ff": "IBM Plex Mono, monospace", "fw": 500},
)

Content layers

Overlays that annotate or decorate regions of the sequence.

annotations#

list of dicts default: []

Named, optionally directional regions drawn as labeled arcs (circular) or bars (linear) above the sequence. Use for genes, CDS, promoters, terminators, RBS, etc.

{"start": int, "end": int, "name": str, "direction": Optional[Literal[1, -1, 0]], "color": Optional[str]}
SeqViz(
    seq="...",
    annotations=[
        {"start": 100, "end": 400, "name": "GFP",
         "direction": 1, "color": "#2a9d8f"},
        {"start": 450, "end": 500, "name": "Terminator",
         "direction": 0, "color": "#6c757d"},
    ],
)

primers#

list of dicts default: []

Directional primers rendered as arrows. direction is required: 1 for forward, -1 for reverse.

{"start": int, "end": int, "name": str, "direction": Literal[1, -1], "color": Optional[str]}
SeqViz(
    seq="...",
    primers=[
        {"start": 0,   "end": 22,   "name": "M13F",
         "direction": 1,  "color": "#2563eb"},
        {"start": 980, "end": 1000, "name": "M13R",
         "direction": -1, "color": "#e76f51"},
    ],
)

highlights#

list of dicts default: []

Colored background fills behind a range of bases. Useful for drawing attention to regions without labeling them.

{"start": int, "end": int, "color": Optional[str]}
SeqViz(
    seq="...",
    highlights=[
        {"start": 50, "end": 75, "color": "#fde68a"},
    ],
)

translations#

list of dicts default: []

Ranges whose amino-acid translation is drawn beneath the sequence. direction is required: 1 translates the forward strand, -1 the reverse strand.

{"start": int, "end": int, "direction": Literal[1, -1], "name": Optional[str], "color": Optional[str]}
SeqViz(
    seq="...",
    translations=[
        {"start": 100, "end": 499, "direction": 1, "name": "GFP ORF"},
    ],
)

enzymes#

list of (str | dict) default: []

Restriction enzymes whose recognition sites should be marked on the sequence. Pass built-in enzyme names as strings (250+ bundled with seqviz) or define custom enzymes with a dict.

str # built-in enzyme name {"name": str, "rseq": str, "fcut": int, "rcut": int, "color": Optional[str], "range": Optional[{"start": Optional[int], "end": Optional[int]}]}
# Built-in enzymes by name
SeqViz(seq="...", enzymes=["EcoRI", "BamHI", "HindIII"])

# Custom enzyme
SeqViz(
    seq="...",
    enzymes=[
        {"name": "MyCutter", "rseq": "GAATTC",
         "fcut": 1, "rcut": 5, "color": "#e76f51"},
    ],
)

Appearance

Colors, zoom, and layout details.

colors#

list of str default: []

Fallback palette for annotations, translations, and highlights that do not set their own color. Colors are assigned in order and wrap around.

SeqViz(
    seq="...",
    colors=["#2a9d8f", "#e76f51", "#f4a261", "#264653"],
    annotations=[
        {"start": 0,   "end": 100, "name": "A"},
        {"start": 200, "end": 300, "name": "B"},
    ],
)

bp_colors#

dict default: {}

Per-base coloring. Keys are either bases ("A", "T", "G", "C") for all occurrences, or integer indexes for coloring specific positions.

# Color every base by identity
SeqViz(
    seq="...",
    bp_colors={
        "A": "#ff6b6b", "T": "#4ecdc4",
        "G": "#ffe66d", "C": "#95e1d3",
    },
)

# Color only specific positions
SeqViz(seq="...", bp_colors={42: "#e76f51", 43: "#e76f51"})

zoom#

dict default: {"linear": 50}

Zoom level of the linear viewer. 0 is maximum overview (whole sequence in one row); 100 is base-level detail.

{"linear": Optional[int] # 0-100}
SeqViz(seq="...", zoom={"linear": 80})

show_complement#

bool default: True

Whether to render the complement strand beneath the sequence in the linear viewer. Set False for a single-strand view (useful for protein or RNA sequences).

SeqViz(seq="...", show_complement=False)

Behavior

Input and runtime knobs.

rotate_on_scroll#

bool default: True

When True, scrolling over the circular viewer rotates it. Set False so the page scrolls normally through the viewer — preferred when embedding inside a longer Dash layout.

SeqViz(seq="...", rotate_on_scroll=False)

disable_external_fonts#

bool default: False

Set True to skip downloading the external web fonts used by seqviz. Useful for offline or air-gapped deployments where font CDNs are unreachable.

SeqViz(seq="...", disable_external_fonts=True)

enable_copy_event#

bool default: True

When True, Ctrl/Cmd+C inside the viewer copies the currently selected sequence range to the clipboard. Set False to leave copy handling to the surrounding page.

SeqViz(seq="...", enable_copy_event=False)

enable_select_all_event#

bool default: True

When True, Ctrl/Cmd+A inside the viewer selects the entire sequence. Set False to defer to the browser's default Select-All.

SeqViz(seq="...", enable_select_all_event=False)

theme#

string default: "light"

Visual theme. seqviz hardcodes dark-gray text and ticks tuned for light backgrounds, so on a dark dashboard the annotation labels, index numbers, and ticks lose contrast. A dark theme recolors those for legibility; the colorblind themes additionally apply a CVD-safe qualitative palette to un-colored annotations (per-annotation color always wins).

  • "light" (default) — seqviz default.
  • "dark" — text / ticks / selector recolored for dark backgrounds.
  • "auto" — follow the page: detects data-mantine-color-scheme on <html> (a dash-mantine-components theme switch) and updates live, falling back to prefers-color-scheme. Zero-boilerplate for Mantine dashboards.
  • "okabe-ito-light", "okabe-ito-dark" — Okabe & Ito's 7-color CVD-safe palette.
  • "colorbrewer-light", "colorbrewer-dark" — ColorBrewer Set2 / Dark2.
  • "tol-light", "tol-dark" — Paul Tol's Bright palette.

Made it this far? There's also an undocumented "xkcd" (aka "xkcd-light" / "xkcd-dark") theme that renders the viewer hand-drawn, xkcd-comic style — a little reward for reading the reference.

from dash import Input, Output, callback

# follow a dash-mantine-components theme switch with zero boilerplate
SeqViz(id="seqviz", seq="...", theme="auto")

# or drive it explicitly from a control
@callback(Output("seqviz", "theme"), Input("scheme", "value"))
def set_theme(scheme):
    return "dark" if scheme == "dark" else "light"

max_seq_length#

number

Guard for very long sequences. seqviz's linear viewer renders per-base DOM and can hang the tab on multi-megabase input. When set and the sequence length exceeds it, the component renders a lightweight placeholder instead of mounting the viewer. Omit for no guard; for very long sequences that must render, prefer viewer="circular".

SeqViz(seq=genome, max_seq_length=500_000, viewer="circular")

aria_label#

string

Accessible name for the viewer. seqviz renders an unlabeled SVG, so the component gives its container role="group" with this label (and labels the circular SVG role="img"). Defaults to an auto-generated summary such as "Sequence viewer: pUC19, 2,686 bp, 4 annotations". Note: seqviz provides no keyboard navigation of individual features, so this is screen-reader labeling only.

SeqViz(seq="...", name="pUC19", aria_label="pUC19 cloning vector map")

State & events

Props you read from — or write to — in Dash callbacks.

selection#

dict

The currently selected range. Read via Input(..., "selection") to react to user selections, or write via Output(..., "selection") to programmatically select a range.

{"start": int, "end": int, "clockwise": Optional[bool]}
from dash import Input, Output, callback

@callback(
    Output("info", "children"),
    Input("seqviz", "selection"),
)
def show_selection(sel):
    if not sel:
        return "No selection"
    return f"Selected {sel['start']} - {sel['end']}"

search_results#

list read-only

Match ranges produced by the search prop. Updated by the component; treat as read-only.

@callback(
    Output("hit-count", "children"),
    Input("seqviz", "search_results"),
)
def count_hits(results):
    return f"{len(results or [])} matches"

on_selection#

function

JavaScript callback invoked on every selection change. Passed through to the underlying seqviz library for JS-only consumers — in a Dash app, prefer reading the selection prop via Input.

clicked_element#

dict read-only

The most recently clicked feature (annotation, primer, enzyme, translation, highlight, or search hit). Updates only on feature clicks — bare sequence selections leave it unchanged — so Input(..., "clicked_element") gives clean feature-click events for linked views. (seqviz exposes no hover or center-index callbacks, so those are not available.)

{"type": str, "name": str, "start": int, "end": int, "direction": int, "id": str, "color": str}
@callback(
    Output("info", "children"),
    Input("seqviz", "clicked_element"),
)
def show_clicked(el):
    return el["name"] if el else "Click a feature"

legend#

bool | dict

Render a built-in, interactive legend on any side of the viewer. Set True for defaults or a dict for finer control; options follow Dash Mantine conventions (position on any of the four sides, and size / spacing / radius / p as xsxl tokens or raw pixels). Interaction mirrors Plotly legends: click an item to hide/show that element, double-click to isolate it (hide the rest), and double-click the isolated item again to restore all. Swatch colors match what the viewer draws (theme palettes included); toggled-off items are reflected in hidden_elements.

{"show": bool, "title": str, "position": "top" | "right" | "bottom" | "left", "direction": "vertical" | "horizontal", "align": "start" | "center" | "end", "size": "xs".."xl", "spacing": "xs".."xl" | int, "radius": "xs".."xl" | int, "withBorder": bool, "p": "xs".."xl" | int, "categories": list of "annotations" | "translations" | "primers" | "highlights"}
SeqViz(
    id="seqviz",
    seq=seq,
    annotations=anns,
    primers=primers,
    legend={"position": "right", "title": "Features",
            "size": "md", "radius": "sm", "withBorder": True},
)

hidden_elements#

list of str

Keys of the legend items currently toggled off, each "<category>:<name>" (or "<category>:<index>" for unnamed items such as highlights). The component updates it as the user clicks the legend, so a callback can observe which elements are hidden. Set it from a callback to control visibility programmatically.

@callback(
    Output("hidden-info", "children"),
    Input("seqviz", "hidden_elements"),
)
def show_hidden(hidden):
    return f"{len(hidden or [])} element(s) hidden"

tooltip#

bool | dict

Show a Plotly-style hover tooltip on annotations. Set True for the default (name plus coordinates) or a dict to supply a hovertemplate. The hovertemplate fills %{field} placeholders per annotation and accepts <br> (or a newline) for line breaks; the first line is emphasized. Available fields: %{name}, %{start}, %{end}, %{length} (bp), %{direction} (forward / reverse / none), %{color}, %{type}. Substituted values render as plain text, so element names cannot inject markup.

Custom data. Pass a customdata list parallel to annotations (row i belongs to annotation i) and reference it positionally, exactly like Plotly: %{customdata[0]}, %{customdata[1]}.

{"show": bool, "hovertemplate": str}
anns = [{"start": 0, "end": 100, "name": "lacZ", "direction": 1}]

SeqViz(
    id="seqviz",
    seq=seq,
    annotations=anns,
    customdata=[["b0344", "beta-galactosidase"]],
    tooltip={"hovertemplate": "%{name} (%{customdata[0]})<br>%{customdata[1]}"},
)

customdata#

list

Extra per-annotation data for the hover tooltip, mirroring Plotly's customdata. A list parallel to annotations: customdata[i] holds the data for annotations[i] (usually itself a list), referenced in the tooltip hovertemplate by position, e.g. %{customdata[0]}, %{customdata[1]}.

SeqViz(
    annotations=[a0, a1],
    customdata=[["b0344", "lacZ"], ["b0345", "lacY"]],
    tooltip={"hovertemplate": "%{name}: %{customdata[0]}"},
)

export_request#

dict

Write this to trigger a figure export. The component serializes the current viewer (theme and colors preserved) and puts a data URI in export_result. Include a changing token so repeated exports of the same format re-fire. scale (PNG only, default 2) sets the raster resolution multiplier.

{"format": "svg" | "png", "token": Any, "scale": Optional[number]}
from dash import Input, Output, ctx, callback

@callback(
    Output("seqviz", "export_request"),
    Input("svg-btn", "n_clicks"), Input("png-btn", "n_clicks"),
    prevent_initial_call=True,
)
def export(svg_n, png_n):
    fmt = "svg" if ctx.triggered_id == "svg-btn" else "png"
    return {"format": fmt, "token": (svg_n or 0) + (png_n or 0)}

export_result#

string read-only

The most recent export as a data URI (data:image/svg+xml,… or data:image/png;base64,…). Feed it to a download — e.g. set it as the href of an html.A(download=…). SVG is vector (best for papers/posters); PNG rasterizes at scalex.

@callback(
    Output("dl", "href"), Output("dl", "download"),
    Input("seqviz", "export_result"), prevent_initial_call=True,
)
def to_download(uri):
    ext = "png" if uri.startswith("data:image/png") else "svg"
    return uri, f"figure.{ext}"

Dash internal

Managed automatically by Dash — you do not set these yourself.

setProps#

function internal

Dash supplies this automatically so the component can report prop changes back to the Python callback layer. You never set this manually.

Python helpers

Importable helpers that ship with dash_seqviz — not component props. from dash_seqviz import parse, fetch_ncbi, legend, validate_props.

parse()#

helper

seqviz deprecated its in-browser file / accession props; parse records in Python instead. parse(source, fmt=None, *, record=0, include_translations=True) reads a FASTA/GenBank path, an open handle, or a raw string and returns a props dict (seq, name, annotations, translations) ready to spread into the component. Requires Biopython.

from dash_seqviz import SeqViz, parse

props = parse("plasmid.gb")          # format auto-detected
SeqViz(id="viewer", **props)

fetch_ncbi()#

helper

Fetch a GenBank record from NCBI by accession and run it through parse(). NCBI's E-utilities require a contact email: pass email= or set NCBI_EMAIL (optional api_key= / NCBI_API_KEY raises the rate limit).

from dash_seqviz import SeqViz, fetch_ncbi

props = fetch_ncbi("MN623123.1", email="you@example.com")
SeqViz(id="viewer", **props)

legend()#

helper

Return a Dash layout (html.Div of swatch + name rows) whose colors match what the viewer renders for the same annotations and theme. legend(annotations, *, theme=None, colors=None, title=None, direction="vertical"). Pair with clicked_element to highlight the clicked feature.

Pass a flat list for a single legend, or a mapping of section label to items to facet the legend by element type (annotations, primers, translations, highlights) — one titled section per key.

from dash import html
from dash_seqviz import SeqViz, legend

html.Div([
    SeqViz(id="v", seq=seq, annotations=anns, primers=primers, theme="okabe-ito-light"),
    # flat legend:
    legend(anns, theme="okabe-ito-light", title="Features"),
    # or faceted by element type:
    legend({"Annotations": anns, "Primers": primers}, theme="okabe-ito-light"),
])

validate_props()#

helper

Optional runtime check for element lists, raising a clear ValueError (missing keys, start > end, bad direction) before a silent mis-render reaches the browser. The package also ships TypedDicts (Annotation, Primer, Highlight, Translation, Enzyme) for editor autocomplete.

from dash_seqviz import Annotation, validate_props

anns: list[Annotation] = [{"start": 0, "end": 22, "name": "promoter", "direction": 1}]
validate_props(annotations=anns)

integrations.mlflow#

optional

log_seqviz(config, artifact_file="seqviz.html") logs a SeqViz view to the active MLflow run as an interactive .html artifact (rendered inline in the MLflow UI) — following the same convention as mlflow.log_figure. log_variants() logs several variants of one sequence as comparable runs (shared seq_sha256 tag + feature metrics). Install with pip install dash-seqviz[mlflow].

import mlflow
from dash_seqviz.integrations import mlflow as mlflow_seqviz

with mlflow.start_run():
    mlflow_seqviz.log_seqviz({"name": "pUC19", "seq": seq, "annotations": [...]})