lib5c.plotters.extendable package

Module contents

Module describing the extendable heatmap plotting system.

The core idea behind this system is the ExtendableFigure API. Subclasses of ExtendableFigure inherit the add_ax() instance method, which tacks on additional matplotlib axes to an existing axis using a divider object obtained using the matplotlib function mpl_toolkits.axes_grid1.make_axes_locatable(). The new axes are stored in an axes dict instance variable on the ExtendableFigure and can subsequently be plotted on with any matplotlib-based function.

This means that an arbitrary number of additional data tracks can be added to the ExtendableFigure in a sequential, interactive manner.

The BaseExtendableHeatmap class extends ExtendableFigure and implements extra functionality specific for plotting contact frequency heatmaps. This includes a custom interface to add_ax() called add_margin_ax(), designed to make it easy to add tracks to the margins of a contact frequency heatmap.

In order to handle the wide diversity of tracks and overlays that may be added to a contact frequency heatmap, a wide variety of plug-in mixin classes are defined. These mixin classes each implement one specific feature in the form of a few related instance methods that internally call add_margin_ax(). For example, ChipSeqExtendableHeatmap provides a function add_chipseq_track() which uses add_margin_ax() to add a ChIP-seq track to the ExtendableHeatmap. The separation of different features into separate mixin classes makes the code easier to understand and also makes it easy to add new features.

The feature functions like add_chipseq_track() typically accept some data as well as parameters for creating the new axis. The functions typically create the new axis using add_margin_ax(), passing through the relevant parameters. The functions then plot the data to the newly created axis using matplotlib plotting functions. Finally, they return the new axis.

By convention, we often plot tracks on both the left and the bottom of the heatmap. To make this easier, most feature functions like add_chipseq_track() have associated helper functions like add_chipseq_tracks(), which simply calls add_chipseq_track() twice: once with loc='bottom' and once with loc='left'.

To add a new feature:

  1. create a new mixin class extending BaseExtendableHeatmap that implements the functions for your feature,
  2. place your new class in the lib5c.plotters.extendable module,
  3. import your class in the top level module file __init__.py and add it to the __all__ variable, and
  4. add your class to the list of classes inherited by ExtendableHeatmap, making sure to place it before BaseExtendableHeatmap in the list.

In the future, this process may be automated.

class lib5c.plotters.extendable.ExtendableFigure[source]

Bases: object

Base class for figures that can interactively and sequentially tack on new axes to themselves.

Uses a divider attribute obtained from mpl_toolkits.axes_grid1.make_axes_locatable() to add new axes to the figure. Clients can call add_ax() to add a new axis.

All the axes in the ExtendableFigure can be accessed by name using a dict- like interface: f[name] where f is the ExtendableFigure instance and name is the name of the axis. The ExtendableFigure starts out with one axis already present, called ‘root’.

axes

The collection of named Axes represented by this object.

Type:dict of matplotlib.axes.Axes
fig

The Figure instance this object represents.

Type:matplotlib.figure.Figure
divider

This object serves as a coordinator for the allocation of new Axes to be appended to this ExtendableFigure.

Type:mpl_toolkits.axes_grid1.axes_divider.AxesDivider

Examples

>>> import numpy as np
>>> from lib5c.plotters.extendable.extendable_figure import ExtendableFigure
>>> xs = np.arange(0, 10)
>>> f = ExtendableFigure()
>>> f['root'].imshow(np.arange(100).reshape((10,10)))
<matplotlib.image.AxesImage object at ...>
>>> f.add_ax('sin')
<matplotlib.axes._axes.Axes object at ...>
>>> f['sin'].plot(xs, np.sin(xs))
[<matplotlib.lines.Line2D object at ...>]
>>> f.add_colorbar('root')
>>> f.save('test/extendablefigure.png')
add_ax(name, loc='bottom', size='10%', pad=0.1)[source]

Adds a new axis to this ExtendableFigure.

Parameters:
  • name (str) – A name for the new axis. The axis will be accessible as f[new_ax_name] where f is this ExtendableFigure instance.
  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the figure to add the new axis to.
  • size (str) – The size of the new axis as a percentage of the main figure size. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
Returns:

The newly created axis.

Return type:

pyplot axis

add_colorbar(source_ax_name, loc='right', size='10%', pad=0.1, new_ax_name='colorbar')[source]

Adds a colorbar to the heatmap in a new axis.

Parameters:
  • source_ax_name (str) – The name of the axis that this should be the colorbar for. This is where matplotlib will look to find color information for the new colorbar.
  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the figure to add the new colorbar to.
  • size (str) – The size of the new axis as a percentage of the main figure size. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • new_ax_name (str) – A name for the new axis. The axis will be accessible as f[new_ax_name] where f is this ExtendableFigure instance.
close()[source]

Clears and closes the pyplot figure related to this ExtendableFigure.

save(filename)[source]

Saves this ExtendableHeatmap to the disk as an image file.

Parameters:filename (str) – The filename to save the image to.
class lib5c.plotters.extendable.BaseExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.extendable_figure.ExtendableFigure

Minimal implementation of an ExtendableFigure organized around a contact frequency heatmap.

