plot

Make a logo plot with interactive, hoverable annotation boxes.

This is an interactive counterpart to plot_logo. The sequence logo itself is drawn by reusing plot_logo, so the glyphs look identical. The difference is in how annotations are displayed: rather than the stacked underline-and-label tracks used by plot_logo, each annotation is drawn as a single translucent, pastel box spanning the full vertical extent of the plot across the positions of the hit. A label – the name column when present, otherwise the annotation’s index – is written in small font in the upper-left corner of its box (unless label=False), and hovering over the box reveals a tooltip with the rest of the annotation’s statistics.

The reason for this idiom is that motif hits frequently carry several pieces of metadata worth inspecting together – the seqlet p-value, the annotation (TOMTOM) p-value, the summed attribution, the strand, and so on – which is more than a static label can show without cluttering the plot. Boxing the region and deferring the details to a hover tooltip keeps the logo readable while still exposing every column you pass in. Because the boxes are translucent, overlapping hits remain legible and are distinguished by their colors and corner labels rather than by being pushed onto separate tracks.

Interactivity is provided by mpld3, which converts the matplotlib figure to D3-backed HTML. The tooltips therefore work both inline in a Jupyter notebook and in exported static HTML. mpld3 is an optional dependency; this function imports it lazily and raises a helpful error if it is not installed. The figure returned has the tooltip plugin already attached, so to view it call mpld3.display(ax.get_figure()) in a notebook (or mpld3.enable_notebook() before plotting), and to export it call mpld3.fig_to_html(ax.get_figure()).

Parameters

X_attr: torch.tensor, shape=(4, -1)

A tensor of the attributions. Can be either the hypothetical attributions, where the entire matrix has values, or the projected attributions, where only the actual bases have their attributions stored, i.e., 3 values per column are zero.

ax: matplotlib.axes.Axes or None, optional

The art board to draw on. If None, choose the current artboard. Default is None.

color: str, dict, numpy.ndarray, list, or None, optional

The glyph coloring, passed through to plot_logo. Accepts the same forms: None for standard nucleotide coloring, a str or dict for per-character coloring, or an array-like for per-position coloring (see plot_logo for the full contract). Default is None.

color_cmap: str, optional

The colormap used to map a numeric per-position color vector to colors, passed through to plot_logo. Default is “viridis”.

color_vmin: float or None, optional

The lower normalization bound for a numeric per-position color vector, passed through to plot_logo. If None, the minimum of the vector is used. Default is None.

color_vmax: float or None, optional

The upper normalization bound for a numeric per-position color vector, passed through to plot_logo. If None, the maximum of the vector is used. Default is None.

annotations: pandas.DataFrame, optional

A set of annotations to box and label. Must contain start and end columns giving each hit’s position relative to the window; all other columns are shown in the hover tooltip. If a name column is present it is used as the box label and tooltip title; otherwise each box is labeled by its index among the annotations visible in the window. In the tooltip, attribution and p-value columns (as emitted by the seqlet caller) are relabeled seqlet attribution and seqlet p-value so they are not confused with a separate annotation p-value. Default is None.

start: int or None, optional

The start of the sequence to visualize. Must be non-negative and cannot be longer than the length of X_attr. If None, visualize the full sequence. Default is None.

end: int or None, optional

The end of the sequence to visualize. Must be non-negative and cannot be longer than the length of X_attr. If start is provided, end must be larger. If None, visualize the full sequence. Default is None.

ylim: tuple or None, optional

The lower and upper bounds of the plot as (low, high). The annotation boxes span this full vertical range. If None, use the bounds chosen by plot_logo. Default is None.

alphabet: list, optional

A list of characters that comprise the alphabet. Default is [‘A’, ‘C’, ‘G’, ‘T’].

min_height_pct: float, optional

Passed through to plot_logo; glyphs shorter than this fraction of the tallest glyph are not drawn. Default is 0.02.

box_alpha: float, optional

The opacity of the annotation box fill, between 0 and 1. The corner label is drawn opaque regardless. Default is 0.3.

box_linewidth: float, optional

The width of the annotation box outline. When 0 (the default), no outline is drawn and the box is shown by its translucent fill alone; set to a positive value to draw a tinted border around each box. Default is 0.

annot_cmap: str, list, or matplotlib.colors.ListedColormap, optional

The colormap used to color the annotation boxes. Each annotation receives a distinct color. If a string, must be a valid matplotlib colormap name. If a list, must be a list of colors. Qualitative (listed) colormaps cycle by annotation index; continuous colormaps are sampled evenly across the annotations. Default is ‘Pastel1’.

label: bool, optional

Whether to draw the name/index label in the corner of each box. The hover tooltip is unaffected by this. Default is True.

label_fontsize: float, optional

The font size of the label drawn in the corner of each box. Only applies when label=True. Default is 9.

grid: bool, optional

