Professional Matplotlib Figures for LaTeX
🔠 Font
Font Style
To ensure that the fonts in matplotlib figures exactly match those in the LaTeX document, the best practice is to use LaTeX for font rendering. This guarantees 100% font consistency.
-
Install TeX Live on your system (
brew install texliveon macOS,apt install texlive-fullon Debian or Ubuntu; for Windows, see this guide ). After installation, make sure the pdflatex executable is available in your PATH. -
Use
LaTeXfor font rendering:
import matplotlib.pyplot as plt
plt.rcParams.update({
"text.usetex": True,
"font.family": "Computer Modern",
})
Font size
Using a font size consistent with the main LaTeX document is essential for a professional appearance. Although this is conceptually simple, many people struggle to adjust the font sizes of elements such as legends, tick labels, and figure titles.
The key point is that font size is relative to the figure size. If a figure is created at an overly large size, the text will appear small once the figure is inserted into the document, even if large font values are used.
Therefore, the first and most important step in font-size control is to set the figure size correctly. The guiding principle is straightforward: make the figure width identical to its final width in the document.
As illustrated in the figure below, for a single-column figure in an IEEE double-column layout, the column width is approximately 3.5 inches. Simply set the figure width to 3.5 inches, and the font sizes will naturally align with the LaTeX document without further tuning.

Column width in a double-column IEEE format is approximately 3.5 inches.
- Set the figure width to match the witdh of the figure in the document. In a double-column IEEE-style layout, the column width is typically 3.5 inches. Therefore, for a single-column figure, set the figure width to 3.5 inches.
fig = plt.figure(figsize=(3.5, 3.5))
- Set the font size to the default
import matplotlib as mpl
mpl.rcParams.update({
"font.size": 10,
"axes.labelsize": 10,
"axes.titlesize": 10,
"figure.titlesize": 10,
"legend.fontsize": 9,
"xtick.labelsize": 9,
"ytick.labelsize": 9,
})
That’s it—the text in the figure will now be consistent with the main document.
📊 Precise Control of Matplotlib Legends
Legend is an essential component of a Matplotlib axis, used to identify and differentiate various elements within a plot.
A legend is generated by ax.legend() or plt.legend() function.
This section demonstrates several arguments for these functions
that allow precise control over the legend's appearance.
Legend Location: loc
Use legend(loc=) to specify the location of the legend.
Can be either accurate coordinates or string.
For example: ax.legend(loc=(0, 0.5)) or ax.legend("upper left").
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(i/3, i/3))
plt.tight_layout()
Legend at different locations.
Font size: fontsize
Use legend(fontsize=) to specify the font size.
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), fontsize=8+i*3)
plt.tight_layout()
Legend with various font sizes.
Number of Columns: ncol
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=i+1)
plt.tight_layout()
Legends of different columns.
Row spacing: labelspacing
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, labelspacing=2*i)
plt.tight_layout()
Adjust the spacing between columns.
Column Spacing: columnspacing
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, columnspacing=2*i)
plt.tight_layout()
Adjust the spacing between columns.
Handle Length: handlelength
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, handlelength=i+1)
plt.tight_layout()
Adjust handle length.
Space Between Handle and Text: handletextpad
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for i, ax in enumerate(axes):
ax.set_ylim(-2, 1.1)
for y in ys:
axes[i].plot(x, y)
axes[i].legend([f"i={i}" for i in range(5)], loc=(0, 0), ncol=2, handletextpad=i)
plt.tight_layout()
Space between handle and text.