The heatmap is plotted using plt.imshow() using data from the array attribute, colored using the other attributes, and the resulting axis is accessible at h['root'] where h is the ExtendableHeatmap instance.

New axes can be added to the margins of the heatmap by calling add_margin_ax(). The axis of the new axis that is parallel to the heatmap will have its limits set to match the grange_x or grange_y attributes. This allows plotting features on the margin axes using genomic coordinates instead of having to convert to pixel coordinates.

The root heatmap axis is still kept in units of pixels. To make drawing on this axis easier, this class provides transform_feature(), which will transform a genomic feature dict into heatmap pixel units.

array

Array of values to plot in the heatmap. Must be square.

Type:np.ndarray
grange_x

The genomic range represented by the x-axis of this heatmap. The dict should have the form:

{
    'chrom': str,
    'start': int,
    'end': int
}
Type:dict
grange_y

The genomic range represented by the y-axis of this heatmap. If None, the heatmap is assumed to be symmetric.

Type:dict, optional
colorscale

The (min, max) of the color range to plot the values in the array with.

Type:tuple of float
colormap

The colormap to use when drawing the heatmap. Strings will be passed to lib5c.plotters.colormaps.get_colormap(). If array contains strings, pass a dict mapping those strings to colors.

Type:str or matplotlib colormap or dict of colors
norm

Pass an instance of matplotlib.colors.Normalize to apply this normalization to the heatmap and colorbar.

Type:matplotlib.colors.Normalize, optional
add_colorbar(loc='right', size='10%', pad=0.1, new_ax_name='colorbar')[source]

Adds a colorbar to the heatmap in a new axis.

Parameters:
  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new colorbar to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • new_ax_name (str) – A name for the new axis. The axis will be accessible as h[new_ax_name] where h is this ExtendableHeatmap instance.
Returns:

The newly added colorbar.

Return type:

pyplot colorbar

add_margin_ax(loc='bottom', size='10%', pad=0.0, new_ax_name='new_h_axis', axis_limits=(0, 1))[source]

Adds a new axis to the margin of this ExtendableHeatmap.

Parameters:
  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the figure to add the new axis to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • new_ax_name (str) – A name for the new axis. The axis will be accessible as h[new_ax_name] where h is this ExtendableHeatmap instance.
Returns:

The newly added axis.

Return type:

pyplot axis

transform_coord(coord, axis='x')[source]

Convenience function for transforming genomic coordinates to heatmap pixel coordinates along a specified axis.

Parameters:
  • coord (int) – The genomic coordinate in base pairs.
  • axis ({'x', 'y'}) – The axis to convert the coordinate for.
Returns:

The coord expressed in heatmap pixel coordinates along the requested axis.

Return type:

float

transform_feature(feature, axis='x')[source]

Uses transform_coord() to transform an entire genomic feature dict to heatmap pixel coordinates.

Parameters:
  • feature (dict) – Represents a genomic feature. Should have ‘chrom’, ‘start’, and ‘end’ keys. The values for ‘start’ and ‘end’ should be in base pair units.
  • axis ({'x', 'y'}) – The axis to convert the feature for.
Returns:

Will have keys ‘chrom’, ‘start’, and ‘end’, but the values for ‘start’ and ‘end’ will now be in units of heatmap pixels along the specified axis.

Return type:

dict

class lib5c.plotters.extendable.ChipSeqExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing ChIP-seq track plotting functionality.

add_chipseq_track(features, loc='bottom', size='10%', pad=0.05, axis_limits=None, linewidth=0.4, name='chipseq', color='k', track_label=None)[source]

Adds one ChIP-seq track along either the x- or y-axis of the heatmap.

Parameters:
  • features (list of dict) –

    Each feature should be a dict with at least the following keys:

    {
        'chrom': str,
        'start': int,
        'end': int,
        'value': float
    }
    

    Each feature will be drawn as a rectangle on the heatmap from ‘start’ to ‘end’ with height ‘value’. If the ‘value’ key is missing, it will be assumed to be one for all features. To get data in this form from bigwig files, consult lib5c.contrib.pybigwig.bigwig.BigWig.query().

  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new ChIP-seq track to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • axis_limits (tuple of float, optional) – Axis limits for the ‘value’ of the plotted features (heights of the rectangles) as a (min, max) tuple. Pass None to automatically scale the axis limits.
  • linewidth (float) – The linewidth to use when drawing the rectangles. Pass smaller values for sharper features/peaks.
  • name (str) – Base name for the new axis. This name will be prefixed with the orientation of the track (‘vertical or ‘horizontal’).
  • color (matplotlib color) – The color to draw the rectangles with.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added ChIP-seq track axis.

Return type:

pyplot axis

add_chipseq_tracks(features, size='10%', pad=0.05, axis_limits=None, linewidth=0.4, name='chipseq', color='k', track_label=None)[source]

Adds ChIP-seq tracks for a single set of features to both the bottom and left side of the heatmap by calling add_chipseq_track() twice.

