LaTeX-Quality Matplotlib Figures
Overview
We recommend using this latexification tool to make matplotlib figures publication-ready. It helps in the following aspects:
- Consistent Typography: Matches your paper’s LaTeX font and styling
- Proper Sizing: Ensures figures fit perfectly in single or double-column layouts
- Clean Aesthetics: Removes unnecessary chart junk and applies academic styling
- High DPI Output: Generates crisp, scalable figures for publications
- LaTeX Math Rendering: Properly renders mathematical expressions using LaTeX
Enhanced Latexify Tool
Here’s our modern, enhanced version of the latexification tool:
import matplotlib.pyplot as plt
import matplotlib
from math import sqrt
import numpy as np
# Color palette for publication-quality plots
= {
COLORS 'primary': '#2E86AB',
'secondary': '#A23B72',
'accent': '#F18F01',
'success': '#C73E1D',
'neutral': '#6B7280',
'spine': '#9CA3AF'
}
def latexify(fig_width=None, fig_height=None, columns=1, font_size=10,
=True, style='modern'):
use_tex"""
Set up matplotlib's RC params for LaTeX plotting.
Parameters
----------
fig_width : float, optional, inches
Width of the figure. Defaults to optimal width for column layout.
fig_height : float, optional, inches
Height of the figure. Defaults to golden ratio of width.
columns : {1, 2}
Number of columns in your document layout.
font_size : int, default 10
Base font size for the plot.
use_tex : bool, default True
Whether to use LaTeX for text rendering.
style : str, default 'modern'
Style preset: 'modern', 'classic', or 'minimal'.
Returns
-------
tuple
(fig_width, fig_height) for use in plt.figure()
"""
assert columns in [1, 2], "Columns must be 1 or 2"
# Set figure width based on common academic paper layouts
if fig_width is None:
= 3.5 if columns == 1 else 7.0 # IEEE single/double column
fig_width
if fig_height is None:
= (sqrt(5) - 1.0) / 2.0
golden_ratio = fig_width * golden_ratio
fig_height
# Ensure reasonable height limits
= 8.0
max_height if fig_height > max_height:
print(f"WARNING: fig_height {fig_height:.1f} too large, "
f"reducing to {max_height} inches.")
= max_height
fig_height
# LaTeX preamble for better math and symbol support
= [
latex_preamble r'\usepackage{amsmath}',
r'\usepackage{amssymb}',
r'\usepackage{gensymb}',
r'\usepackage{siunitx}'
]
# Base configuration
= {
params 'figure.figsize': [fig_width, fig_height],
'figure.dpi': 150,
'savefig.dpi': 300,
'font.size': font_size,
'axes.labelsize': font_size,
'axes.titlesize': font_size + 1,
'legend.fontsize': font_size - 1,
'xtick.labelsize': font_size - 1,
'ytick.labelsize': font_size - 1,
'axes.linewidth': 0.8,
'grid.linewidth': 0.5,
'lines.linewidth': 1.5,
'patch.linewidth': 0.5,
'xtick.major.width': 0.8,
'ytick.major.width': 0.8,
'xtick.minor.width': 0.4,
'ytick.minor.width': 0.4,
}
# Style-specific configurations
if style == 'modern':
params.update({'axes.spines.top': False,
'axes.spines.right': False,
'axes.spines.left': True,
'axes.spines.bottom': True,
'axes.edgecolor': COLORS['spine'],
'xtick.color': COLORS['spine'],
'ytick.color': COLORS['spine'],
'axes.labelcolor': 'black',
'grid.alpha': 0.3,
})elif style == 'minimal':
params.update({'axes.spines.top': False,
'axes.spines.right': False,
'axes.spines.left': False,
'axes.spines.bottom': False,
'xtick.bottom': True,
'ytick.left': True,
'grid.alpha': 0.2,
})
# LaTeX configuration
if use_tex:
params.update({'text.usetex': True,
'text.latex.preamble': latex_preamble,
'font.family': 'serif',
'mathtext.fontset': 'custom',
})else:
params.update({'font.family': 'DejaVu Serif',
'mathtext.fontset': 'dejavuserif',
})
matplotlib.rcParams.update(params)return fig_width, fig_height
def format_axes(ax, grid=True, minor_ticks=True):
"""
Apply consistent formatting to matplotlib axes.
Parameters
----------
ax : matplotlib.axes.Axes
The axes to format.
grid : bool, default True
Whether to show grid lines.
minor_ticks : bool, default True
Whether to show minor tick marks.
"""
# Remove top and right spines for cleaner look
'top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines[
# Style remaining spines
for spine in ['left', 'bottom']:
'spine'])
ax.spines[spine].set_color(COLORS[0.8)
ax.spines[spine].set_linewidth(
# Configure grid
if grid:
True, alpha=0.3, linewidth=0.5)
ax.grid(True)
ax.set_axisbelow(
# Add minor ticks for better precision
if minor_ticks:
ax.minorticks_on()='minor', alpha=0.5)
ax.tick_params(which
# Improve tick formatting
=COLORS['spine'], which='both')
ax.tick_params(colors
def save_figure(filename, bbox_inches='tight', pad_inches=0.1,
format='pdf', transparent=False):
"""
Save figure with publication-quality settings.
Parameters
----------
filename : str
Output filename (without extension).
bbox_inches : str, default 'tight'
Bounding box setting for saving.
pad_inches : float, default 0.1
Padding around the figure.
format : str, default 'pdf'
Output format ('pdf', 'png', 'svg', 'eps').
transparent : bool, default False
Whether to save with transparent background.
"""
f"{filename}.{format}",
plt.savefig(=bbox_inches,
bbox_inches=pad_inches,
pad_inchesformat=format,
=transparent,
transparent=300 if format == 'png' else None)
dpiprint(f"Figure saved as {filename}.{format}")
# Color palette for consistent plotting
def get_color_palette(n_colors=5):
"""Get a publication-quality color palette."""
= [COLORS['primary'], COLORS['secondary'],
base_colors 'accent'], COLORS['success'], COLORS['neutral']]
COLORS[return base_colors[:n_colors]
Usage Examples
Basic Usage
import matplotlib.pyplot as plt
import numpy as np
# Set up LaTeX formatting
= latexify(columns=1, font_size=10)
fig_width, fig_height
# Create sample data
= np.linspace(0, 10, 100)
x = np.sin(x)
y1 = np.cos(x)
y2
# Create figure
= plt.subplots(figsize=(fig_width, fig_height))
fig, ax
# Plot data with publication colors
= get_color_palette(2)
colors =colors[0], label=r'$\sin(x)$')
ax.plot(x, y1, color=colors[1], label=r'$\cos(x)$', linestyle='--')
ax.plot(x, y2, color
# Format axes
format_axes(ax)
# Add labels with LaTeX math
r'Time $t$ [\si{\second}]')
ax.set_xlabel(r'Amplitude $A$ [\si{\volt}]')
ax.set_ylabel(r'Trigonometric Functions')
ax.set_title(
ax.legend()
# Save with high quality
'trigonometric_functions', format='pdf')
save_figure( plt.show()
Advanced Example with Subplots
# Set up for double-column figure
= latexify(columns=2, font_size=9, style='modern')
fig_width, fig_height
# Create data
= np.linspace(0, 4*np.pi, 200)
x = [1, 2, 3, 4]
frequencies = get_color_palette(4)
colors
# Create subplots
= plt.subplots(2, 2, figsize=(fig_width, fig_height))
fig, axes = axes.flatten()
axes
for i, freq in enumerate(frequencies):
= np.sin(freq * x) * np.exp(-x/10)
y
=colors[i], linewidth=1.5)
axes[i].plot(x, y, colorrf'$f = {freq}$ Hz')
axes[i].set_title(r'Time $t$ [\si{\second}]')
axes[i].set_xlabel(r'$A(t)$')
axes[i].set_ylabel(
# Format each subplot
=True)
format_axes(axes[i], grid
plt.tight_layout()'damped_oscillations', format='pdf')
save_figure( plt.show()
Customizing for Different Journals
# IEEE style (single column)
def ieee_style():
return latexify(fig_width=3.5, columns=1, font_size=8, style='modern')
# Nature style (double column)
def nature_style():
return latexify(fig_width=7.0, columns=2, font_size=7, style='minimal')
# Custom style for presentations
def presentation_style():
return latexify(fig_width=6.0, font_size=14, style='modern', use_tex=False)
Best Practices
Call
latexify()
before creating figures: This ensures all subsequent plots use the correct styling.Use LaTeX math notation: Write math expressions like
r'$\alpha + \beta^2$'
for proper rendering.Consistent color scheme: Use
get_color_palette()
for publication-quality colors.Save in vector format: Use PDF or SVG for scalable figures in publications.
Match journal requirements: Check specific width and font size requirements for your target journal.
Test without LaTeX: If you encounter LaTeX errors, set
use_tex=False
for faster iteration.
Troubleshooting
Common LaTeX Issues
If you encounter LaTeX errors:
# Quick fix: disable LaTeX temporarily
=False)
latexify(use_tex
# Or install required LaTeX packages
# On Ubuntu/Debian: sudo apt-get install texlive-latex-extra
# On macOS: brew install --cask mactex
Font Issues
# List available fonts
import matplotlib.font_manager as fm
print([f.name for f in fm.fontManager.ttflist])
# Use system fonts if LaTeX unavailable
=False)
latexify(use_tex'font.family'] = 'Times New Roman' # or other serif font plt.rcParams[
This tool ensures your figures meet the highest publication standards while maintaining consistency across your research output.