A comprehensive Python library for programmatically creating and compiling LaTeX documents and snippets.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Figure environments, image inclusion, subfigures, and matplotlib integration for scientific and technical documents. PyLaTeX provides comprehensive support for incorporating graphics, from simple image inclusion to complex multi-panel figures and matplotlib plot integration.
The Figure class creates floating figure environments that can be positioned automatically by LaTeX with captions and labels.
class Figure(Float):
def __init__(self, position=None, **kwargs):
"""
Create a floating figure environment.
Parameters:
- position: str, float positioning ('h', 't', 'b', 'p', '!')
- 'h': here (at current position)
- 't': top of page
- 'b': bottom of page
- 'p': separate page
- '!': override LaTeX restrictions
"""
def add_image(self, filename, *, width=NoEscape(r"0.8\textwidth"),
placement=NoEscape(r"\centering")):
"""
Add an image to the figure.
Parameters:
- filename: str, path to image file
- width: str or NoEscape, image width specification
- placement: str or NoEscape, horizontal placement command
"""
def add_plot(self, *args, extension="pdf", **kwargs):
"""
Add current matplotlib plot to figure.
Parameters:
- *args: arguments passed to plt.savefig
- extension: str, image file format ('pdf', 'png', 'eps', 'svg')
- **kwargs: keyword arguments for plt.savefig and image placement
- width: image width in LaTeX
- placement: horizontal placement
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.figure import Figure
doc = Document()
with doc.create(Section('Results')):
# Basic figure with image
with doc.create(Figure(position='htbp')) as fig:
fig.add_image('path/to/image.png',
width=NoEscape(r'0.6\textwidth'))
fig.add_caption('Experimental results showing data trends.')
fig.append(Label('fig:results'))
# Figure with custom sizing
with doc.create(Figure(position='H')) as fig: # Force position with 'H'
fig.add_image('diagram.pdf',
width=NoEscape(r'12cm'))
fig.add_caption('System architecture diagram.')PyLaTeX seamlessly integrates with matplotlib for programmatic figure generation.
import matplotlib.pyplot as plt
import numpy as np
from pylatex import Document, Section
from pylatex.figure import Figure
doc = Document()
# Generate matplotlib plot
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure(figsize=(8, 6))
plt.plot(x, y, 'b-', label='sin(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Sine Wave')
plt.legend()
plt.grid(True)
with doc.create(Section('Analysis')):
with doc.create(Figure(position='htbp')) as fig:
# Add current plot to figure
fig.add_plot(dpi=300, width=NoEscape(r'0.8\textwidth'))
fig.add_caption('Sine wave analysis.')
# Multiple plots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.plot(x, np.sin(x))
ax1.set_title('Sine')
ax2.plot(x, np.cos(x))
ax2.set_title('Cosine')
plt.tight_layout()
with doc.create(Figure()) as fig:
fig.add_plot(bbox_inches='tight')
fig.add_caption('Comparison of sine and cosine functions.')The SubFigure class enables creation of multi-panel figures with individual captions.
class SubFigure(Figure):
def __init__(self, width=NoEscape(r"0.45\linewidth"), **kwargs):
"""
Create a subfigure within a figure environment.
Parameters:
- width: str or NoEscape, subfigure width
- **kwargs: additional arguments passed to Figure
Requires:
- subcaption package (automatically added)
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.figure import Figure, SubFigure
import matplotlib.pyplot as plt
import numpy as np
doc = Document()
with doc.create(Section('Comparative Analysis')):
with doc.create(Figure(position='htbp')) as fig:
# First subplot
with doc.create(SubFigure(width=NoEscape(r'0.45\textwidth'))) as subfig:
x = np.linspace(0, 10, 100)
plt.figure(figsize=(6, 4))
plt.plot(x, np.sin(x), 'r-')
plt.title('Function A')
subfig.add_plot()
subfig.add_caption('Sine wave')
# Add horizontal space
fig.append(NoEscape(r'\hfill'))
# Second subplot
with doc.create(SubFigure(width=NoEscape(r'0.45\textwidth'))) as subfig:
plt.figure(figsize=(6, 4))
plt.plot(x, np.cos(x), 'b-')
plt.title('Function B')
subfig.add_plot()
subfig.add_caption('Cosine wave')
# Overall caption
fig.add_caption('Comparison of trigonometric functions.')
# Three-panel figure
with doc.create(Figure(position='htbp')) as fig:
for i, (func, name, color) in enumerate([(np.sin, 'Sine', 'red'),
(np.cos, 'Cosine', 'blue'),
(np.tan, 'Tangent', 'green')]):
with doc.create(SubFigure(width=NoEscape(r'0.32\textwidth'))) as subfig:
plt.figure(figsize=(4, 3))
x = np.linspace(0, 2*np.pi, 100)
plt.plot(x, func(x), color=color)
plt.title(name)
subfig.add_plot()
subfig.add_caption(f'{name} function')
if i < 2: # Add space between subfigures
fig.append(NoEscape(r'\hfill'))
fig.add_caption('Trigonometric functions comparison.')The StandAloneGraphic class provides direct image inclusion without float environments.
class StandAloneGraphic(UnsafeCommand):
def __init__(self, filename, image_options=NoEscape(r"width=0.8\textwidth"),
extra_arguments=None):
"""
Include graphics directly without figure environment.
Parameters:
- filename: str, path to image file
- image_options: str or NoEscape, includegraphics options
- extra_arguments: additional command arguments
Requires:
- graphicx package (automatically added)
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.figure import StandAloneGraphic
doc = Document()
with doc.create(Section('Gallery')):
doc.append('Here is an inline image: ')
# Direct image inclusion
doc.append(StandAloneGraphic('logo.png',
image_options=NoEscape(r'width=2cm')))
doc.append(' within the text.')
# Centered image without float
doc.append(NoEscape(r'\begin{center}'))
doc.append(StandAloneGraphic('banner.jpg',
image_options=NoEscape(r'width=\textwidth')))
doc.append(NoEscape(r'\end{center}'))from pylatex import Document, Section, NoEscape, Command
from pylatex.figure import Figure, SubFigure
import matplotlib.pyplot as plt
import numpy as np
doc = Document()
with doc.create(Section('Experimental Results')):
with doc.create(Figure(position='htbp')) as fig:
# 2x2 grid of subfigures
data_sets = [
(lambda x: x**2, 'Quadratic', 'red'),
(lambda x: x**3, 'Cubic', 'blue'),
(lambda x: np.exp(x), 'Exponential', 'green'),
(lambda x: np.log(x), 'Logarithmic', 'orange')
]
for i, (func, name, color) in enumerate(data_sets):
width = NoEscape(r'0.48\textwidth')
with doc.create(SubFigure(width=width)) as subfig:
plt.figure(figsize=(5, 4))
x = np.linspace(0.1, 5, 100) if name == 'Logarithmic' else np.linspace(0, 5, 100)
y = func(x)
plt.plot(x, y, color=color, linewidth=2)
plt.title(f'{name} Function')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True, alpha=0.3)
subfig.add_plot(bbox_inches='tight', dpi=300)
subfig.add_caption(f'{name} growth pattern')
# Add spacing and line breaks
if i % 2 == 0: # After first and third subfigures
fig.append(NoEscape(r'\hfill'))
elif i == 1: # After second subfigure
fig.append(NoEscape(r'\\[1em]'))
fig.add_caption('Comparison of different mathematical functions showing various growth patterns.')from pylatex import Document, Command, NoEscape
from pylatex.figure import Figure
doc = Document()
# Add tikz package for annotations
doc.packages.append(Package('tikz'))
doc.packages.append(Package('tikz', options=['remember picture', 'overlay']))
with doc.create(Figure(position='htbp')) as fig:
fig.add_image('schematic.png', width=NoEscape(r'0.8\textwidth'))
# Add tikz overlay for annotations
fig.append(NoEscape(r'\begin{tikzpicture}[remember picture, overlay]'))
fig.append(NoEscape(r'\node[red, font=\Large] at (2, 1) {Input};'))
fig.append(NoEscape(r'\node[blue, font=\Large] at (6, 1) {Output};'))
fig.append(NoEscape(r'\draw[red, thick, ->] (2, 0.5) -- (6, 0.5);'))
fig.append(NoEscape(r'\end{tikzpicture}'))
fig.add_caption('System schematic with flow annotations.')PyLaTeX supports various image formats through LaTeX's graphicx package:
from pylatex import Document, Package
from pylatex.figure import Figure
doc = Document()
# Enable additional graphics support
doc.packages.append(Package('graphicx'))
doc.packages.append(Package('epstopdf')) # Automatic EPS to PDF conversion
with doc.create(Figure()) as fig:
# Vector graphics (recommended for scalability)
fig.add_image('plot.pdf') # PDF graphics
fig.add_image('diagram.eps') # EPS graphics
# Raster graphics
fig.add_image('photo.jpg', width=NoEscape(r'0.5\textwidth'))
fig.add_image('screenshot.png', width=NoEscape(r'10cm'))from pylatex import Document, Command, NoEscape
from pylatex.utils import fix_filename
doc = Document()
# Set graphics path for all images
doc.preamble.append(Command('graphicspath', arguments=NoEscape(r'{{./images/}}')))
# Fix problematic filenames
safe_filename = fix_filename('image with spaces & symbols.jpg')
with doc.create(Figure()) as fig:
fig.add_image(safe_filename)
fig.add_caption('Image with cleaned filename.')from pylatex import Document, Package
from pylatex.figure import Figure
doc = Document()
doc.packages.append(Package('float')) # For 'H' option
# Different positioning strategies
positions = [
('htbp', 'Standard float positioning'),
('H', 'Force exact position (requires float package)'),
('!htbp', 'Override LaTeX restrictions'),
('t', 'Top of page only'),
('b', 'Bottom of page only')
]
for pos, description in positions:
with doc.create(Figure(position=pos)) as fig:
fig.add_image('example.png')
fig.add_caption(f'{description} (position={pos})')from pylatex import Document, NoEscape, Command
from pylatex.figure import Figure
doc = Document()
# Adjust float parameters
doc.preamble.append(Command('setcounter', arguments=['topnumber', '3']))
doc.preamble.append(Command('renewcommand', arguments=[NoEscape(r'\topfraction'), '.75']))
doc.preamble.append(Command('setcounter', arguments=['bottomnumber', '2']))
doc.preamble.append(Command('renewcommand', arguments=[NoEscape(r'\bottomfraction'), '.75']))
with doc.create(Figure()) as fig:
# Custom alignment
fig.append(NoEscape(r'\centering'))
fig.add_image('centered.png')
# Adjust spacing around image
fig.append(NoEscape(r'\vspace{1em}'))
fig.add_caption('Figure with custom spacing.')import matplotlib.pyplot as plt
import numpy as np
from pylatex import Document, Section
from pylatex.figure import Figure
def generate_analysis_plots(data_sets, output_doc):
"""Generate standardized analysis plots."""
with output_doc.create(Section('Data Analysis')) as section:
for i, (data, title) in enumerate(data_sets):
# Create matplotlib figure
plt.figure(figsize=(10, 6))
# Plot data
plt.subplot(1, 2, 1)
plt.plot(data['x'], data['y'], 'bo-')
plt.title(f'{title} - Raw Data')
plt.xlabel('X Values')
plt.ylabel('Y Values')
plt.grid(True)
# Plot analysis
plt.subplot(1, 2, 2)
plt.hist(data['y'], bins=20, alpha=0.7)
plt.title(f'{title} - Distribution')
plt.xlabel('Y Values')
plt.ylabel('Frequency')
plt.tight_layout()
# Add to document
with output_doc.create(Figure(position='htbp')) as fig:
fig.add_plot(dpi=300, bbox_inches='tight')
fig.add_caption(f'Analysis of {title.lower()} dataset.')
# Usage
doc = Document()
datasets = [
({'x': np.linspace(0, 10, 50), 'y': np.random.normal(0, 1, 50)}, 'Dataset A'),
({'x': np.linspace(0, 10, 50), 'y': np.random.exponential(2, 50)}, 'Dataset B')
]
generate_analysis_plots(datasets, doc)Figure-related functionality requires specific LaTeX packages:
graphicx package (automatically added)subcaption package (automatically added with SubFigure)float package (for 'H' option)epstopdf package for automatic conversionfrom pylatex import Document, Package
doc = Document()
# Common figure packages
doc.packages.append(Package('graphicx'))
doc.packages.append(Package('float'))
doc.packages.append(Package('subcaption'))
doc.packages.append(Package('caption', options=['font=small', 'labelfont=bf']))The figure system in PyLaTeX provides professional-quality image handling with seamless integration between programmatic plot generation and LaTeX document composition.
Install with Tessl CLI
npx tessl i tessl/pypi-pylatex