dantro.plot.utils package#

Subpackage that organizes general plotting utilities.

Submodules#

dantro.plot.utils._file_writer module#

This module implements custom matplotlib movie writers; basically, these are specializations of matplotlib.animation.AbstractMovieWriter.

class FileWriter(*, name_padding: int = 7, fstr: str = '{dir:}/{num:0{pad:}d}.{ext:}')[source]#

Bases: matplotlib.animation.AbstractMovieWriter

A specialization of matplotlib.animation.AbstractMovieWriter that writes each frame to a file.

It is registered as the frames writer.

__init__(*, name_padding: int = 7, fstr: str = '{dir:}/{num:0{pad:}d}.{ext:}')[source]#

Initialize the FileWriter, which adheres to the matplotlib.animation interface and can be used to write each frame of an animation to individual files.

Parameters
  • name_padding (int, optional) – How wide the numbering should be

  • fstr (str, optional) – The format string to generate the name

setup()[source]#

Called when entering the saving context

finish()[source]#

Called when finished

classmethod isAvailable() bool[source]#

Always available.

saving(fig: Figure, base_outfile: str, dpi: Optional[int] = None, **setup_kwargs)[source]#

Create an instance of the context manager

Parameters
  • fig (Figure) – The figure object to save

  • base_outfile (str) – The path this movie writer would store a movie file at; the file name will be interpreted as the name of the directory that the frames are saved to; the file extension is retained.

  • dpi (int, optional) – The desired densiy

  • **setup_kwargs – Passed to setup method

Returns

this object, which also is a context manager.

Return type

FileWriter

grab_frame(**savefig_kwargs)[source]#

Stores a single frame

__enter__()[source]#

Called when entering context.

Makes sure that the output directory exists.

__exit__(*args)[source]#

Called when exiting context.

Closes the figure.

_abc_impl = <_abc._abc_data object>#
property frame_size#

A tuple (width, height) in pixels of a movie frame.

dantro.plot.utils.color_mngr module#

Implements the ColorManager which simplifies working with matplotlib.colors.Colormap and related objects.

NORMS = {'BoundaryNorm': <class 'matplotlib.colors.BoundaryNorm'>, 'CenteredNorm': <class 'matplotlib.colors.CenteredNorm'>, 'FuncNorm': <class 'matplotlib.colors.FuncNorm'>, 'LogNorm': <class 'matplotlib.colors.LogNorm'>, 'NoNorm': <class 'matplotlib.colors.NoNorm'>, 'Normalize': <class 'matplotlib.colors.Normalize'>, 'PowerNorm': <class 'matplotlib.colors.PowerNorm'>, 'SymLogNorm': <class 'matplotlib.colors.SymLogNorm'>, 'TwoSlopeNorm': <class 'matplotlib.colors.TwoSlopeNorm'>}#

matplotlib color normalizations supported by the ColorManager. See the matplotlib.colors module for more information.

class ColorManager(*, cmap: Optional[Union[str, dict, list, Colormap]] = None, norm: Optional[Union[str, dict, Normalize]] = None, labels: Optional[Union[List[str], Dict[float, str]]] = None, vmin: Optional[float] = None, vmax: Optional[float] = None, discretized: Optional[bool] = None)[source]#

Bases: object

Custom color manager which provides an interface to the matplotlib.colors module and aims to simplify working with colormaps, colorbars, and different normalizations.

_NORMS_NOT_SUPPORTING_VMIN_VMAX: Tuple[str] = ('BoundaryNorm', 'CenteredNorm')#

Names of norms that do not support getting passed the vmin and vmax arguments.

_POSSIBLE_CMAP_KWARGS: Tuple[str] = ('name', 'colors', 'segmentdata', 'bad', 'under', 'over', 'reversed', 'N', 'gamma', 'placeholder_color', 'continuous', 'from_values')#

Keyword arguments that are used by matplotlib or the ColorManager to construct colormaps. If using the implicit syntax for defining labels and colormap values, these can not be used for labels.

_SNS_COLOR_PALETTE_PREFIX: str = 'color_palette::'#