Parameters:
  • features (list of dict) –

    Each feature should be a dict with at least the following keys:

    {
        'chrom': str,
        'start': int,
        'end': int,
        'value': float
    }
    

    Each feature will be drawn as a rectangle on the heatmap from ‘start’ to ‘end’ with height ‘value’. If the ‘value’ key is missing, it will be assumed to be one for all features. To get data in this form from bigwig files, consult lib5c.contrib.pybigwig.bigwig.BigWig.query().

  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • axis_limits (tuple of float, optional) – Axis limits for the ‘value’ of the plotted features (heights of the rectangles) as a (min, max) tuple. Pass None to automatically scale the axis limits.
  • linewidth (float) – The linewidth to use when drawing the rectangles. Pass smaller values for sharper features/peaks.
  • name (str) – Base name for the new axis. This name will be prefixed with the orientation of the track (‘vertical’ or ‘horizontal’).
  • color (matplotlib color) – The color to draw the rectangles with.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added ChIP-seq track axes.

Return type:

list of pyplot axes

class lib5c.plotters.extendable.DomainExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing ChIP-seq domain outlining functionality.

outline_domain(domain, color='green', linewidth=2, upper=True)[source]

Outlines a contact domain on the heatmap.

Parameters:
  • domain (dict) –

    A genomic feature dict describing the domain to be outlinerd. Should be a dict with at least the following keys:

    {
        'chrom': str,
        'start': int,
        'end': int
    }
    

    ’start’ and ‘end’ should be in units of base pairs (this function will handle the conversion to heatmap pixel units).

  • color (matplotlib color) – The color to outline the domain with.
  • linewidth (float) – The line width to use when outlining the domain. Pass a larger number for a thicker, more visible outline.
  • upper (bool) – Pass True to draw the outline in the upper triangle of the heatmap. Pass False to draw it in the lower triangle.
outline_domains(domains, color='green', linewidth=2, upper=True)[source]

Outlines a set of contact domains on the heatmap by repeatedly calling outline_domain().

Parameters:
  • domains (list of dict) –

    A list of domains, where each domain is represented as genomic feature dict with at least the following keys:

    {
        'chrom': str,
        'start': int,
        'end': int
    }
    

    ’start’ and ‘end’ should be in units of base pairs (this function will handle the conversion to heatmap pixel units).

  • color (matplotlib color) – The color to outline the domains with.
  • linewidth (float) – The line width to use when outlining the domains. Pass a larger number for a thicker, more visible outline.
  • upper (bool) – Pass True to draw the outlines in the upper triangle of the heatmap. Pass False to draw them in the lower triangle.
class lib5c.plotters.extendable.GeneExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing gene track plotting functionality.

To deal with the fact that genes may overlap (e.g., where a gene has multiple isoforms), this class uses the concept of “gene stacks”. Each gene track in a gene stack represents a separate axis added to the ExtendableHeatmap. By packing a set of genes into separate “rows”, functions like add_gene_stack() can plot each row in the stack as a separate gene track via add_gene_track().

Most commonly, we will want to add reference gene tracks corresponding to a particular genome assembly. To make this easy, this class provides the add_refgene_stack() and add_refgene_stacks() functions.

add_gene_stack(genes, loc='bottom', size='3%', pad_before=0.0, pad_within=0.0, axis_limits=(0, 1), intron_height=0.05, exon_height=0.5, padding=1000, colors=None)[source]

Adds one stack of gene tracks along either the x- or y-axis of the heatmap by packing one set of genes into rows and calling add_gene_track() once for every row.

Parameters:
  • genes (list of dict) –

    Each dict should represent a gene and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'name'  : str,
        'id'    : str,
        'strand': '+' or '-',
        'blocks': list of dicts
    }
    

    Each block represents an exon as dicts with the following structure:

    {
        'start': int,
        'end'  : int
    }
    

    The ‘name’ and ‘id’ keys are optional and are only used when color- coding genes. See lib5c.parsers.genes.load_genes().

  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new gene tracks to.
  • size (str) – The size of each new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad_before (float) – The padding to use between the existing parts of the figure and the newly added gene tracks.
  • pad_within (float) – The padding to use between each newly added gene track.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of each new gene track.
  • intron_height (float) – Controls thickness of gene introns. Pass a larger number for thicker introns.
  • exon_height (float) – Controls thickness of gene exons. Pass a larger number for thicker exons.
  • padding (int) – The padding to use when packing genes into rows, in units of base pairs. Genes that are within this many base pairs of each other will get packed into different rows.
  • colors (dict, optional) – Pass a dict mapping gene names or id’s to matplotlib colors to color code those genes. Genes not in the dict will be colored black by default. Using gene names as keys should color all isoforms, while using gene id’s as keys should color just the isoform matching the specified id.
Returns:

The newly added gene track axes, one for each row of genes.

Return type:

list of pyplot axis

add_gene_stacks(genes, size='3%', pad_before=0.0, pad_within=0.0, axis_limits=(0, 1), intron_height=0.05, exon_height=0.5, padding=1000, colors=None)[source]

Adds a gene stack for a set of genes to both the bottom and left side of the heatmap by calling add_gene_stack() twice.

