API Reference

Lifegraph

class lifegraph.Lifegraph(birthdate, size=Papersize.A3, dpi=300, label_space_epsilon=0.2, max_age=90, min_age=0, axes_rect=None, ax=None)[source]

Bases: object

Visualize a life as a grid of weekly squares.

Each row represents one year of life and each column one week, creating a 52-column by max_age-row grid. Events, eras, and other annotations can be added and are automatically laid out to avoid overlapping labels.

Parameters:
  • birthdate (datetime.date) – The date to anchor the grid. Row 0, column 1 corresponds to the first week of life.

  • size (Papersize, optional) – Paper size that controls default figure dimensions and styling parameters. Default is Papersize.A3.

  • dpi (int, optional) – Resolution in dots per inch. Default is 300.

  • label_space_epsilon (float, optional) – Minimum gap (in data units) the layout engine keeps between annotation labels. Default is 0.2.

  • max_age (int, optional) – Number of rows (years) in the grid. Default is 90.

  • axes_rect (list of float, optional) – [left, bottom, width, height] passed to matplotlib.figure.Figure.add_axes(). Ignored when ax is provided. Default is [0.25, 0.1, 0.5, 0.8].

  • ax (matplotlib.axes.Axes or None, optional) – An existing axes to draw on. When provided, the caller is responsible for the figure lifecycle (saving, showing, closing). Default is None (a new figure is created).

Examples

Create a basic life graph and save it:

>>> from lifegraph import Lifegraph
>>> from datetime import date
>>> g = Lifegraph(date(1990, 11, 1))
>>> g.save("my_life.png")

Use a provided axes for subplot composition:

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> g = Lifegraph(date(1990, 11, 1), ax=ax, max_age=50)
>>> g.draw()
>>> fig.savefig("subplot.png")
>>> plt.close(fig)
format_x_axis(text=None, positionx=None, positiony=None, color=None, fontsize=None)[source]

Customise the x-axis label appearance.

All parameters are optional; only the supplied values are changed.

Parameters:
  • text (str or None, optional) – Replacement label text.

  • positionx (float or None, optional) – X position of the label in axes coordinates.

  • positiony (float or None, optional) – Y position of the label in axes coordinates.

  • color (str or tuple or None, optional) – A matplotlib color.

  • fontsize (float or None, optional) – Font size in points.

Examples

>>> g.format_x_axis(text="Weeks", color="red", fontsize=14)
format_y_axis(text=None, positionx=None, positiony=None, color=None, fontsize=None)[source]

Customise the y-axis label appearance.

All parameters are optional; only the supplied values are changed.

Parameters:
  • text (str or None, optional) – Replacement label text.

  • positionx (float or None, optional) – X position of the label in axes coordinates.

  • positiony (float or None, optional) – Y position of the label in axes coordinates.

  • color (str or tuple or None, optional) – A matplotlib color.

  • fontsize (float or None, optional) – Font size in points.

Examples

>>> g.format_y_axis(text="Your Age", color="green")
show_max_age_label()[source]

Display the maximum age number at the bottom-right of the grid.

Examples

>>> g = Lifegraph(date(1990, 1, 1), max_age=100)
>>> g.show_max_age_label()
add_life_event(text, date, color=None, hint=None, side=None, color_square=True)[source]

Add a labeled event to the graph.

The event position on the grid is calculated from the birthdate and the event date. An arrow connects the label text to the corresponding grid square.

Parameters:
  • text (str) – Label text for the event.

  • date (datetime.date) – When the event occurred.

  • color (str or tuple or None, optional) – A matplotlib color. A random color is chosen when None.

  • hint (Point or tuple or None, optional) – Approximate label position in data coordinates. Mutually exclusive with side.

  • side (Side or None, optional) – Force the label to Side.LEFT or Side.RIGHT. Mutually exclusive with hint.

  • color_square (bool, optional) – If True (default), the grid square is colored to match the label.

Raises:

ValueError – If date is outside the range [birthdate, birthdate + max_age).

Examples

>>> from lifegraph import Lifegraph, Side
>>> from datetime import date
>>> g = Lifegraph(date(1990, 11, 1))
>>> g.add_life_event("Graduated", date(2012, 5, 20), color="#00FF00")
>>> g.add_life_event("Moved abroad", date(2015, 3, 1), side=Side.LEFT)
add_era(text, start_date, end_date, color=None, side=None, alpha=0.3)[source]

Highlight a period of your life with a colored background.

The background spans from start_date to end_date behind the grid squares.