If a colormap name starts with this string, will use seaborn.color_palette() to generate the colormap

_SNS_DIVERGING_PALETTE_PREFIX: str = 'diverging::'#

If a colormap name starts with this string, will use seaborn.diverging_palette() to generate the colormap, parsing the remaining parts of the name into positional and keyword arguments.

__init__(*, cmap: Optional[Union[str, dict, list, Colormap]] = None, norm: Optional[Union[str, dict, Normalize]] = None, labels: Optional[Union[List[str], Dict[float, str]]] = None, vmin: Optional[float] = None, vmax: Optional[float] = None, discretized: Optional[bool] = None)[source]#

Initializes a ColorManager by building the colormap, the norm, and the colorbar labels.

Refer to the dedicated documentation page for examples and integration instructions.

Parameters
  • cmap (Union[str, dict, list, Colormap], optional) –

    The colormap specification. If this is not already a matplotlib.colors.Colormap instance, it will be parsed into a dict-like specification, which has the options as shown below.

    • If cmap is a string, it is turned into dict(name=cmap).

    • If cmap is a list (or tuple), it will be converted to dict(from_values=cmap), creating a segmented colormap. See below for more information.

    In dict form, the following arguments are available:

    name (str, optional):

    Name of a registered matplotlib colormap or None to use a default. For available colormap names, see here.

    Also supports seaborn colormaps. If the name starts with the _SNS_COLOR_PALETTE_PREFIX string, seaborn.color_palette() is used to generate the colormap. If starting with _SNS_DIVERGING_PALETTE_PREFIX, seaborn.diverging_palette() is invoked, using argument specified as part of the name.

    This opens many possibilities, as shown in the seaborn documentation. For example:

    color_palette::YlOrBr
    color_palette::icefire
    color_palette::icefire_r          # reversed
    color_palette::light:b            # white -> blue
    color_palette::dark:b             # black -> blue
    color_palette::light:#69d         # custom color
    color_palette::light:#69d_r       # ... reversed
    color_palette::dark:salmon_r      # named, reversed
    color_palette::ch:s=-.2,r=.6      # cubehelix
    
    diverging::220,20
    diverging::145,300,s=60
    diverging::250, 30, l=65, center=dark
    

    Here, the ch:<key>=<val>,<key>=<val> syntax is used to create a seaborn.cubehelix_palette(). The same <arg>,<arg>,<key>=<val>,<key>=<val> syntax is used for the diverging palette.

    Note

    When specifying these via YAML, make sure to put the string into single or double quotes to avoid it being interpreted as a YAML mapping.

    from_values (Union[dict, list], optional):

    Dict of colors keyed by bin-specifier. If given, name is ignored and a discrete colormap is created from the list of specified colors. The norm is then set to matplotlib.colors.BoundaryNorm.

    The bins can be specified either by bin-centers (Scalar) or by bin-intervals (2-tuples). For the former, the deduced bin-edges are assumed halfway between the bin-centers. For the latter, the given intervals must be pairwise connected. In both cases, the bins must monotonically increase.

    If a list of colors is passed they are automatically assigned to the bin-centers [0, 1, 2, ...], potentially shifted depending on vmin and vmax. Inferring these values is done in _infer_pos_map().

    Alternatively, a continuous, linearly interpolated colormap can be generated by setting the continuous flag, see below. This will construct a LinearSegmentedColormap. In such a case, keys in from_values can only be scalar, bin intervals cannot be specified.

    continuous (bool, optional):

    If True, will interpret the from_values data as specifying points between which a linear interpolation is carried out. Will create a LinearSegmentedColormap.

    under (Union[str, dict], optional):

    Passed on to set_under()

    over (Union[str, dict], optional):

    Passed on to set_over()

    bad (Union[str, dict], optional):

    Passed on to set_bad()

    placeholder_color (str, optional):

    None values in from_values are replaced with this color (default: white).

    reversed (bool, optional):

    If True, will reverse the colormap.

    labels_and_colors (dict, optional):

    This is a shorthand syntax for specifying colorbar labels and colors at the same time. Keys refer to labels, values to colors. The label positions and bounds are inferred using _infer_pos_map() and are affected by vmin and vmax. These may also be given implicitly via **kwargs (see below), but not at the same time!

    Effectively, the mapping is unpacked into two parts: The keys are used to specify the values of the labels dict (on the top-level); the values are used to specify the values of the cmap.from_values dict (see above). The keys are inferred from the length of the sequence and vmin and vmax, expecting to map to an integer data positions.

    Example:

    cmap:
      empty: darkkhaki            # -> 0
      susceptible: forestgreen    # -> 1
      exposed: darkorange         # ...
      infected: firebrick
      recovered: slategray
      deceased: black
      source: maroon
      inert: moccasin             # -> 7
    
      # can still set extremes here (should not appear)
      under: red
      over: red
    
    **kwargs (optional):

    Depending on the argument names, these are either passed to colormap instantiation or are used to specify the labels_and_colors mapping. For the latter, labels may not be named after arguments that are relevant for colormap initialization (_POSSIBLE_CMAP_KWARGS).

  • norm (Union[str, dict, Normalize], optional) – The norm that is applied for the color-mapping. If it is a string, the matching norm in matplotlib.colors is created with default values. If it is a dict, the name entry specifies the norm and all further entries are passed to its constructor. Overwritten if a discrete colormap is specified via cmap.from_values.

  • labels (Union[List[str], Dict[float, str]], optional) – Colorbar tick-labels keyed by tick position. If a list of labels is passed they are automatically assigned to the positions [0, 1, 2, ...] (if no vmin and vmax are given) or [vmin, vmin + 1, ..., vmax] otherwise.

  • vmin (float, optional) – The lower bound of the color-mapping. Not passed to matplotlib.colors.BoundaryNorm, which does not support it. If given, this argument in combination with vmax needs to define an integer range that has the same number of values as needed for a colormap constructed from from_values or via the label -> color mapping. If discretized is set, this value will be set to ceil(vmin) - 0.5.

  • vmax (float, optional) – The upper bound of the color-mapping. Not passed to matplotlib.colors.BoundaryNorm, which does not support it. If given, this argument in combination with vmin needs to define an integer range that has the same number of values as needed for a colormap constructed from from_values or via the label -> color mapping. If discretized is set, this value will be set to floor(vmax) + 0.5.

  • discretized (bool, optional) – If True, assumes that the data this colormap is to represent only has integer values and makes a number of changes to improve the overall visualization. For instance, if True, the vmin and vmax values will be set to the appropriate half-integer such that tick positions are centered within the corresponding range. If None (default), will do this automatically if a colormap is constructed via from_values or via label -> color mapping.