Whether to draw a light horizontal grid. mpld3 renders whatever grid matplotlib’s style specifies, which is frequently a heavy default. When True, this overrides it with a subtle light-gray horizontal grid; when False, no grid is drawn at all (it does not fall back to the matplotlib default). Either way the appearance does not depend on the caller’s rcParams. Default is True.

despine: bool, optional

Whether to remove the bottom and left axis lines. mpld3 draws its own near-black axis spines and tick marks that ignore matplotlib’s spine settings; when True, these are hidden (via injected CSS) for a clean, despined look while the tick labels and grid remain. Default is True.

tooltip_css: str or None, optional

CSS string passed to the mpld3 tooltip plugin for styling the hover text. If None, a default stylesheet is used that gives the tooltip a semi-opaque white background, a border, and padding so the text is legible over the plot. Pass a string to override it entirely. Default is None.

Returns

ax: matplotlib.axes.Axes

The axes on which the logo was drawn. The parent figure has the mpld3 tooltip plugin attached; render it with mpld3.display or mpld3.fig_to_html.

Make a logo plot and optionally annotate it.

This function will take in a matrix of weights for each character in a sequence and produce a plot where the characters have heights proportional to those weights. Attribution values from a predictive model are commonly used to weight the characters, but the weights can come from anywhere.

Optionally, annotations can be provided in the form of a dataframe with contents described below in the parameters section. These annotations will be displayed underneath the characters in a manner that tries to avoid overlap across annotations.

Parameters

X_attr: torch.tensor, shape=(4, -1)

A tensor of the attributions. Can be either the hypothetical attributions, where the entire matrix has values, or the projected attributions, where only the actual bases have their attributions stored, i.e., 3 values per column are zero.

ax: matplotlib.pyplot.subplot or None, optional

The art board to draw on. If None, choose the current artboard.

color: str, dict, numpy.ndarray, list, or None, optional

The coloring for the glyphs, which can be specified per character or per position depending on the form passed in:

  • None: color each character according to the standard coloring.

  • str: color every character with this single color.

  • dict: color each character according to a mapping from the character to a color (e.g. {'A': 'red', 'C': 'blue', ...}).

  • array-like: color each position independently. Must have the same length as the last dimension of X_attr (before any start/end slicing) and is sliced alongside X_attr under the same conditions. May either be a 1D numeric vector, in which case each value is mapped to a color through color_cmap and the color_vmin/color_vmax bounds, or a sequence of color specifications (names, hex strings, or an (length, 3)/ (length, 4) array of RGB(A) values), used verbatim. All glyphs in a column share the color assigned to that position.

When an array-like is passed but its length does not match the last dimension of X_attr, a TangermemeWarning is raised and the standard per-character coloring is used instead. Default is None.

color_cmap: str, optional

The colormap used to map a numeric color vector to colors. Ignored unless color is a 1D numeric array-like. Default is “viridis”.

color_vmin: float or None, optional

The lower bound used to normalize a numeric color vector before mapping through color_cmap. If None, the minimum of the vector is used. Default is None.

color_vmax: float or None, optional

The upper bound used to normalize a numeric color vector before mapping through color_cmap. If None, the maximum of the vector is used. Default is None.

annotations: pandas.DataFrame, optional

A set of annotations with the following columns in any order except for motif_name, which can be called anything but must come first:

  • motif_name: the name of the motif

  • start: the start of the hit relative to the window provided

  • end: the end of the hit relative to the window provided

  • strand: the strand the hit is on (optional)

  • score: the score of the hit

These will probably come from the output of the hit caller. Default is None.

start: int or None, optional

The start of the sequence to visualize. Must be non-negative and cannot be longer than the length of X_attr. If None, visualize the full sequence. Default is None.

end: int or None, optional

The end of the sequence to visualize. Must be non-negative and cannot be longer than the length of X_attr. If start is provided, end must be larger. If None, visualize the full sequence. Default is None.

ylim: tuple or None, optional

The lower and upper bounds of the plot. Pass the bounds in here rather than setting them after calling this function if you want the annotation spacing to adjust to it. If None, use the default bounds. Default is None.

n_tracks: int, optional

The number of rows of annotation labels to plot with bars before simply putting the name of the motif. Default is 4.

score_key: str, optional

When annotations are provided, the name of the key to use as a score. Must have the semantics that a higher value means a “better” annotation. Default is ‘score’.

show_extra: bool, optional

Whether to show motif names past the n_tracks number of rows. If False, do not show those motifs. Default is True.

show_score: bool, optional

Whether to show the score of the hit. Sometimes, the annotation can take up too much space already and the scoring information is not as helpful, so disabling this will only display the motif hit name. Default is True.

annot_cmap: str, list, or matplotlib.colors.ListedColormap, optional

The colormap to use for the annotations. Rows of annotation labels receive distinct colors, bars are colored according to their corresponding label. If a string, must be a valid matplotlib qualitative colormap name If a list, must be a list of colors (list of colornames or list of RGB tuples). Labels are colorcoded if there is more than 1 row of annotations, otherwise black.

Returns

ax: plt.subplot

A subplot that contains the plot.