Parameters:
  • genes (list of dict) –

    Each dict should represent a gene and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'name'  : str,
        'id'    : str,
        'strand': '+' or '-',
        'blocks': list of dicts
    }
    

    Each block represents an exon as dicts with the following structure:

    {
        'start': int,
        'end'  : int
    }
    

    The ‘name’ and ‘id’ keys are optional and are only used when color- coding genes. See lib5c.parsers.genes.load_genes().

  • size (str) – The size of each new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad_before (float) – The padding to use between the existing parts of the figure and the newly added gene tracks.
  • pad_within (float) – The padding to use between each newly added gene track.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of each new gene track.
  • intron_height (float) – Controls thickness of gene introns. Pass a larger number for thicker introns.
  • exon_height (float) – Controls thickness of gene exons. Pass a larger number for thicker exons.
  • padding (int) – The padding to use when packing genes into rows, in units of base pairs. Genes that are within this many base pairs of each other will get packed into different rows.
  • colors (dict, optional) – Pass a dict mapping gene names or id’s to matplotlib colors to color code those genes. Genes not in the dict will be colored black by default. Using gene names as keys should color all isoforms, while using gene id’s as keys should color just the isoform matching the specified id.
Returns:

The first element of the outer list is a list of the newly added horizontal gene track axes, one for each row of genes. The second element is the same but for the newly added vertical gene track axes.

Return type:

list of lists of pyplot axis

add_gene_track(genes, loc='bottom', size='3%', pad=0.0, new_ax_name='genes', axis_limits=(0, 1), intron_height=0.05, exon_height=0.5, colors=None)[source]

Adds one gene track (for one row of genes) along either the x- or y-axis of the heatmap.

Parameters:
  • genes (list of dict) –

    Each dict should represent a gene and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'name'  : str,
        'id'    : str,
        'strand': '+' or '-',
        'blocks': list of dicts
    }
    

    Each block represents an exon as dicts with the following structure:

    {
        'start': int,
        'end'  : int
    }
    

    The ‘name’ and ‘id’ keys are optional and are only used when color- coding genes. See lib5c.parsers.genes.load_genes().

  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new gene track to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • new_ax_name (str) – The name for the new axis. You can access the new axis later at h[name] where h is this ExtendableHeatmap instance.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the gene track.
  • intron_height (float) – Controls thickness of gene introns. Pass a larger number for thicker introns.
  • exon_height (float) – Controls thickness of gene exons. Pass a larger number for thicker exons.
  • colors (dict, optional) – Pass a dict mapping gene names or id’s to matplotlib colors to color code those genes. Genes not in the dict will be colored black by default. Using gene names as keys should color all isoforms, while using gene id’s as keys should color just the isoform matching the specified id.
Returns:

The newly added gene track axis.

Return type:

pyplot axis

add_gene_tracks(genes, size='3%', pad=0.0, axis_limits=(0, 1), intron_height=0.05, exon_height=0.5, colors=None)[source]

Adds a gene track for a single row of genes to both the bottom and left side of the heatmap by calling add_gene_track() twice.

Parameters:
  • genes (list of dict) –

    Each dict should represent a gene and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'name'  : str,
        'id'    : str,
        'strand': '+' or '-',
        'blocks': list of dicts
    }
    

    Each block represents an exon as dicts with the following structure:

    {
        'start': int,
        'end'  : int
    }
    

    The ‘name’ and ‘id’ keys are optional and are only used when color- coding genes. See lib5c.parsers.genes.load_genes().

  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the gene track.
  • intron_height (float) – Controls thickness of gene introns. Pass a larger number for thicker introns.
  • exon_height (float) – Controls thickness of gene exons. Pass a larger number for thicker exons.
  • colors (dict, optional) – Pass a dict mapping gene names or id’s to matplotlib colors to color code those genes. Genes not in the dict will be colored black by default. Using gene names as keys should color all isoforms, while using gene id’s as keys should color just the isoform matching the specified id.
Returns:

The newly added gene track axes.

Return type:

list of pyplot axes

add_refgene_stack(assembly, loc='bottom', size='3%', pad_before=0.0, pad_within=0.0, axis_limits=(0, 1), intron_height=0.05, exon_height=0.5, padding=1000, colors=None)[source]

Adds a gene stack to either the x- or y-axis of the heatmap by getting a set of reference genes for a specified genome assembly, and then passes that set of genes to add_gene_stack().

Parameters:
  • assembly ({'hg18', 'hg19', 'hg38', 'mm9', 'mm10'}) – The genome assembly to load reference genes for.
  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new gene tracks to.
  • size (str) – The size of each new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad_before (float) – The padding to use between the existing parts of the figure and the newly added gene tracks.
  • pad_within (float) – The padding to use between each newly added gene track.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of each new gene track.
  • intron_height (float) – Controls thickness of gene introns. Pass a larger number for thicker introns.
  • exon_height (float) – Controls thickness of gene exons. Pass a larger number for thicker exons.
  • padding (int) – The padding to use when packing genes into rows, in units of base pairs. Genes that are within this many base pairs of each other will get packed into different rows.
  • colors (dict, optional) – Pass a dict mapping gene names or id’s to matplotlib colors to color code those genes. Genes not in the dict will be colored black by default. Using gene names as keys should color all isoforms, while using gene id’s as keys should color just the isoform matching the specified id.
Returns:

The newly added gene track axes, one for each row of genes.

Return type:

list of pyplot axis

add_refgene_stacks(assembly, size='3%', pad_before=0.0, pad_within=0.0, axis_limits=(0, 1), intron_height=0.05, exon_height=0.5, padding=1000, colors=None)[source]

Adds a gene stack for a set of genes to both the bottom and left side of the heatmap by calling add_refgene_stack() twice.

Parameters:
  • assembly ({'hg18', 'hg19', 'hg38', 'mm9', 'mm10'}) – The genome assembly to load reference genes for.
  • size (str) – The size of each new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad_before (float) – The padding to use between the existing parts of the figure and the newly added gene tracks.
  • pad_within (float) – The padding to use between each newly added gene track.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of each new gene track.
  • intron_height (float) – Controls thickness of gene introns. Pass a larger number for thicker introns.
  • exon_height (float) – Controls thickness of gene exons. Pass a larger number for thicker exons.
  • padding (int) – The padding to use when packing genes into rows, in units of base pairs. Genes that are within this many base pairs of each other will get packed into different rows.
  • colors (dict, optional) – Pass a dict mapping gene names or id’s to matplotlib colors to color code those genes. Genes not in the dict will be colored black by default. Using gene names as keys should color all isoforms, while using gene id’s as keys should color just the isoform matching the specified id.
Returns:

The first element of the outer list is a list of the newly added horizontal gene track axes, one for each row of genes. The second element is the same but for the newly added vertical gene track axes.

Return type:

list of lists of pyplot axis

class lib5c.plotters.extendable.LegendExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing functionality for adding a legend.

add_legend(colors, **kwargs)[source]

Adds a legend to the ExtendableHeatmap.

Parameters:
  • colors (dict) – The entries to add to the legend. Keys should be string labels to use in the legend, and values should be matplotlib colors.
  • kwargs (kwargs) – Will be passed through to ax.legend().
Returns:

The newly created Legend.

Return type:

matplotlib.legend.Legend

class lib5c.plotters.extendable.ClusterExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing cluster outlining functionality.

add_clusters(cluster_array, colors=None, weight='100x', outline_color=None, outline_weight='2x', labels=None, fontsize=7)[source]

Adds clusters to the heatmap surface.

Parameters:
  • cluster_array (np.ndarray) – Array of cluster IDs. Should match size and shape of the underlying array this ExtendableHeatmap was constructed with.
  • colors ('random' or single color or list/dict of colors or None) – Pass ‘random’ for random colors, pass a dict mapping cluster IDs to matplotlib colors to outline each cluster in the indicated color, pass None to skip outlining clusters.
  • weight (numeric or str) – Pass a numeric to set the linewidth for the cluster outlines. Pass a string ending in “x” (such as “100x”) to specify the line width as a multiple of the inverse of the number of pixels in the heatmap.
  • outline_color (matplotlib color or None) – Pass a matplotlib color to outline the outlines (e.g. with neon green) to make them stand out more. Pass None to skip adding this extra outline.
  • outline_weight (numeric or str) – ass a numeric to set the linewidth for the outlines of the cluster outlines. Pass a string ending in “x” (such as “2x”) to specify the line width as a multiple of the outline linewidth.
  • labels (True, dict of str, or None) – Pass True to simply label the clusters by their ID. Pass a mapping from cluster IDs to labels to label the clusters with a the labels. Pass None to skip outlining clusters.
  • fontsize (numeric) – The font size to use for cluster labels.
label_cluster(cluster, label, fontsize=7)[source]

Labels a cluster.

Parameters:
  • cluster (list of {'x': int, 'y': int} dicts) – The cluster to label.
  • label (str) – The string to label the cluster with.
  • fontsize (numeric) – The fontsize to use for the label.
outline_cluster(cluster, color, linewidth=2)[source]

Outlines a single cluster in the specified color.

Parameters:
  • cluster (list of {'x': int, 'y': int} dicts) – The cluster to outline.
  • color (matplotlib color) – The color to outline in.
  • linewidth (numeric) – The linewidth to use.
class lib5c.plotters.extendable.RulerExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing ruler track plotting functionality.

add_ruler(loc='bottom', size='5%', pad=0.0, new_ax_name='ruler', axis_limits=(1, 0), ruler_tick_height=0.3, ruler_text_baseline=0.5, no_ticks=False, fontsize=7, no_tick_precision=2)[source]

Adds one ruler track along either the x- or y-axis of the heatmap.

Parameters:
  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new ruler track to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • new_ax_name (str) – The name for the newly created axis.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the ruler track.
  • ruler_tick_height (float) – The height of the ruler ticks.
  • ruler_text_baseline (float) – Controls how far away from the top of the new axis the text elements (chromosome name and region size) will be drawn.
  • no_ticks (bool) – Pass True to skip plotting ruler ticks, and instead write the start and end coordinate of the plotted region in units of megabase pairs.
  • fontsize (float) – The font size to use for adding labels to the ruler axis.
  • no_tick_precision (int) – When no_ticks is True, round the start and end coordinates of the plotted region to this many digits after the decimal.
Returns:

The newly added ruler track axis.

Return type:

pyplot axis

