plotting — Plotting tools#

This module provides all the plotting facilities that the other modules in the package make use of.

At the very basic level, the module provides a complete matplotlib setup tailored for interactive use in a GUI environment. This is encapsulated in the apply_stylesheet() function, which is automatically called with the default stylesheet when importing the module.

Note

In order to have a consistent plotting experience you are advised to always import pyplot from this module, rather than directly from matplotlib, i.e., use:

from aptapy.plotting import plt

rather than:

from matplotlib import pyplot as plt

This will ensure that the configuration block is properly executed.

The setup_axes() and setup_gca() functions provide a handy shorcut to set up axes via keyword arguments, encompassing the most common customizations (titles, labels, grids, legends, etc.).

Interactive cursors#

The module provides a zoomable, interactive cursor object, implemented in the VerticalCursor class. When activated, a cursor displays the numerical values of the x and y coordinates of the plottable 1-dimensional objects, and allows to zoom in and out interactively on the matplotlib canvas, more specifically:

  • left click and drag: select a rectangle for zooming in, with the zoom being applier on release;

  • right click: restore the initial view.

The cursor follows the mouse position when no button is clicked.

See also

Cursors interact seamlessly with StripChart objects, as illustrated in the Interactive cursor example.

Warning

At this time the cursor code is not optimized for efficiency—keep this in mind of the experience is not super fluid. There is undoubtedly room for improvement, e.g., using blitting (see issue #11). but we would like to let the API settle before we venture into that.

The plottable hierarchy#

The module defines an abstract base class, AbstractPlottable, which is the base class for all objects that can be plotted on a matplotlib canvas. The class defines the basic interface that all plottable objects must implement, as well as some common functionality, and is inherited by all the histogram and strip chart classes defined in the package, as well as by all the fitting models.

Styling matplotlib#

All native matplotlib styling facilities aside, aptapy provides a few custom stylesheets that can be used to style plots consistently across the package. The stylesheets are stored in the aptapy/styles folder, and can be applied in two different ways:

See also

The Dark theme and XKCD theme examples illustrate some of the custom aptapy stylesheets.

Warning

If you are using a matplotlib version newer than 3.7.1, you can use the dotted package-style syntax in conjunction with all the matplotlib styling facilities, and refer to the aptapy stylesheets directly as, e.g., aptapy.styles.aptapy-dark. The custom functions provided in this module allow you to refer to the aptapy stylesheets by name (e.g., aptapy-dark) and should support older matplotlib versions as well.

Module documentation#

Plotting facilities.

class aptapy.plotting.AbstractPlottable(label: str = None, xlabel: str = None, ylabel: str = None)[source]#

Abstract base class for plottable objects.

This is a small convenience class that defines a common interface for plottable objects, and it is meant to guarantee a consistent interface across different plottable objects, such as fitting models, histograms and strip charts.

This is largely based on the matplotlib plotting interface. A plottable object has three basic attributes:

  • a label, that is used to label the data series in the plot legend;

  • an xlabel, that is used to label the x axis of the plot;

  • a ylabel, that is used to label the y axis of the plot.

The main public interface is the plot() method, that takes care of plotting the object on the given axes (defaulting to the current axes), taking care of setting up the labels as needed. What the plot() method does internally is delegated to the _render() slot, that must be implemented by derived classes.

label: str = None#
xlabel: str = None#
ylabel: str = None#
plot(axes: Axes = None, **kwargs) Axes[source]#

Plot the object on the given axes (or on the current axes if none is passed as an argument).

The intended behavior for underlying text labels is that:

  • if the label attribute is set on the plottable object, this is used to create an entry in the legend;

  • if a label keyword argument is passed to this method, this overrides the object attribute;

  • if no label attribute is set on the object, and no label keyword argument is passed, no entry is created in the legend (i.e., we recover the native matplotlib behavior);

  • if the xlabel and/or ylabel attributes are set on the object, these are used to label the corresponding axes.

Derived classes can add behavior on top of this (e.g., enrich the label based on the current state of the object), but for consistency they should respect the intended behavior described above.

Arguments#

axesmatplotlib.axes.Axes, optional

The axes to plot on. If None, the current axes are used.

kwargskeyword arguments

Additional keyword arguments passed to the _render() method. Note that the specifics depends on how _render() is implemented, and which type of matplotlib object the plottable is representing.

Returns#

matplotlib.axes.Axes

The axes the object has been plotted on.

abstractmethod _render(axes: Axes, **kwargs) None[source]#

Render the object on the given axes.

Arguments#

axesmatplotlib.axes.Axes

The axes to plot on.

kwargskeyword arguments

Additional keyword arguments.

_abc_impl = <_abc._abc_data object>#
class aptapy.plotting.VerticalCursor(axes: Axes = None, **kwargs)[source]#

Class representing a zoomable vertical cursor attached to a matplotlib Axes object.

Arguments#

axesmatplotlib.axes.Axes, optional

The axes to draw the cursor on. If None, the current axes are used.

kwargskeyword arguments

Additional keyword arguments passed to axvline().

TEXT_SIZE = 'x-small'#
property canvas: FigureCanvasBase#

Return the underlying matplotlib canvas.

redraw_canvas() None[source]#

Trigger a re-draw of the underlying canvas.

This is factored into separate function, as which function, e.g., draw() or draw_idle(), has important performance implications, and this approach allow for a transparent, class-wide switch between one hook and the other.

add_marker(trajectory: Callable[[float], float], **kwargs) None[source]#

Add a new marker to the cursor.

Note the default color is taken from the last Line2D object that has been drawn on the canvas, which makes convenient, e.g., to add a marker right after you have plotted a strip chart.

Arguments#

trajectoryCallable[[float], float]

A callable representing the trajectory of the data set.

kwargskeyword arguments

Additional keyword arguments passed to the ConstrainedTextMarker constructor.

set_visible(visible: bool) bool[source]#

Set the visibility of the cursor elements.

Arguments#

visiblebool

Flag indicating whether the cursor elements should be visible or not.

Returns#

bool

True if a redraw is needed, False otherwise.

move(x: float) None[source]#

Move the cursor to a given x position.

Arguments#

xfloat

The x position to move the cursor to.

_rectangle_coords(event: MouseEvent) Tuple[source]#

Return the (x0, y0, x1, y1) coordinates of the rectangle defined by the _last_press_position and the current event position.

The tuple is guaranteed to be in the right order, i.e., x1 >= x0 and y1 >= y0, which simplifies the operations downstream.

Arguments#

eventmatplotlib.backend_bases.MouseEvent

The mouse event we want to respond to.

on_button_press(event: MouseEvent) None[source]#

Function processing the mouse button press events.

Arguments#

eventmatplotlib.backend_bases.MouseEvent

The mouse event we want to respond to.

on_button_release(event: MouseEvent) None[source]#

Function processing the mouse button release events.

Arguments#

eventmatplotlib.backend_bases.MouseEvent

The mouse event we want to respond to.

on_motion_notify(event: MouseEvent) None[source]#

Function processing the mouse events.

Arguments#

eventmatplotlib.backend_bases.MouseEvent

The mouse event we want to respond to.

activate() None[source]#

Enable the cursor by connecting the mouse motion event to the on_mouse_move() method.

deactivate() None[source]#

Disable the cursor by disconnecting the mouse motion event.

aptapy.plotting.setup_axes(axes, **kwargs)[source]#

Setup a generic axes object.

aptapy.plotting.setup_gca(**kwargs)[source]#

Setup the axes for the current plot.

aptapy.plotting.last_line_color(axes: Axes = None, default: str = 'black') str[source]#

Return the color used to draw the last line

Arguments#

axesmatplotlib.axes.Axes

The axes to get the last line color from.

defaultstr

The default color to return if no lines are found.

aptapy.plotting.apply_stylesheet(style: str = 'aptapy') None[source]#

Apply a given matplotlib stylesheet permanently.

See https://matplotlib.org/stable/users/explain/customizing.html for more information about the basic matplotlib customization.

Note plt.style.use accepts dotted names of the form package.style_name (in that case, package should be an importable Python package name; style files in subpackages are allowed too.)

If you want to temporarily apply a given style, consider using the plt.style.context() context manager instead (the rules for the stylesheets are exactly the same).

Arguments#

stylestr

The style to use for the plot.

aptapy.plotting.stylesheet_context(style: str = 'aptapy') Generator[None, None, None][source]#

Context manager to temporarily apply a given matplotlib stylesheet.

Arguments#

stylestr

The style to use for the plot.

aptapy.plotting.reset(gallery_conf: Dict = None, fname: str = None) None[source]#

Reset the matplotlib configuration to the default one.

This is the hook called by sphinx-gallery before running each example script, to avoid that configuration changes in one example affect the subsequent ones. The callback is configured in docs/conf.py, via the reset_module key of the sphinx_gallery_conf.