Centromere and Satellites#

This is a demonstration of the downstream analysis after using vampire anno to annotate a TR locus across population.

[!NOTE] You can download this notebook by clicking the Download button in the upper-right corner of this page and selecting the .ipynb format.

import numpy as np
import vampire as vp
import logging
import plotly.io as pio
pio.renderers.default = "notebook_connected"

Set up logging for intermediate information.

vampire_logger = logging.getLogger("vampire")
vampire_logger.setLevel(logging.INFO) # set level to "DEBUG", "INFO", "WARNING"
if not vampire_logger.handlers:
    handler = logging.StreamHandler()
    handler.setFormatter(
        logging.Formatter(
            "[%(asctime)s] %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )
    )
    vampire_logger.addHandler(handler)

Set the default plot style for all the plots in this notebook. You can set font_size, font_family, line_width, height, width, showgrid to set default parameters.

vp.anno.pl.set_default_plotstyle()

Importing Data#

Reading BEDGraph(read_bedgraph#

Use read_bedgraph to load standard BEDGraph files, including .bedgraph and .bedgraph.gz.

Expected columns:

Column

Meaning

chrom

chromosome name

start

0-based start position

end

end position (exclusive)

value

signal value

lf = read_bedgraph("example.bedgraph")

Since this returns a pl.LazyFrame, Nothing is computed when reading.

To trigger computation:

df = lf.collect()
print(df)

# Example: filtering high signal regions
df = (
    read_bedgraph("example.bedgraph")
    .filter(pl.col("value") > 10)
    .collect()
)

Reading BED files (read_bed)#

Use read_bed to load standard bed / bed.gz files.

Expected minimal BED columns:

Column

Meaning

chrom

chromosome

start

start position

end

end position

Optional BED fields are also supported:

  • name

  • score

  • strand

  • thickStart / thickEnd

  • itemRgb

  • blockCount / blockSizes / blockStarts

Reading indexed BED files (read_indexed_bed)#

Use read_indexed_bed when working with compressed and indexed BED files (.bed.gz + .tbi).

This function allows fast random access queries by genomic region.

Your file must have:

  • .bed.gz

  • .bed.gz.tbi (corresponding index file)

lf = read_indexed_bed(
    bed_file="example.bed.gz",
    chrom="chr1",
    start=1_000_000,
    end=2_000_000,
)

df = lf.collect()

Custom column annotations#

All three functions (read_bedgraph, read_bed, read_indexed_bed) support a columns parameter, which allows you to customize column names and data types.

This is useful when:

  • Your BED/BEDGraph has non-standard extra columns

  • You want to rename fields for downstream analysis

  • You need strict type enforcement for performance or correctness

  • You are working with tool-specific BED extensions

Here we use the result file generated by ModDotPlot as an example. When we want to visualize the 2D identity heatmap, we need to read the bed file with the following columns:

Column

Meaning

chrom1

target chromosome

start1

target start position

end1

target end position

chrom2

query chromosome

start2

query start position

end2

query end position

value

identity

identity_2d_cols = {
    "chrom1": pl.Utf8,
    "start1": pl.Int64,
    "end1": pl.Int64,
    "chrom2": pl.Utf8,
    "start2": pl.Int64,
    "end2": pl.Int64,
    "value": pl.Float64,
}
lf = read_indexed_bed("signal.bed.gz", columns=identity_2d_cols)

Track Configuration#

tracksplot() accepts a list of track configuration dictionaries. Each dictionary describes one genomic track to be displayed.

Common Fields#

Field

Type

Required

Description

name

str

Track name displayed on the left side

type

str

Track type: "bedgraph", "bed", or "heatmap"

data

pl.DataFrame | pl.LazyFrame

Input data

height

float

Relative track height. Default: 1.0

showlegend

bool

Whether to show the legend. Default: False

Bedgraph Track#

A BedGraph track visualizes continuous numerical signals along the genome.

Supported fields

Field

Type

Default

Description

plot_type

str

"line"

Plot style: "line", "bar", or "density"

max_value

float

data maximum

Upper limit of the y-axis

min_value

float

data minimum

Lower limit of the y-axis

linewidth

float

1

Line width for line plots

color

str

"#212529"

Line or bar color

colorscale

list[str] | list[tuple[float, str]]

Colorscale used for density plots

Example

{
    "name": "CpG Met.",
    "type": "bedgraph",
    "data": met_df,
    "plot_type": "bar",
}

Bed Track#

A BED track visualizes genomic intervals as rectangles or stranded features.

Supported fields

Field

Type

Default

Description

stranded

bool

False

Draw directional arrows according to strand information

arrowhead_length

float

0.03

Arrowhead length relative to the displayed region

color

str

"#212529"

Feature color

draw_baseline

bool

False

Draw a thin baseline across the full region before rendering intervals

Example

{
    "name": "Orientations",
    "type": "bed",
    "data": strand_df,
    "stranded": True,
}

Heatmap Track#

A triangle heatmap track visualizes symmetric-matrix-like genomic data.

Supported fields

Field

Type

Default

Description

max_value

float

data maximum

Maximum value used for color scaling

min_value

float

data minimum

Minimum value used for color scaling

colorscale

list[str] | list[tuple[float, str]]

StainedGlass-style

Heatmap colorscale

flip_y

bool

False

Reverse the y-axis order

Example

{
    "name": "2D Identity",
    "type": "heatmap",
    "data": identity_2d_df,
    "flip_y": True,
}

Visualization#

Here we use the chromosome 1 centromere annotation from the T2T-CHM13v2.0 assembly, published by Gao et al., 2025, as an example.

# This line attempts to load the cached data. If the dataset has not been downloaded yet,
# it will be downloaded automatically, which may take a few moments.
tracks = vp.datasets.chm13_cen1_tracks()
vp.anno.pl.tracksplot(
    tracks,
    region = "chm13_chr1:121119216-127324115",
    title = "chm13_chr1:121119216-127324115",
    vertical_spacing = 0.02,
    track_name_dx = -0.08,
    base_width = 400, # optional; adjust figure width to fit within the manual page width
)