2. Text Visualizations

One of Multiplex’s biggest additions to matplotlib is the text visualizations. These visualizations embody Multiplex’s principles: Multiplex structures the data, and you style it.

All text visualizations or annotations you see in Multiplex are based on the Annotation class. This class isn’t quite a visualization on its own, but it is the engine that lays out the text for you.

The Annotation class is only concerned with the layout of the visualiation. That means that you get to keep all the flexibility to style the text. For example, the below visualization, created using the TextAnnotation class, highlights only the named entities:

_images/2-text-annotation.png

Note

Eager to start creating text visualizations? Multiplex’s Jupyter Notebook examples are a quick guide to get you up and running. Check out the text visualizations Jupyter Notebook to learn how to create the above visualization, or to start creating your own text visualizations.

Annotations

An Annotation is a text-only description that is added to visualizations. The Annotation class is not quite a visualization, but it’s one of Multiplex’s most important classes. It is a tool to help you tell your story.

For example, any visualization based on the LabelledVisualization class can draw labels—text annotations—anywhere on the plot. You can also use it on any normal matplotlib plot as long as you wrap it around a Drawable. All you have to do is create a Drawable and call the annotate() function.

import matplotlib.pyplot as plt
from multiplex import drawable
viz = drawable.Drawable(plt.figure(figsize=(10, 10)))
lines = viz.annotate('Hello world!', (0, 2), 0)

Annotations can be as simple as providing a string of text, the x-position, and the y-position, as in the example above. However, you can also create more complex annotations. You can even style each word individually!

The Annotation is most important for the TextAnnotation class. TextAnnotation visualizations are made up only of text and revolve around the Annotation class. It also adds some extra functionality to annotations, such as by drawing legends.

Look over the Annotation class to learn more about what kind of annotations you can create. If you want to create text-only visualizations, skip ahead to the TextAnnotation class.

class text.annotation.Annotation(drawable, annotation, x, y, wordspacing=None, lineheight=1.25, align='left', va='top', pad=0, *args, **kwargs)

Although the Annotation is not a visualization, it is also based on a Drawable. Moreover, like any Visualization, it also revolves around the draw() method.

Apart from the Drawable, the Annotation keeps track of the text it has drawn in the lines instance variable. The name of this variable comes from the fact that the Annotation is mainly concerned with organizing the text. The annotation draws every bit of the text as a token and organizes these tokens into lines.

In addition to the drawn tokens, the annotation stores the original annotation, position and style. This information is used when the annotation is re-drawn.

Variables:
  • drawable (Drawable) – The Drawable where the time series visualization will be drawn.
  • lines (list of list of matplotlib.text.Text) – The lines drawn by the annotation. Each line in turn is made up of a list of tokens as matplotlib.text.Text.
  • annotation (str or list of str or list of dict) – The original annotation.
  • x (tuple) – A tuple representing the x-range for the annotation.
  • y – The y-position of the annotation.
  • style (dict) – The general style of the annotation.
Vartype:

float

__init__(drawable, annotation, x, y, wordspacing=None, lineheight=1.25, align='left', va='top', pad=0, *args, **kwargs)

Initialize the Annotation with the Drawable. The Annotation uses the Drawable’s figure to get the renderer and the axes to draw the text. The constructor also creates an instance variable with the lines in the Annotation.

In addition to the Drawable, the class requires three types of inputs:

  1. The text to draw,
  2. The x-bounds for the annotation, and
  3. The y-position of the annotation.

You can use the rest of the defined keyword arguments to style the annotation as a whole. For example, the align option aligns the entire annotation. Conversely, you can use the keyword arguments (kwargs) to style each individual word. The accepted styling options are those supported by the matplotlib.text.Text class.

You can provide the text either as a string or as a dictionary. If you provide a string, the function automatically segments it into words. Dictionaries should have the following format:

{
  'text': 'token',
  'style': { 'facecolor': 'None' }
}

Of these keys, only the text is required.

