Getting started¶
Build a point chart from a Python table, then apply the same grammar to genomic intervals. The examples use plain Python records, so you do not need pandas or prior genomics knowledge.
GenomeSpy uses a declarative visualization grammar: you describe what the chart should show, and GenomeSpy determines how to draw it. A chart description has three central ingredients:
data: the values you want to show;
a mark: the shape used to represent a row, such as a point or rectangle;
encodings: rules that map data fields to visible properties.
Your Python objects become a validated GenomeSpy specification, which the browser renders. The specification follows the GenomeSpy visualization grammar, so its documentation applies to the charts you write here.
Install¶
GenomeSpy Python requires Python 3.11 or newer.
From PyPI¶
pip install genome-spy-python
For notebook use, install the Arrow extra so PyArrow is available for dataframe transport:
pip install "genome-spy-python[arrow]"
From source¶
pip install uv
git clone https://github.com/genome-spy/genome-spy-python.git
cd genome-spy-python
uv sync
Notebook rendering loads the pinned GenomeSpy JavaScript bundle from a CDN, so the browser needs network access when a chart first appears.
Start a notebook and import the package:
import genome_spy as gs
Start with a small table¶
This table contains six records, represented by Python dictionaries. Each
record is one row. The keys day, value, and group name the table’s
fields, or columns.
measurements = [
{"day": 1, "value": 4.2, "group": "A"},
{"day": 1, "value": 3.4, "group": "B"},
{"day": 2, "value": 5.1, "group": "A"},
{"day": 2, "value": 4.6, "group": "B"},
{"day": 3, "value": 5.8, "group": "A"},
{"day": 3, "value": 5.2, "group": "B"},
]
Choose a mark¶
A point mark asks GenomeSpy to draw one point for every record:
points = gs.Chart(measurements).mark_point(size=100)
Without positional encodings, all six points overlap. An encoding assigns each point a position.
Map fields to visual channels¶
A channel is the visual property controlled by an encoding. The x channel
controls horizontal position:
positioned_points = points.encode(x=gs.X("day:O"))
The text "day:O" contains a field name and a type code. A data type tells
GenomeSpy how values should behave:
Code |
Type |
Use it for |
|---|---|---|
|
quantitative |
Numeric amounts that can be compared mathematically |
|
nominal |
Unordered names or categories |
|
ordinal |
Values with a meaningful order or sequence |
Day is ordinal because day 1 comes before day 2. The measured value is quantitative, while the groups are nominal categories:
encoded_points = positioned_points.encode(
y=gs.Y("value:Q"),
color=gs.Color("group:N"),
)
The explicit gs.Y("value", type="quantitative") form means the same thing as
gs.Y("value:Q"). The shorthand is convenient once the type codes are
familiar.
Adjust scales and guides¶
A scale converts data values into positions, colors, or sizes. An axis is the visible guide for a positional scale, while a legend explains a color, size, or shape scale.
Guide titles label the mappings. Setting zero=False lets the vertical scale
focus on the observed values instead of including zero:
measurement_chart = encoded_points.encode(
x=gs.X("day:O").title("Day"),
y=gs.Y("value:Q").scale(zero=False).title("Measured value"),
color=gs.Color("group:N").legend(title="Group"),
)
Make a genomic interval track¶
GenomeSpy extends the same grammar with chromosome-aware positions. A genomic interval describes a span from a start position to an end position on a chromosome.
The example uses three intervals on chromosome 17:
features = [
{"chrom": "chr17", "start": 43_044_000, "end": 43_050_000, "kind": "A"},
{"chrom": "chr17", "start": 43_057_000, "end": 43_061_000, "kind": "B"},
{"chrom": "chr17", "start": 43_068_000, "end": 43_075_000, "kind": "A"},
]
Use a rectangle mark for each interval. The x encoding maps the start, and
x2 maps the other edge of the rectangle:
genomic_track = (
gs.Chart(features)
.mark_rect()
.encode(
x=gs.Locus("chrom", "start").scale(
domain=[
{"chrom": "chr17", "pos": 43_040_000},
{"chrom": "chr17", "pos": 43_080_000},
]
),
x2=gs.Locus("chrom", "end"),
y=gs.Y("kind:N").title("Feature kind"),
color=gs.Color("kind:N").legend(None),
)
.properties(assembly="hg38")
)
gs.Locus("chrom", "start") combines a chromosome field and a position field
into a locus, meaning a place in the genome. The hg38 genome assembly
supplies the chromosome names, lengths, and order needed by the locus scale.
The scale’s domain chooses the region the chart opens on. Without it the view
would span all three billion bases of the assembly, leaving these features too
small to see. Drag and scroll the chart to move beyond that opening window.
These example intervals use zero-based, half-open coordinates: the start is included and the end is excluded. This is the convention used by formats such as BED. Other formats may require a coordinate offset, as described in genomic coordinates.
Where to go next¶
Start the user guide with data and chart inputs.
Learn more about encodings and channels.
Read about genomic axes and intervals.
Combine linked tracks with composition.
Browse complete applications in the example gallery, or try the packaged datasets behind them.
Save and inspect charts writes the generated specification with
to_dict(),to_json(), andsave().Advanced: update a displayed chart without rebuilding it.
Consult the GenomeSpy documentation for the complete grammar. This guide teaches a subset; every property it describes is available here through the same names.