Parameters:
  • text (str) – Label text for the era.

  • start_date (datetime.date) – When the era started.

  • end_date (datetime.date) – When the era ended.

  • color (str or tuple or None, optional) – A matplotlib color. A random color is chosen when None.

  • side (Side or None, optional) – Force the label to a specific side of the grid.

  • alpha (float, optional) – Opacity of the colored background. Default is 0.3.

Raises:

ValueError – If either date is outside the valid range.

Examples

>>> from lifegraph import Lifegraph
>>> from datetime import date
>>> g = Lifegraph(date(1990, 1, 1))
>>> g.add_era("College", date(2008, 9, 1), date(2012, 5, 15),
...           color="blue", alpha=0.2)
add_era_span(text, start_date, end_date, color=None, hint=None, side=None, color_start_and_end_markers=False)[source]

Add a dumbbell-shaped annotation marking a time span.

Circles are drawn at the start and end grid positions, connected by a line, with a label pointing to the midpoint.

Parameters:
  • text (str) – Label text for the era span.

  • start_date (datetime.date) – When the span started.

  • end_date (datetime.date) – When the span ended.

  • color (str or tuple or None, optional) – A matplotlib color. A random color is chosen when None.

  • hint (Point or tuple or None, optional) – Approximate label position in data coordinates. Mutually exclusive with side.

  • side (Side or None, optional) – Force the label to a specific side. Mutually exclusive with hint.

  • color_start_and_end_markers (bool, optional) – If True, the start and end grid squares are colored to match the label. Default is False.

Raises:

ValueError – If either date is outside the valid range.

Examples

>>> from lifegraph import Lifegraph
>>> from datetime import date
>>> g = Lifegraph(date(1990, 1, 1))
>>> g.add_era_span("Road trip", date(2015, 6, 1),
...                date(2015, 8, 30), color="#D2691E")
add_watermark(text)[source]

Add diagonal watermark text across the graph.

Parameters:

text (str) – The watermark text.

Examples

>>> g.add_watermark("DRAFT")
add_title(text, fontsize=None)[source]

Add a title above the graph.

Parameters:
  • text (str) – Title text.

  • fontsize (float or None, optional) – Font size in points. Uses the paper-size default when None.

Examples

>>> g.add_title("The Life of Ada Lovelace")
add_image(image_name, alpha=1)[source]

Overlay an image on the graph axes.

The image is stretched to fill the grid area.

Parameters:
  • image_name (str) – Path to the image file.

  • alpha (float, optional) – Opacity of the image overlay. Default is 1.

Examples

>>> g.add_image("background.jpg", alpha=0.5)
draw()[source]

Render the graph onto the axes.

Call this explicitly when using a provided ax and you want to trigger rendering before saving or showing the figure yourself.

Examples

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> g = Lifegraph(date(1990, 1, 1), ax=ax, max_age=50)
>>> g.draw()
>>> fig.savefig("out.png")
>>> plt.close(fig)
show()[source]

Render the graph and display it interactively.

When using a provided axes, the caller should call matplotlib.pyplot.show() on their own figure instead.

Examples

>>> g = Lifegraph(date(1990, 1, 1))
>>> g.add_title("My Life")
>>> g.show()
close()[source]

Close the figure and free resources.

Only has an effect when the figure was created internally (i.e. no ax was provided).

save(name, transparent=False)[source]

Render the graph and save it to a file.

Parameters:
  • name (str) – Output file path (e.g. "my_life.png").

  • transparent (bool, optional) – Save with a transparent background. Default is False.

Examples

>>> g = Lifegraph(date(1990, 1, 1))
>>> g.save("my_life.png")
save_config(path, include_styling=False)[source]

Export the graph configuration to a JSON or YAML file.

The file format is inferred from the extension: .json for JSON, .yaml or .yml for YAML.

Parameters:
  • path (str or pathlib.Path) – Output file path.

  • include_styling (bool, optional) – If True, axis label customisations are included. Default is False.

classmethod from_config(path, apply_styling=True)[source]

Create a Lifegraph from a previously exported config file.

Parameters:
  • path (str or pathlib.Path) – Path to a .json, .yaml, or .yml config file.

  • apply_styling (bool, optional) – If True (default) and the file contains a styling section, axis customisations are applied.

Return type:

Lifegraph

Side

class lifegraph.core.Side(value)[source]

Bases: Enum

Specify which side of the plot to place an annotation.

Use Side.LEFT to place the label to the left of the grid or Side.RIGHT to place it to the right.

Examples

>>> from lifegraph import Lifegraph, Side
>>> from datetime import date
>>> g = Lifegraph(date(1990, 1, 1))
>>> g.add_life_event("Event", date(2000, 6, 1), side=Side.LEFT)
LEFT = 1
RIGHT = 2