You can use the style to override the general styling options, which you can specify as kwargs. Once again, the accepted styling options are those supported by the matplotlib.text.Text class.

Use the kwargs as a general style, and the dictionary’s style as a specific style for each word. If you specify a kwargs styling option, but it is missing from the dictionary’s style, the general style is used.

Note

For example, imagine you specify the text color to be blue and the fontsize to be 12 in the **kwargs. If in the dictionary’s style of a particular word you set the color to be red, its color will be red. However, since the fontsize is not specified, it will use the general font size: 12.

Parameters:
  • drawable (Drawable) – The Drawable where the text visualization will be drawn.
  • annotation (str or list of str or list of dict) – The text data. The visualization expects a string, a list of tokens, or a list of dict instances as shown above.
  • x (float or tuple) – The x-position of the annotation. The function expects either a float or a tuple. If a float is given, the annotation starts at that x-position and ends at the axes’ limit. If a tuple is given, the annotation starts at the first value and ends at the second value.
  • y (float) – The starting y-position of the annotation.
  • wordspacing (float or None) – The space between words. If None is given, the space is calculated based on the height of the line.
  • lineheight (float) – The space between lines.
  • align (str) –

    The text’s alignment. Possible values:

    • left
    • center
    • right
    • justify
    • justify-start (or justify-left)
    • justify-center
    • justify-end or (justify-right)
  • va (str) –

    The vertical alignment, can be one of:

    • top: the annotation grows down from the y position.
    • center: the annotation is centered around the given y position.
    • bottom: the annotation grows up from the y position.
  • pad (float) –

    The amount of padding applied to the annotation along the x-axis. The padding is applied to all sides of the annotation and reduces its size.

    Note

    Note that the padding decreases the width of the annotation. In CSS terms, the box-sizing is the border box.

draw(*args, **kwargs)

Draw a text annotation on the plot.

Returns:The drawn annotation’s lines. Each line is made up of a list of tokens.
Return type:list of matplotlib.text.Text
get_virtual_bb(transform=None)

Get the bounding box of the entire Annotation. This is called a virtual bounding box because it is not a real bounding box. Rather, it is the smallest rectangular bounding box that covers all of the bounding boxes of the Annotation’s tokens.

Parameters:transform (None or matplotlib.transforms.TransformNode) – The bounding box transformation. If None is given, the data transformation is used.
Returns:The bounding box of the annotation.
Return type:matplotlib.transforms.Bbox
set_position(position, ha='left', va='top', transform=None, *args, **kwargs)

Move the annotation to the given position. This function moves all of the tokens stored in the lines instance variable to its new position.

Warning

The vertical alignment should be the same as the vertical alignment when the annotation was created.

Parameters:
  • position (tuple) – A tuple made up of the new x and y coordinates.
  • ha (str) –

    The horizontal alignment, can be one of:

    • left: the given x-coordinate becomes the leftmost point of the annotation.
    • center: the given x-coordinate becomes the center point of the annotation.
    • right: the given x-coordinate becomes the rightmost point of the annotation.
  • va (str) –

    The vertical alignment, can be one of:

    • top: the given y-coordinate becomes the highest point of the annotation.
    • center: the given y-coordinate becomes the center point of the annotation.
    • bottom: the given y-coordinate becomes the lowest point of the annotation.
  • transform (None or matplotlib.transforms.TransformNode) – The bounding box transformation. If None is given, the data transformation is used.
Raises:
  • ValueError – When the given horizontal alignment is not supported.
  • ValueError – When the given vertical alignment is not supported.
redraw()

Re-draw the annotation. This function re-constructs the entire annotation from scratch.

This function should be called if the axes change as the text tokens could end up overlapping.

Returns:The drawn annotation’s lines. Each line is made up of a list of tokens.
Return type:list of matplotlib.text.Text
remove()

Remove all tokens in the annotation from the visualization. This function removes all of the Annotation’s text from the plot and then empties the lines.