property cmap: Colormap#

Returns the constructed colormap object

property norm: Normalize#

Returns the constructed normalization object

property labels: dict#

A dict or list of colorbar labels

property vmin: Optional[float]#

The vmin value of the colormap and norm

property vmax: Optional[float]#

The vmax value of the colormap and norm

map_to_color(X: Union[float, ndarray])[source]#

Maps the input data to color(s) by applying both norm and colormap.

Parameters

X (Union[float, ndarray]) – Data value(s) to convert to RGBA.

Returns

Tuple of RGBA values if X is scalar, otherwise an array of RGBA values with a shape of X.shape + (4, ).

create_cbar(mappable: ScalarMappable, *, fig: Optional[Figure] = None, ax: Optional[Axes] = None, label: Optional[str] = None, label_kwargs: Optional[dict] = None, tick_params: Optional[dict] = None, extend: str = 'auto', **cbar_kwargs) Colorbar[source]#

Creates a colorbar of a given mappable

Parameters
Returns

The created colorbar object

Return type

Colorbar

_parse_cmap_kwargs(*, _labels: Union[list, dict], name: Optional[str] = None, continuous: Optional[bool] = None, from_values: Optional[Union[list, dict]] = None, placeholder_color: str = 'w', labels_and_colors: Optional[dict] = None, **kwargs) Tuple[dict, dict, dict][source]#
Parameters
  • _labels (Union[list, dict]) – The (top-level!) labels argument. While not being parsed here, it is needed for informative error messages.

  • name (str, optional) – Name of the colormap

  • continuous (bool, optional) – Whether to create a continuous or a discrete colormap.

  • from_values (Union[dict, list], optional) – The values from which to create the colormap. Keys are either given explicitly or inferred using _infer_pos_map().

  • placeholder_color (str, optional) – Color used when a value in from_values did not specify a value.

  • **kwargs – combined keyword arguments for the colormap creation and shorthand entries for label -> color mapping.