Core data structures

class lifegraph.core.Point(x, y)[source]

Bases: object

A 2-D point in data coordinates.

Parameters:
  • x (float) – The x coordinate.

  • y (float) – The y coordinate.

Examples

>>> from lifegraph.core import Point
>>> p = Point(10, 20)
>>> p.x
10
class lifegraph.core.DatePosition(x, y, date)[source]

Bases: Point

A point on the grid associated with a calendar date.

Extends Point to additionally store the date that maps to the (week, year_of_life) grid coordinate.

Parameters:
  • x (int) – Week number (1–52).

  • y (int) – Year of life (0-indexed from birthdate).

  • date (datetime.date) – The calendar date this position represents.

Examples

>>> from lifegraph.core import DatePosition
>>> from datetime import date
>>> dp = DatePosition(10, 5, date(1995, 3, 1))
>>> dp.date
datetime.date(1995, 3, 1)
class lifegraph.core.Marker(x, y, marker='s', fillstyle='none', color='black')[source]

Bases: Point

Configuration for a colored marker drawn on the grid.

Extends Point with matplotlib marker styling attributes.

Parameters:
  • x (float) – The x position of the marker.

  • y (float) – The y position of the marker.

  • marker (str, optional) – A matplotlib marker style. Default is 's' (square).

  • fillstyle (str, optional) – A matplotlib fill style. Default is 'none'.

  • color (str or tuple, optional) – A matplotlib color. Default is 'black'.

Examples

>>> from lifegraph.core import Marker
>>> m = Marker(5, 10, color='red')
class lifegraph.core.Annotation(date, text, label_point, color='black', bbox=None, event_point=None, put_circle_around_point=True, marker=None, relpos=(0.5, 0.5), source_y_range=None)[source]

Bases: Point

A text annotation with layout-conflict resolution support.

Holds the label text and its position, along with metadata used by Lifegraph to prevent overlapping labels.

Parameters:
  • date (datetime.date) – When the annotated event occurred.

  • text (str) – The label text.

  • label_point (Point) – Initial location for the label text.

  • color (str or tuple, optional) – A matplotlib color. Default is 'black'.

  • bbox (matplotlib.transforms.Bbox or None, optional) – The bounding box of the rendered text. Set after layout.

  • event_point (Point or None, optional) – Where on the grid the event is located.

  • put_circle_around_point (bool, optional) – Whether to draw a circle around the event square. Default is True.

  • marker (Marker or None, optional) – A Marker to draw at the event position.

  • relpos (tuple of float, optional) – The relative position on the label from which the annotation arrow originates. See matplotlib annotation guide. Default is (0.5, 0.5).

  • source_y_range (tuple of (int, int) or None, optional) – The (y_lo, y_hi) row range of the source object (event, era, or era span). Used by Lifegraph to filter annotations outside the visible [min_age, max_age) window. Default is None (always visible).

set_bbox(bbox)[source]

Set the bounding box of the rendered annotation text.

Parameters:

bbox (matplotlib.transforms.Bbox) – The bounding box in data coordinates.

set_relpos(relpos)[source]

Set the arrow origin relative to the label bounding box.

Parameters:

relpos (tuple of float) –

(rx, ry) where each value is in [0, 1]. See the matplotlib annotation guide.

overlaps(that)[source]

Check whether this annotation’s bounding box overlaps another’s.

Two boxes do not overlap when one is entirely to the right of the other, or entirely below the other.

Parameters:

that (Annotation) – The other annotation to test against.

Returns:

True if the bounding boxes overlap.

Return type:

bool

Raises:

ValueError – If that is not an Annotation.

is_within_epsilon_of(that, epsilon)[source]

Check whether two annotations are closer than a tolerance.

Parameters:
  • that (Annotation) – The other annotation.

  • epsilon (float) – Minimum allowed distance between bounding boxes.

Returns:

True if the annotations are within epsilon of each other.

Return type:

bool

Raises:

ValueError – If that is not an Annotation.

get_bbox_overlap(that, epsilon)[source]

Compute the overlap dimensions between two annotation bounding boxes.

Parameters:
  • that (Annotation) – The other annotation.

  • epsilon (float) – Buffer added to the height calculation.

Returns:

(width, height) of the overlap region.

Return type:

tuple of float

Raises:

ValueError – If that is not an Annotation.

get_xy_correction(that, epsilon)[source]

Compute the correction needed to resolve an overlap.

Parameters:
  • that (Annotation) – The other annotation.

  • epsilon (float) – Buffer added to the correction.

Returns:

(dx, dy) correction to apply.

Return type:

tuple of float

Raises:

ValueError – If that is not an Annotation.