add_rulers(size='5%', pad=0.0, axis_limits=(1, 0), ruler_tick_height=0.3, ruler_text_baseline=0.5, no_ticks=False, fontsize=7, no_tick_precision=2)[source]

Adds a ruler track to both the bottom and left side of the heatmap by calling add_ruler() twice.

Parameters:
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the ruler track.
  • ruler_tick_height (float) – The height of the ruler ticks.
  • ruler_text_baseline (float) – Controls how far away from the top of the new axis the text elements (chromosome name and region size) will be drawn.
  • no_ticks (bool) – Pass True to skip plotting ruler ticks, and instead write the start and end coordinate of the plotted region in units of megabase pairs.
  • fontsize (float) – The font size to use for adding labels to the ruler axis.
  • no_tick_precision (int) – When no_ticks is True, round the start and end coordinates of the plotted region to this many digits after the decimal.
Returns:

The newly added gene ruler axes.

Return type:

list of pyplot axes

class lib5c.plotters.extendable.SNPExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing SNP track plotting functionality.

add_snp_track(snps, loc='bottom', size='3%', pad=0.0, name='snp', axis_limits=(0, 1), snp_height=0.5, colors=None, track_label=None)[source]

Adds one SNP track along either the x- or y-axis of the heatmap.

Parameters:
  • snps (list of dict) –

    Each dict should represent a SNP and should have at least the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int
    }
    

    If color-coding SNPs, include a ‘name’ or ‘id’ key.

  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new SNP track to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • name (str) – The name for the new axis. This name will be prefixed with the orientation of the track (‘vertical’ or ‘horizontal’).
  • axis_limits (tuple of float) – Limits for the non-genomic axis of the SNP track.
  • snp_height (float) – Height of SNP arrowheads in same units as axis_limits.
  • colors (dict, optional) – Maps SNP ids or names to color names. Defaults to black if not passed or if a SNP’s name or id are not found in the dict.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added SNP track axis.

Return type:

pyplot axis

add_snp_tracks(snps, size='3%', pad=0.0, axis_limits=(0, 1), snp_height=0.5, name='snp', colors=None, track_label=None)[source]

Adds SNP tracks for a single set of SNPs to both the bottom and left side of the heatmap by calling add_snp_track() twice.

Parameters:
  • snps (list of dict) –

    Each dict should represent a SNP and should have at least the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int
    }
    

    If color-coding SNPs, include a ‘name’ or ‘id’ key.

  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • axis_limits (tuple of float) – Limits for the non-genomic axis of the SNP track.
  • snp_height (float) – Height of SNP arrowheads in same units as axis_limits.
  • name (str) – The name for the new axis. This name will be prefixed with the orientation of the track (‘vertical’ or ‘horizontal’).
  • colors (dict, optional) – Maps SNP ids or names to color names. Defaults to black if not passed or if a SNP’s name or id are not found in the dict.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added SNP track axes.

Return type:

list of pyplot axes

class lib5c.plotters.extendable.MotifExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing motif track plotting functionality.

add_motif_track(motifs, loc='bottom', size='3%', pad=0.0, name='motif', axis_limits=(0, 1), intron_height=0.05, motif_linewidth=1, exon_height=0.5, colors=None, track_label=None)[source]

Adds one motif track along either the x- or y-axis of the heatmap.

Parameters:
  • motifs (list of dict) –

    Each dict should represent a motif instance and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'strand': '+' or '-'
    }
    
  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new motif track to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • name (str) – Base name for the new axis. This name will be prefixed with the orientation of the track (‘vertical’ or ‘horizontal’).
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the motif track.
  • intron_height (float) – Controls height of the rectangle spanning the length of the motif.
  • motif_linewidth (float) – The linewidth to use when plotting.
  • exon_height (float) – Controls the size of the arrowhead that indicates the motif orientation.
  • colors (dict, optional) – Map from the value of the ‘strand’ key in the motifs dicts (usually ‘+’ or ‘-‘) to color name for motifs with that strand value (i.e., orientation). If not provided for a given strand, color is black by default.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added motif track axis.

Return type:

pyplot axis

add_motif_tracks(motifs, size='3%', pad=0.0, axis_limits=(0, 1), intron_height=0.05, exon_height=0.5, name='motif', motif_linewidth=1, colors=None, track_label=None)[source]

Adds motif tracks for a single set of motifs to both the bottom and left side of the heatmap by calling add_motif_track() twice.

Parameters:
  • motifs (list of dict) –

    Each dict should represent a motif instance and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'strand': '+' or '-'
    }
    
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the motif track.
  • intron_height (float) – Controls height of the rectangle spanning the length of the motif.
  • exon_height (float) – Controls the size of the arrowhead that indicates the motif orientation.
  • name (str) – Base name for the new axis. This name will be prefixed with the orientation of the track (‘vertical’ or ‘horizontal’).
  • motif_linewidth (float) – The linewidth to use when plotting.
  • colors (dict, optional) – Map from the value of the ‘strand’ key in the motifs dicts (usually ‘+’ or ‘-‘) to color name for motifs with that strand value (i.e., orientation). If not provided for a given strand, color is black by default.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added motif track axes.