_parse_norm_kwargs(*, name: Optional[str] = None, **kws) dict[source]#

Parses the norm arguments into a uniform shape

_parse_cbar_labels(labels: Union[None, Dict[float, str], Sequence[str]]) Optional[Dict[float, str]][source]#

Parses the labels argument into a uniform shape

_infer_pos_map(seq: Sequence[Any], *, vmin: Optional[int] = None, vmax: Optional[int] = None) Dict[float, Any][source]#

Given a sequence, infers a mapping position -> value, where the positions are numeric values and the values of the resulting dict are the ones from the given sequence.

If vmin and vmax are given, they are used to help with inferring the values. Note that these arguments need to be explicitly passed.

_parse_boundaries(bins: Sequence, *, set_vmin_vmax: bool = False, discretized: bool = False) Tuple[float][source]#

Parses the boundaries for the BoundaryNorm.

Parameters
  • bins (Sequence) – Either monotonically increasing sequence of bin centers or sequence of connected intervals (2-tuples).

  • set_vmin_vmax (bool, optional) – Description

  • discretized (bool, optional) – Description

Returns

Monotonically increasing boundaries.

Return type

Tuple[float]

Raises

ValueError – On disconnected intervals or decreasing boundaries.

_create_cmap(*, name: Optional[str] = None, colors: Optional[list] = None, segmentdata: Optional[dict] = None, bad: Optional[Union[dict, str]] = None, under: Optional[Union[dict, str]] = None, over: Optional[Union[dict, str]] = None, reversed: bool = False, N: Optional[int] = None, gamma: float = 1.0) Colormap[source]#

Creates a colormap.

Parameters
Returns

The created colormap.

Return type

Colormap

Raises

ValueError – On invalid colormap name.

_create_norm(name: Optional[str] = None, **norm_kwargs) Normalize[source]#

Creates a norm.

Parameters
Returns

The created norm.

Return type

Normalize

Raises

ValueError – On invalid norm specification.

parse_cmap_and_norm_kwargs(*, _key_map: Optional[dict] = None, use_color_manager: bool = True, **kws) dict[source]#

A function that parses colormap-related keyword arguments and passes them through the ColorManager, making its functionality available in places that would otherwise not be able to use the expanded syntax of the color manager.

Note

The resulting dict will only have the cmap and cbar kwargs (or their mapped equivalents) set from the color manager, all other arguments are simply passed through.

In particular, this means that the labels feature of the color manager is not supported, because this function has no ability to set the colorbar.

Parameters
  • _key_map (dict, optional) – If custom keyword argument keys are expected as output, e.g. hue_cmap instead of cmap, set the values to these custom names: {"cmap": "hue_cmap"}. Expected keys are cmap, norm, vmin, vmax. If not set or partially not set, will use defaults.

  • use_color_manager (bool, optional) – If false, will simply pass through

  • **kws – Keyword arguments to parse

Returns

The updated keyword arguments with cmap and norm (or equivalent keys according to _key_map).

Return type

dict

dantro.plot.utils.mpl module#

Matplotlib utilities which are used in PlotHelper or other places.

class figure_leak_prevention(*, close_current_fig_on_raise: bool = False)[source]#

Bases: object

Context manager that aims to prevent superfluous matplotlib figures persisting beyond the context. Such figure objects can aggregate and start memory issues or even representation errors.

Specifically, it does the following:

  • When entering, stores all current figure numbers

  • When exiting regularly, all figures that were opened within the context are closed, except the currently selected figure.

  • When exiting with an exception, the behaviour is the same, unless the close_current_fig_on_raise is set, in which case the currently selected figure is not excluded from closing.