update_X_with_correction(correction)[source]

Shift the label in the x direction.

Parameters:

correction (tuple of float) – correction[0] is added to the x position and bounding box.

update_Y_with_correction(correction)[source]

Shift the label in the y direction.

Parameters:

correction (tuple of float) – correction[1] is added to the y position and bounding box.

class lifegraph.core.Era(text, start, end, color, alpha=1)[source]

Bases: object

A highlighted region on the grid representing a period of time.

Eras are drawn as colored rectangles spanning from start to end behind the grid squares.

Parameters:
  • text (str) – Label for the era.

  • start (datetime.date) – Start date of the era.

  • end (datetime.date) – End date of the era.

  • color (str or tuple) – A matplotlib color.

  • alpha (float, optional) – Opacity of the era rectangle. Default is 1.

Examples

>>> from lifegraph import Lifegraph
>>> from datetime import date
>>> g = Lifegraph(date(1990, 1, 1))
>>> g.add_era("College", date(2008, 9, 1), date(2012, 5, 15), color="blue")
class lifegraph.core.EraSpan(text, start, end, color, start_marker=None, end_marker=None)[source]

Bases: Era

A dumbbell-shaped annotation marking a span of time.

Draws circles at the start and end positions connected by a line, with an optional label.

Parameters:
  • text (str) – Label for the era span.

  • start (datetime.date) – Start date.

  • end (datetime.date) – End date.

  • color (str or tuple) – A matplotlib color.

  • start_marker (Marker or None, optional) – Custom marker for the start position.

  • end_marker (Marker or None, optional) – Custom marker for the end position.

Examples

>>> from lifegraph import Lifegraph
>>> from datetime import date
>>> g = Lifegraph(date(1990, 1, 1))
>>> g.add_era_span("Grad school", date(2012, 9, 1), date(2016, 5, 15),
...               color="#4423fe")

Configuration

class lifegraph.configuration.Papersize(value)[source]

Bases: Enum

Supported paper sizes for the life graph figure.

Each member maps to standard paper dimensions (in inches) that determine the default figure size and all proportional styling parameters. ISO A-series sizes range from A0 (33.1 x 46.8 in) to A10 (1.0 x 1.5 in). US sizes include Letter (8.5 x 11 in), Legal, JuniorLegal, HalfLetter, Ledger, and Tabloid. The default for Lifegraph is Papersize.A3.

Examples

>>> from lifegraph import Lifegraph
>>> from lifegraph.configuration import Papersize
>>> from datetime import date
>>> g = Lifegraph(date(1990, 1, 1), size=Papersize.Letter)
A0 = (33.1, 46.8)
A1 = (23.4, 33.1)
A2 = (16.5, 23.4)
A3 = (11.7, 16.5)
A4 = (8.3, 11.7)
A5 = (5.8, 8.3)
A6 = (4.1, 5.8)
A7 = (2.9, 4.1)
A8 = (2.0, 2.9)
A9 = (1.5, 2.0)
A10 = (1.0, 1.5)
HalfLetter = (5.5, 8.5)
Letter = (8.5, 11.0)
Legal = (8.5, 14.0)
JuniorLegal = (5.0, 8.0)
Ledger = (11.0, 17.0)
Tabloid = (17.0, 11.0)
class lifegraph.configuration.LifegraphParams(papersize)[source]

Bases: object

Drawing parameters scaled to a particular paper size.

On construction, two dictionaries are populated:

  • rcParams – values forwarded to matplotlib.pyplot.rcParams.update().

  • otherParams – lifegraph-specific styling knobs (annotation offsets, watermark size, era-span line widths, etc.).

Parameters:

papersize (Papersize) – The paper size to configure for.

rcParams

Matplotlib RC parameter overrides.

Type:

dict

otherParams

Lifegraph-specific styling parameters.

Type:

dict

Examples

>>> from lifegraph.configuration import LifegraphParams, Papersize
>>> params = LifegraphParams(Papersize.A4)
>>> params.rcParams["figure.figsize"]
[8.3, 11.7]

Serialization

lifegraph.serialization.export_config(graph, path, include_styling=False)[source]
lifegraph.serialization.import_config(cls, path, apply_styling=True)[source]

Utilities

lifegraph.utils.random_color()[source]

Return a random color from matplotlib’s named color sets.

Selects a random color from the union of matplotlib.colors.BASE_COLORS and matplotlib.colors.CSS4_COLORS.

Returns:

A color value accepted by matplotlib (e.g. 'red' or (1.0, 0.0, 0.0)).

Return type:

str or tuple

Examples

>>> from lifegraph.utils import random_color
>>> c = random_color()