part of Course 133 Navigating Matplotlib
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.
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.
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.
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.
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.
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.
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.
-
First, you need to make sure that the setting
usetex
is set toTrue
. - Then you need to make sure to use r-strings (string literals) so that python doesn't try to convert escape characters in your string.
- Also, don't forget to enclose your equation in dollar signs ($). That tells LaTeX to enter math mode.
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.