Return type:

list of pyplot axes

class lib5c.plotters.extendable.RectangleExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing rectangle outlining functionality.

Unlike cluster outlining, which outlines specific pixels of the heatmap, or domain outlining, which outlines the upper or lower triangles of diagonal- aligned squares corresponding to domains, rectangle outlining simply draws a rectangle on the heatmap whose sides are described by genomic ranges.

This can be used to outline cluster bounding boxes.

add_rectangle(coords, color='#00FF00', weight='100x', transpose=True)[source]

Draw some rectangles (specified in genomic coordinates) on the heatmap.

Parameters:
  • coords (tuple of dict or str) –

    Genomic coordinates for the rectangle to be plotted. Can be a tuple:

    ({'chrom': str, 'start': int, 'end': int},
     {'chrom': str, 'start': int, 'end': int})
    

    where the first dict specifies the genomic coordinates of one side of the rectangle, and the second dict specifies the genomic coordinates of the other side. Can also be a string of the form chrom:start-end_chrom:start-end, where the _ separates genomic ranges which specify the coordinates of the two sides of the rectangle.

  • color (valid matplotlib color) – The edge color to draw the rectangle with.
  • weight (int or str) – The line width to use to draw the rectangle. Pass a string of the form '100x' to specify the line width as a multiple of the inverse of the size of this heatmap’s array.
  • transpose (bool) – Pass True to interpret the first feature in coords as the side of the rectangle parallel to the y-axis. Pass False to interpret it as the side parallel to the x-axis.
add_rectangles(coords_list, color='#00FF00', weight='100x', transpose=True)[source]

Draw some rectangles (specified in genomic coordinates) on the heatmap.

Parameters:
  • coords_list (list of tuple of dict or list of str) –

    List of sets genomic coordinates (one set for each rectangle) to be plotted. The list can contain tuples:

    ({'chrom': str, 'start': int, 'end': int},
     {'chrom': str, 'start': int, 'end': int})
    

    where the first dict specifies the genomic coordinates of one side of the rectangle, and the second dict specifies the genomic coordinates of the other side. The list can also contain strings of the form chrom:start-end_chrom:start-end, where the _ separates genomic ranges which specify the coordinates of the two sides of the rectangle.

  • color (valid matplotlib color) – The edge color to draw the rectangles with.
  • weight (int or str) – The line width to use to draw the rectangles. Pass a string of the form '100x' to specify the line width as a multiple of the inverse of the size of this heatmap’s array.
  • transpose (bool) – Pass True to interpret the first feature in each tuple or string as the side of the rectangle parallel to the y-axis. Pass False to interpret it as the side parallel to the x-axis.
class lib5c.plotters.extendable.BedExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

ExtendableHeatmap mixin class providing bed track plotting functionality.

add_bed_track(bed_tracks, loc='bottom', size='3%', pad=0.0, name='bed', axis_limits=(0, 1), intron_height=0.05, colors=None, track_label=None)[source]

Adds one bed track along either the x- or y-axis of the heatmap.

Parameters:
  • bed_tracks (list of dict) –

    Each dict should represent a bed feature and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'strand': '+' or '-'
    }
    

    The ‘strand’ key is optional and is only used for color-coding bed features when colors is passed.

  • loc ({'top', 'bottom', 'left', 'right'}) – Which side of the heatmap to add the new bed track to.
  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • name (str) – Base name for the new axis. This name will be prefixed with the orientation of the track (‘vertical’ or ‘horizontal’).
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the bed track.
  • intron_height (float) – The height to draw each bed feature with.
  • colors (dict, optional) – Map from the value of the ‘strand’ key in the bed_tracks dicts (usually ‘+’ or ‘-‘) to color name for bed features with that strand value (i.e., orientation). If not provided for a given strand or if the bed feature doesn’t have a ‘strand’ key the color is black by default.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added bed track axis.

Return type:

pyplot axis

add_bed_tracks(bed_tracks, size='3%', pad=0.0, axis_limits=(0, 1), intron_height=0.05, name=None, colors=None, track_label=None)[source]

Adds bed tracks for a single set of bed features to both the bottom and left side of the heatmap by calling add_bed_track() twice.

Parameters:
  • bed_tracks (list of dict) –

    Each dict should represent a bed feature and could have the following keys:

    {
        'chrom' : str,
        'start' : int,
        'end'   : int,
        'strand': '+' or '-'
    }
    

    The ‘strand’ key is optional and is only used for color-coding bed features when colors is passed.

  • size (str) – The size of the new axis as a percentage of the main heatmap width. Should be passed as a string ending in ‘%’.
  • pad (float) – The padding to use between the existing parts of the figure and the newly added axis.
  • axis_limits (tuple of float) – Axis limits for the non-genomic axis of the bed track.
  • intron_height (float) – The height to draw each bed feature with.
  • name (str) – Base name for the new axis. This name will be prefixed with the orientation of the track (‘vertical’ or ‘horizontal’).
  • colors (dict, optional) – Map from the value of the ‘strand’ key in the bed_tracks dicts (usually ‘+’ or ‘-‘) to color name for bed features with that strand value (i.e., orientation). If not provided for a given strand or if the bed feature doesn’t have a ‘strand’ key the color is black by default.
  • track_label (str, optional) – Pass a string to label the track.