__repr__()

Get the annotation as text. The representation is the concatenated text.

Returns:The text representation of the annotation, made up of the annotation text.
Return type:str

Text Visualizations

The TextAnnotation builds on the Annotation, but is a full-fledged visualization. That means the TextAnnotation makes it easier to create a visualization and adds other functionality, such as a legend.

As with the Annotation, the TextAnnotation takes care of laying out the text for you. All you have to do is specify the text to visualize and its style.

To start creating text visualizations, create a Drawable class and call the draw_text_annotation() function. This method expects, at the very least, a string of text, but you can also pass on other styling options:

import matplotlib.pyplot as plt
from multiplex import drawable
viz = drawable.Drawable(plt.figure(figsize=(10, 10)))
text = 'Hello world!'
viz.draw_text_annotation(text, align='justify',
                         fontfamily='serif', alpha=0.9,
                         lineheight=1.25, lpad=0.1, rpad=0.1)
viz.show()

You can even use the TextAnnotation for more complex visualizations. For example, instead of a string, you can segment your text into words yourself and style them individually.

Note

You can view more complex text visualization examples in the Jupyter Notebook tutorial.

class text.text.TextAnnotation(drawable, *args, **kwargs)

The TextAnnotation is mainly concerned with organizing text. Like all visualizations, it stores a Drawable instance and revolves around the draw() function.

The main difference from the Annotation is that the draw() function does not require the x and y positions. Instead, this class assumes that the visualization is made up only of text.

Moreover, the TextAnnotation adds support for a legend. The legend is added when tokens have a label key. Therefore the TextAnnotation may only create a legend when tokens are provided as dict instances.

draw(annotation, wordspacing=0.005, lineheight=1.25, align='left', with_legend=True, lpad=0, rpad=0, tpad=0, *args, **kwargs)

Draw the text annotation visualization.

The method expects, at least, the text annotation. You can pass on the text as a string, or segment the text into tokens yourself and pass them on as a list.

You can also split the text into words and pass them on as dict instances to style them individually. Dictionaries should have the following format:

{
  'text': 'token',
  'style': { 'facecolor': 'None' },
  'label': None
}

Of these keys, only the text is required.

You can use the style to override the general styling options, which you can specify as kwargs. Once again, the accepted styling options are those supported by the matplotlib.text.Text class.

Use the kwargs as a general style, and the dictionary’s style as a specific style for each word. If you specify a kwargs styling option, but it is missing from the dictionary’s style, the general style is used.

Note

For example, imagine you specify the text color to be blue and the fontsize to be 12 in the **kwargs. If in the dictionary’s style of a particular word you set the color to be red, its color will be red. However, since the fontsize is not specified, it will use the general font size: 12.

The last key is the label. If you set a label, Multiplex automatically creates a legend for you.

Parameters:
  • annotation (str or list of str or list of dict) – The text annotation. The visualization expects a string, a list of tokens, or a list of dict instances as shown above.
  • wordspacing (float) – The space between words.
  • lineheight (float) – The space between lines.
  • align (str) –

    The text’s alignment. Possible values:

    • left
    • center
    • right
    • justify
    • justify-start (or justify-left)
    • justify-center
    • justify-end or (justify-right)
  • with_legend (bool) – A boolean indicating whether the visualization should create a legend when it finds labels.
  • lpad (float) – The left padding as a fraction of the plot. The range is expected to be between 0 and 1.
  • rpad (float) – The right padding as a fraction of the plot. The range is expected to be between 0 and 1.
  • tpad (float) – The top padding as a percentage of the plot.
Returns:

The drawn lines. Each line is made up of tuples, and each tuple is made up of:

  1. The list of legend labels in the line, and
  2. The list of tokens drawn in the line.

Return type:

list of tuple

Raises:
  • ValueError – When the left padding is not between 0 and 1.
  • ValueError – When the right padding is not between 0 and 1.
  • ValueError – When the left padding and the right padding combined are larger than 1.