__init__(*, close_current_fig_on_raise: bool = False)[source]#

Initialize the context manager

Parameters

close_current_fig_on_raise (bool, optional) – If True, the currently selected figure will not be exempt from the figure closure in case an exception occurs. This flag has no effect when the context is exited without an exception.

__enter__()[source]#

Upon entering, store all currently open figure numbers

__exit__(exc_type: type, *args) None[source]#

Iterates over all currently open figures and closes all figures that were not previously open, except the currently selected figure.

If an exception is detected, i.e. exc_type` is **not** None, the current figure is only closed if the context manager was entered with the ``close_current_fig_on_raise flag set.

calculate_space_needed_hv(fig: Figure, obj, *, spacing_h: float = 0.02, spacing_v: float = 0.02) Tuple[float, float][source]#

Calculates the horizontal and vertical space needed for an object in this figure.

Note

This will invoke matplotlib.figure.Figure.draw() two times and cause resizing of the figure!

Parameters
  • fig (Figure) – The figure

  • obj – The object in that figure to fit

  • spacing_h (float, optional) – Added to space needed (in inches)

  • spacing_v (float, optional) – Added to space needed (in inches)

Returns

the horizontal and vertical space needed to fit

into the figure (in inches).

Return type

Tuple[float, float]

remove_duplicate_handles_labels(h: list, l: list) Tuple[list, list][source]#

Returns new aligned lists of handles and labels from which duplicates (identified by label) are removed.

This maintains the order and association by keeping track of seen items; see https://stackoverflow.com/a/480227/1827608 for more information.

Parameters
  • h (list) – List of artist handles

  • l (list) – List of labels

Returns

handles and labels

Return type

Tuple[list, list]

gather_handles_labels(mpo) Tuple[list, list][source]#

Uses .findobj to search a figure or axis for legend objects and returns lists of handles and (string) labels.

prepare_legend_args(h, l, *, custom_labels: List[str], hiding_threshold: int) Tuple[list, list, bool][source]#

A utility function that allows setting custom legend handles and implements some logic to hide all handles if there are too many.

set_tick_locators_or_formatters(*, ax: Axes, kind: str, x: dict = None, y: dict = None, z: dict = None)[source]#

Sets the tick locators or formatters. Look at the PlotHelper methods _hlpr_set_tick_{locators/formatters} for more information.

Names are looked up in the matplotlib.ticker and matplotlib.dates modules.

Parameters
  • ax (Axes) – The axes object

  • kind (str) – Whether to set a locator or a formatter.

  • x (dict, optional) – The config for the x-axis tick locator/formatter

  • y (dict, optional) – The config for the y-axis tick locator/formatter

  • z (dict, optional) – The config for the z-axis tick locator/formatter

dantro.plot.utils.plot_func module#

Implements utilities that revolve around the plotting function which is then invoked by the plot creators:

  • a decorator to declare a function as a plot function

  • the tools to resolve a plotting function from a module or file

class PlotFuncResolver(*, base_module_file_dir: Optional[str] = None, base_pkg: Optional[str] = None)[source]#

Bases: object

Takes care of resolving a plot function

BASE_PKG: str = 'dantro.plot.funcs'#

The default module string to use for relative module imports, where this module becomes the base package. Evaluated in __init__().

__init__(*, base_module_file_dir: Optional[str] = None, base_pkg: Optional[str] = None)[source]#

Set up the plot function resolver.

Parameters
  • base_module_file_dir (str, optional) – If given, module_file arguments to resolve() that are relative paths will be seen relative to this directory. Needs to be an absolute directory path and supports ~ expansion.

  • base_pkg (str, optional) – If given, use this base package instead for relative module imports instead of BASE_PKG.

Raises
resolve(*, plot_func: Union[str, Callable], module: Optional[str] = None, module_file: Optional[str] = None) Callable[source]#

Resolve and return the plot function callable

Parameters
  • plot_func (Union[str, Callable]) – The name or module string of the plot function as it can be imported from module. If this is a callable will directly return that callable.

  • module (str) – If plot_func was the name of the plot function, this needs to be the name of the module to import that name from.

  • module_file (str) – Path to the file to load and look for the plot_func in. If base_module_file_dir is given during initialization, this can also be a path relative to that directory.

Returns

The resolved plot function

Return type

Callable

Raises

TypeError – On bad argument types

_get_module_from_file(path: str, *, base_module_file_dir: str)[source]#

Returns the module corresponding to the file at the given path.

This uses import_module_from_file() to carry out the import.

_get_module_via_import(*, module: str, base_pkg: str)[source]#

Returns the module via import.

Imports module via importlib, allowing relative imports from the package defined as base package.

_attach_attributes(plot_func: Callable, /, *, module=None, plot_func_modstr: Optional[str] = None) Callable[source]#

Attaches some informational attributes to the plot function.

class is_plot_func(*, creator: Optional[str] = None, creator_type: Optional[type] = None, creator_name: Optional[str] = None, use_dag: Optional[bool] = None, required_dag_tags: Optional[Sequence[str]] = None, compute_only_required_dag_tags: bool = True, pass_dag_object_along: bool = False, unpack_dag_results: bool = False, use_helper: Optional[bool] = None, helper_defaults: Optional[Union[dict, str]] = None, supports_animation=False, add_attributes: Optional[dict] = None)[source]#

Bases: object

This is a decorator class declaring the decorated function as a plotting function to use with BasePlotCreator or derived creators.

Note

This decorator has a set of specializations that make sense only when using a specific creator type! For example, the helper-related arguments are only used by PyPlotCreator and are ignored without warning otherwise.

__init__(*, creator: Optional[str] = None, creator_type: Optional[type] = None, creator_name: Optional[str] = None, use_dag: Optional[bool] = None, required_dag_tags: Optional[Sequence[str]] = None, compute_only_required_dag_tags: bool = True, pass_dag_object_along: bool = False, unpack_dag_results: bool = False, use_helper: Optional[bool] = None, helper_defaults: Optional[Union[dict, str]] = None, supports_animation=False, add_attributes: Optional[dict] = None)[source]#

Initialize the decorator.

Note

Some arguments are only evaluated when using a certain creator type, e.g. PyPlotCreator.

Parameters
  • creator (str, optional) – The creator to use; needs to be registered with the PlotManager under this name.

  • creator_type (type, optional) – The type of plot creator to use. This argument is DEPRECATED, use creator instead.

  • creator_name (str, optional) – The name of the plot creator to use. This argument is DEPRECATED, use creator instead.

  • use_dag (bool, optional) – Whether to use the data transformation framework.

  • required_dag_tags (Sequence[str], optional) – The DAG tags that are required by the plot function.

  • compute_only_required_dag_tags (bool, optional) – Whether to compute only those DAG tags that are specified as required by the plot function. This is ignored if no required DAG tags were given and can be overwritten by the compute_only argument.

  • pass_dag_object_along (bool, optional) – Whether to pass on the DAG object to the plot function

  • unpack_dag_results (bool, optional) – Whether to unpack the results of the DAG computation directly into the plot function instead of passing it as a dictionary.

  • use_helper (bool, optional) – Whether to use the PlotHelper with this plot. Needs PyPlotCreator. If None, will default to True for supported creators and False otherwise.

  • helper_defaults (Union[dict, str], optional) – Default configurations for helpers; these are automatically considered to be enabled. If not dict-like, will assume this is an absolute path (supporting ~ expansion) to a YAML file and will load the dict-like configuration from there. Needs PyPlotCreator.

  • supports_animation (bool, optional) – Whether the plot function supports animation. Needs PyPlotCreator.

  • add_attributes (dict, optional) – Additional attributes to add to the plot function.

Raises

ValueError – If helper_defaults was a string but not an absolute path.

__call__(func: Callable)[source]#

If there are decorator arguments, __call__() is only called once, as part of the decoration process and expects as only argument the function to be decorated.