Returns:

The newly added bed track axes.

Return type:

list of pyplot axes

class lib5c.plotters.extendable.ExtendableHeatmap(array, grange_x, grange_y=None, colorscale=None, colormap='obs', norm=None)[source]

Bases: lib5c.plotters.extendable.chipseq_extendable_heatmap.ChipSeqExtendableHeatmap, lib5c.plotters.extendable.domain_extendable_heatmap.DomainExtendableHeatmap, lib5c.plotters.extendable.gene_extendable_heatmap.GeneExtendableHeatmap, lib5c.plotters.extendable.legend_extendable_heatmap.LegendExtendableHeatmap, lib5c.plotters.extendable.ruler_extendable_heatmap.RulerExtendableHeatmap, lib5c.plotters.extendable.cluster_extendable_heatmap.ClusterExtendableHeatmap, lib5c.plotters.extendable.snp_extendable_heatmap.SNPExtendableHeatmap, lib5c.plotters.extendable.motif_extendable_heatmap.MotifExtendableHeatmap, lib5c.plotters.extendable.rectangle_extendable_heatmap.RectangleExtendableHeatmap, lib5c.plotters.extendable.bed_extendable_heatmap.BedExtendableHeatmap, lib5c.plotters.extendable.base_extendable_heatmap.BaseExtendableHeatmap

Fully-extended ExtendableHeatmap class. Inherits from BaseExtendableHeatmap as well as all feature-providing classes.

Examples

>>> import numpy as np
>>> import matplotlib.patches as patches
>>> import matplotlib.colors as colors
>>> from lib5c.parsers.counts import load_counts
>>> from lib5c.parsers.primers import load_primermap
>>> from lib5c.parsers.bed import load_features
>>> from lib5c.parsers.table import load_table
>>> from lib5c.plotters.extendable import ExtendableHeatmap
>>> primermap = load_primermap('test/bins.bed')
>>> counts = load_counts('test/test.counts', primermap)['Sox2']
>>> h = ExtendableHeatmap(
...     array=counts,
...     grange_x={'chrom': 'chr3', 'start': 34108879, 'end': 35104879},
...     colorscale=(-10, 10),
...     colormap='obs_over_exp',
...     norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03)
... )
>>> xs = np.arange(len(counts)) + 0.5
>>> h.add_rulers()
[<matplotlib.axes._axes.Axes object at ...>,
 <matplotlib.axes._axes.Axes object at ...>]
>>> h.add_refgene_stacks('mm9', pad_before=0.1,
...                      colors={'NM_011443': 'r', 'NR_015580': 'b'})
[[<matplotlib.axes._axes.Axes object at ...>,
  <matplotlib.axes._axes.Axes object at ...>],
 [<matplotlib.axes._axes.Axes object at ...>,
  <matplotlib.axes._axes.Axes object at ...>]]
>>> h.add_legend({'Sox2': 'red', 'Sox2 OT': 'blue'})
<matplotlib.legend.Legend object at ...>
>>> boundaries = [{'chrom': 'chr3', 'start': 34459302, 'end': 34576915}]
>>> h.add_chipseq_tracks(load_features('test/tracks/CTCF_ES.bed',
...                                    boundaries=boundaries)['chr3'],
...                      name='ES CTCF')
[<matplotlib.axes._axes.Axes object at ...,
 <matplotlib.axes._axes.Axes object at ...>]
>>> h.add_chipseq_tracks(load_features('test/tracks/CTCF_NPC.bed',
...                                    boundaries=boundaries)['chr3'],
...                      name='NPC CTCF', color='r')
[<matplotlib.axes._axes.Axes object at ...,
 <matplotlib.axes._axes.Axes object at ...>]
>>> h.add_ax('sin')
<matplotlib.axes._axes.Axes object at ...>
>>> h['sin'].plot(xs, np.sin(xs))
[<matplotlib.lines.Line2D object at ...>]
>>> h['sin'].set_xlim((0, len(counts)))
(0, 83)
>>> h.add_colorbar()
<matplotlib.colorbar.Colorbar object at ...>
>>> h['horizontal_gene_track_1'].text(34558297, 0.5, 'Sox2', va='center',
...                                   ha='left', fontsize=5, color='r')
Text(3.45583e+07,0.5,'Sox2')
>>> h['horizontal_gene_track_1'].add_patch(
...     patches.Rectangle([34541337, 0], 16960, 1, fill=False, ec='r')
... )
<matplotlib.patches.Rectangle object at ...>
>>> h.outline_domains(load_features('test/communities.bed')['chr3'])
>>> h.add_clusters(
...     load_table('test/colors.tsv', load_primermap('test/bins_new.bed'),
...                dtype='|S25')['x']['Sox2'][0:41, 0:41],
...     colors='random')
>>> h.add_rectangles(['chr3:34541337-34568297_chr3:34651337-34678297'])
>>> h.add_rectangles(['chr3:34541337-34568297_chr3:34651337-34678297'],
...                  color='red', transpose=False)
>>> h.save('test/extendableheatmap.png')