part of Course 133 Navigating Matplotlib


x-axis label, y-axis label, and title
ax.set_xlabel("The x-axis label")
ax.set_ylabel("The y-axis label")
ax.set_title("The Title")
some text on a plot
ax.text(x_text, y_text, "Some text")
text alignment examples
ax.text(x_text, y_text, "plot text",
        horizontalalignment="left",
        verticalalignment="top")
a variety of text styles
ax.text(x_text, y_text,
        "fontsize=20", fontsize=20)
text in a bounding box
ax.text(x_text, y_text, "Text in a box",
        bbox=dict(boxstyle = "square",
                  facecolor = "white"))
a variety of annotation styles
ax.annotate(
    "an annotation note",
    (x_point, y_point),
    (x_text, y_text),
    arrowprops=dict(arrowstyle = "-|>"))
a LaTeX equation
matplotlib.rcParams['text.usetex'] = True
ax.text(0, 0, r"$E = mc^2$")

Text is one of the trickiest things to get right on a plot because there are so many options and permutations. Anyone who's honest will tell you that they Google the syntax every time when doing Matplotlib text formatting. I can't change that, but I at least want to give you a one-stop shop for your searches.

By the way, if you're looking for how to customize axis tick labels, there's an entire lesson dedicated to that here.

First we set the stage for our examples. For an explanation of any part of this, look here.

import matplotlib
matplotlib.use("agg")
import matplotlib.pyplot as plt
import numpy as np

# Create the curve data.
x = np.linspace(-6, 6, 500)
y = np.sinc(x)
fig = plt.figure()
ax = fig.gca()
ax.plot(x, y)

Add axis labels and a title

The most popular text to add is axis labels and a plot title. The calls for doing this are fairly intuitive. (Much more so than some we'll see further down the page.)

ax.set_xlabel("The x-axis label")
ax.set_ylabel("The y-axis label")
ax.set_title("The Title")

The text these commands create is of a generic style, but don't worry. Keep reading, and you'll get a chance later to customize the heck out it. x-axis label, y-axis label, and title

Put any text anywhere

You're not limited to axis labels and a title. You can add any text you want to any location on the plot.

ax.text(-5, .8, "Some text")

The incantation of text(x, y, "some text") lets you arbitrarily place your note anywhere in the plot, using plot coordinates.

some text on a plot

Fine-tune text placement

You may have noticed that choosing an x and a y for the text position is a little ambiguous. Are you choosing the location for the bottom of the text or the top? For the left or the right? Your system will have default answers to these questions in place, but sometimes you'll want more control.

ax.text(-1, -1, "right-top",
        horizontalalignment="right",
        verticalalignment="top")

The horizontalalignment argument lets you specify whether the x position you feed it should be fall just to the right of the text, to the left, or in the center.

As you probably guessed, the verticalalignment argument lets you specify where the y position you supply should fall: at the top of the text, at the bottom, or in the center. There is also a baseline option, the position of the bottoms of most of the letters except for things with tails like y, g, p, and q.

text alignment examples

Customize your text style

Now that we have our text precisely located, we can go wild on the formatting. Size, font, style, color - it's a free-for-all.

ax.text(-1, 1, 'fontsize=16', fontsize=16)
ax.text(-1, 0, 'fontstyle="italic"', fontstyle="italic")
ax.text(-1, -1, 'fontweight="bold"', fontweight="bold")
ax.text(1, -1, "rotation=15", rotation=15)
ax.text(1, 0, 'color="red"', color="red")
ax.text(1, 1, 'family="serif"', family="serif")

If this still doesn't satisfy your textual creativity, take a look at the full list of text properties in the Matplotlib API.

a variety of text styles

Keep in mind, as with most of the text modifications here, you can apply these to axis labels and titles too.

Put your text in a box

Occasionally it's helpful to draw a box around some text.

ax.text(2, .4, "Text in a box",
        bbox=dict(boxstyle = "square",
                  facecolor = "white"))

Doing this requires a bit more complex incantation. text() accepts a bbox argument, which takes a dictionary of keywords that describe the bounding box. A square boxstyle is a good place to start. It comes colorful by default, but if you specify a white box facecolor, it will blend in nicely.

If on the other hand you'd like to explore the limits of what's possible in bounding boxes, take a look at the fancy gallery in Matplotlib. You won't be disappointed.

text in a bounding box

Point your text at something

A powerful way to turn a picture into a story is with annotation, bits of text pointing to something in a plot. Annotation can be used to call out surprising features, label separate curves, add auxiliiary information, or explain the significance of a wiggle.

Returning to our sinc() example, we can show annotations pointing to various aspects of the curve.

ax.annotate(
    "Some annotation text",
    (x_point, y_point),
    (x_text, y_text),
    arrowprops=dict(arrowstyle = "-|>"))

The pattern for calling out an annotation has several parts, and they're all mixed up from what we've seen before. Now the first argument to annotate() is the text. Then a Tuple of the x- and y-positions for the end of the pointer line. And only then, a Tuple of the x- and y-positions of the text. And note the use of Tuples here, where text() accepts x and y as separate arguments.

And after getting through all that, specifying the arrow has it's own quirky syntax. The arrowprops argument takes a dictionary of arrow properties. arrowstyle is the most important one to call out. Here, -|> denotes a line with a triangular arrow head at the non-text end. There are several others (take a close look at the example plot) and even the ability to draw your own custom arrow designs. Visit the fancy gallery to get a sense of the choices on tap.

a variety of annotation styles

For a deeper dig into everything that's possible with annotations, take a look through the API for annotate().

Make beautiful equations

If you really want to communicate precisely, or just make yourself look smart, there's nothing quite like a complex equation. And nothing takes the wind out of an equation's sails like terrible typesetting.

Luckily for all of us, Donald Knuth became obsessed with this, and Leslie Lamport jumped in too, and between them they solved the problem. If you happen to have LaTeX on your computer, you can use it to typeset your equations right in your plots. Your symbols will be crisp. Your placements will be correct. Your equations will be legible and, even when unitelligible, aesthetically pleasing.

matplotlib.rcParams['text.usetex'] = True
ax.text(
    0, 0,
    r"$f(x | \mu, \sigma^2) = \frac{1}{\sqrt{2\pi\sigma^2}}" +
    r"e^{- \frac{(x - \mu)^2}{2\sigma^2}}$")

There are a couple little tricks to getting this working.

a LaTeX equation

You can drop these attractive expressions anywhere you put text - in axis labels and titles and in annotations. If you'd like a full tour of the wild things you can do with LaTeX in plots, check out this demo page.


Now you are off to the races! My sincere hope is that this little reference page takes 90% of the Google goose chase out of getting your plot text just right. If you want to explore the other plot magic you can do, come take a look at the full set of tutorials.