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
Advanced graphics creation with TikZ including geometric shapes, plots, coordinate systems, and complex diagrams. PyLaTeX provides comprehensive support for TikZ and PGFPlots, enabling programmatic generation of professional-quality vector graphics, technical diagrams, and data visualizations.
The TikZ class creates the basic environment for vector graphics with support for geometric shapes, paths, and annotations.
class TikZ(Environment):
"""
Basic TikZ picture environment for vector graphics.
Requires:
- tikz package (automatically added)
"""
def __init__(self, options=None, *, data=None):
"""
Create a TikZ picture environment.
Parameters:
- options: str, list, or TikZOptions, TikZ picture options
- data: initial graphics content
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ
doc = Document()
with doc.create(Section('Basic Graphics')):
# Simple TikZ drawing
with doc.create(TikZ()) as tikz:
tikz.append(NoEscape(r'\draw (0,0) -- (2,0) -- (1,1) -- cycle;'))
tikz.append(NoEscape(r'\fill[red] (0.5,0.5) circle (0.1);'))
# TikZ with options
tikz_options = ['scale=2', 'transform shape']
with doc.create(TikZ(options=tikz_options)) as tikz:
tikz.append(NoEscape(r'\draw[blue, thick] (0,0) rectangle (2,1);'))
tikz.append(NoEscape(r'\node at (1,0.5) {Scaled Rectangle};'))The TikZCoordinate class provides precise coordinate handling with support for relative and absolute positioning.
class TikZCoordinate(LatexObject):
def __init__(self, x, y, relative=False):
"""
Create a TikZ coordinate.
Parameters:
- x: float or int, X coordinate
- y: float or int, Y coordinate
- relative: bool, whether coordinate is relative (++) or absolute
"""
@classmethod
def from_str(cls, coordinate):
"""
Create coordinate from string representation.
Parameters:
- coordinate: str, coordinate string like '(1,2)' or '++(1,2)'
"""
def distance_to(self, other):
"""
Calculate distance to another coordinate.
Parameters:
- other: TikZCoordinate, target coordinate
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ, TikZCoordinate
doc = Document()
with doc.create(Section('Coordinate Examples')):
with doc.create(TikZ()) as tikz:
# Define coordinates
start = TikZCoordinate(0, 0)
end = TikZCoordinate(3, 2)
relative_point = TikZCoordinate(1, 1, relative=True)
# Use coordinates in drawing commands
tikz.append(NoEscape(f r'\draw {start} -- {end};'))
tikz.append(NoEscape(f r'\draw {end} -- {relative_point};'))
# Calculate and use distances
distance = start.distance_to(end)
tikz.append(NoEscape(f r'\node at (1.5, 2.5) {{Distance: {distance:.2f}}};'))
# Coordinate arithmetic
with doc.create(Section('Coordinate Calculations')):
with doc.create(TikZ()) as tikz:
p1 = TikZCoordinate(1, 1)
p2 = TikZCoordinate(2, 1)
p3 = p1 + p2 # Addition
tikz.append(NoEscape(f r'\fill[red] {p1} circle (0.05);'))
tikz.append(NoEscape(f r'\fill[blue] {p2} circle (0.05);'))
tikz.append(NoEscape(f r'\fill[green] {p3} circle (0.05);'))Core TikZ drawing primitives for creating geometric shapes and paths.
class TikZNode(Command):
def __init__(self, text=None, options=None, at=None):
"""
Create a TikZ node.
Parameters:
- text: str, node content
- options: str or TikZOptions, node formatting options
- at: TikZCoordinate or str, node position
"""
class TikZDraw(Command):
def __init__(self, path, options=None):
"""
Create a TikZ draw command.
Parameters:
- path: str, drawing path specification
- options: str or TikZOptions, drawing options (color, line style, etc.)
"""
class TikZPath(Command):
def __init__(self, path, options=None):
"""
Create a TikZ path command.
Parameters:
- path: str, path specification
- options: str or TikZOptions, path options
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ, TikZNode, TikZDraw, TikZCoordinate
doc = Document()
with doc.create(Section('TikZ Drawing Commands')):
with doc.create(TikZ()) as tikz:
# Draw geometric shapes
tikz.append(TikZDraw(r'(0,0) rectangle (3,2)', options='fill=lightblue'))
tikz.append(TikZDraw(r'(4,0) circle (1)', options='fill=red, opacity=0.5'))
tikz.append(TikZDraw(r'(0,3) -- (3,4) -- (2,5) -- cycle',
options='fill=green, draw=black, thick'))
# Add nodes with labels
tikz.append(TikZNode('Rectangle', at=TikZCoordinate(1.5, 1)))
tikz.append(TikZNode('Circle', at=TikZCoordinate(4, 0)))
tikz.append(TikZNode('Triangle', at=TikZCoordinate(1.5, 4)))
# Complex path example
with doc.create(Section('Complex Paths')):
with doc.create(TikZ()) as tikz:
# Bezier curves
tikz.append(NoEscape(
r'\draw[thick, blue] (0,0) .. controls (1,2) and (3,2) .. (4,0);'
))
# Decorative paths
tikz.append(NoEscape(
r'\draw[decorate, decoration={zigzag, amplitude=0.2cm}] '
r'(0,-1) -- (4,-1);'
))The Axis class provides sophisticated plotting capabilities through PGFPlots integration.
class Axis(Environment):
def __init__(self, options=None, *, data=None):
"""
Create a PGFPlots axis environment for data plotting.
Parameters:
- options: str, list, or Options, axis configuration options
- data: initial plot content
Requires:
- pgfplots package (automatically added)
- pgfplotsset compatibility setting (automatically configured)
"""
class Plot(Command):
def __init__(self, name=None, func=None, coordinates=None,
error_bar=None, options=None):
"""
Create a plot within an axis environment.
Parameters:
- name: str, plot name for legend
- func: str, mathematical function to plot
- coordinates: list, data points as coordinate pairs
- error_bar: dict, error bar specifications
- options: str or Options, plot styling options
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ, Axis, Plot
import numpy as np
doc = Document()
with doc.create(Section('Data Plotting')):
# Basic function plot
with doc.create(TikZ()) as tikz:
with tikz.create(Axis(options='xlabel=x, ylabel=y, title=Function Plot')) as axis:
axis.append(Plot(name='sin(x)', func='sin(deg(x))'))
axis.append(Plot(name='cos(x)', func='cos(deg(x))'))
# Data point plotting
with doc.create(TikZ()) as tikz:
# Generate sample data
x_data = np.linspace(0, 10, 20)
y_data = np.sin(x_data) + 0.1 * np.random.randn(20)
coordinates = [(x, y) for x, y in zip(x_data, y_data)]
axis_options = [
'xlabel=Time (s)',
'ylabel=Amplitude',
'title=Experimental Data',
'grid=major',
'legend pos=north east'
]
with tikz.create(Axis(options=axis_options)) as axis:
axis.append(Plot(name='Measured', coordinates=coordinates,
options='only marks, mark=*'))
axis.append(Plot(name='Theory', func='sin(deg(x))',
options='thick, red'))
# Multiple axis types
with doc.create(Section('Specialized Plots')):
# Logarithmic scale
with doc.create(TikZ()) as tikz:
log_options = [
'xmode=log',
'ymode=log',
'xlabel=Frequency (Hz)',
'ylabel=Magnitude',
'title=Bode Plot'
]
with tikz.create(Axis(options=log_options)) as axis:
# Frequency response data
freq = np.logspace(0, 3, 50)
magnitude = 1 / np.sqrt(1 + (freq/100)**2)
coords = [(f, m) for f, m in zip(freq, magnitude)]
axis.append(Plot(coordinates=coords, options='thick, blue'))Advanced styling and localized transformations using scope environments.
class TikZScope(Environment):
def __init__(self, options=None, *, data=None):
"""
Create a TikZ scope for localized styling and transformations.
Parameters:
- options: str or TikZOptions, scope-specific options
- data: initial scope content
"""
class TikZOptions(Options):
"""
Specialized options class for TikZ with no escaping.
"""
def append_positional(self, option):
"""
Add positional option to TikZ options.
Parameters:
- option: str, option to add
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ, TikZScope, TikZOptions
doc = Document()
with doc.create(Section('Scoped Styling')):
with doc.create(TikZ()) as tikz:
# Global elements
tikz.append(NoEscape(r'\draw (0,0) rectangle (6,4);'))
# Scoped transformations and styling
scope_options = TikZOptions(['red', 'thick', 'scale=0.5', 'shift={(1,1)}'])
with tikz.create(TikZScope(options=scope_options)) as scope:
scope.append(NoEscape(r'\draw (0,0) rectangle (4,2);'))
scope.append(NoEscape(r'\fill[blue] (2,1) circle (0.5);'))
# Different scope with rotation
rotate_options = TikZOptions(['rotate=45', 'shift={(4,2)}'])
with tikz.create(TikZScope(options=rotate_options)) as scope:
scope.append(NoEscape(r'\draw[green, thick] (0,0) -- (2,0) -- (1,1) -- cycle;'))
# Nested scopes
with doc.create(Section('Nested Scopes')):
with doc.create(TikZ()) as tikz:
with tikz.create(TikZScope(options='blue, thick')) as outer_scope:
outer_scope.append(NoEscape(r'\draw (0,0) rectangle (4,3);'))
with outer_scope.create(TikZScope(options='red, scale=0.5')) as inner_scope:
inner_scope.append(NoEscape(r'\draw (1,1) rectangle (3,2);'))
inner_scope.append(NoEscape(r'\node at (2,1.5) {Nested};'))from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ, TikZNode, TikZCoordinate
doc = Document()
with doc.create(Section('System Architecture')):
with doc.create(TikZ()) as tikz:
# Define diagram components
components = [
('User Interface', TikZCoordinate(0, 3), 'fill=lightblue'),
('API Layer', TikZCoordinate(0, 2), 'fill=lightgreen'),
('Business Logic', TikZCoordinate(0, 1), 'fill=yellow'),
('Database', TikZCoordinate(0, 0), 'fill=pink')
]
# Draw components
for name, pos, style in components:
tikz.append(NoEscape(f r'\node[draw, {style}, minimum width=3cm, minimum height=0.8cm] '
f'at {pos} {{{name}}};'))
# Draw connections
for i in range(len(components) - 1):
y1, y2 = 3 - i - 0.4, 3 - i - 1 + 0.4
tikz.append(NoEscape(f r'\draw[thick, ->] (0,{y1}) -- (0,{y2});'))
# Network diagram
with doc.create(Section('Network Topology')):
with doc.create(TikZ()) as tikz:
# Server nodes
servers = [
('Web Server', TikZCoordinate(0, 2)),
('App Server', TikZCoordinate(3, 2)),
('DB Server', TikZCoordinate(6, 2))
]
# Client nodes
clients = [
('Client 1', TikZCoordinate(1, 0)),
('Client 2', TikZCoordinate(2, 0)),
('Client 3', TikZCoordinate(4, 0)),
('Client 4', TikZCoordinate(5, 0))
]
# Draw servers
for name, pos in servers:
tikz.append(NoEscape(f r'\node[draw, rectangle, fill=lightblue] '
f'at {pos} {{{name}}};'))
# Draw clients
for name, pos in clients:
tikz.append(NoEscape(f r'\node[draw, circle, fill=lightgreen] '
f'at {pos} {{{name}}};'))
# Connect clients to web server
for _, pos in clients:
tikz.append(NoEscape(f r'\draw[->] {pos} -- (0,2);'))
# Connect servers
tikz.append(NoEscape(r'\draw[<->] (0,2) -- (3,2);'))
tikz.append(NoEscape(r'\draw[<->] (3,2) -- (6,2);'))from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ, Axis
import numpy as np
doc = Document()
with doc.create(Section('Mathematical Functions')):
# 3D surface plot
with doc.create(TikZ()) as tikz:
axis_options = [
'view={60}{30}',
'xlabel=x',
'ylabel=y',
'zlabel=z',
'title=3D Surface'
]
with tikz.create(Axis(options=axis_options)) as axis:
# Generate 3D function data
axis.append(NoEscape(
r'\addplot3[surf, samples=20, domain=-2:2] {x*x + y*y};'
))
# Vector field visualization
with doc.create(Section('Vector Fields')):
with doc.create(TikZ()) as tikz:
axis_options = [
'axis equal',
'xlabel=x',
'ylabel=y',
'title=Vector Field',
'grid=major'
]
with tikz.create(Axis(options=axis_options)) as axis:
# Create vector field
for x in np.linspace(-2, 2, 10):
for y in np.linspace(-2, 2, 10):
# Vector components (simple example)
dx, dy = -y * 0.3, x * 0.3
tikz.append(NoEscape(
f r'\draw[->] ({x},{y}) -- ({x+dx},{y+dy});'
))from pylatex import Document, Section, Package, NoEscape
from pylatex.tikz import TikZ
doc = Document()
# Enable TikZ libraries for advanced features
doc.packages.append(Package('tikz', options=[
'arrows', 'positioning', 'shapes', 'decorations.markings'
]))
with doc.create(Section('Flow Chart')):
with doc.create(TikZ()) as tikz:
# Define node styles
tikz.append(NoEscape(r'''
\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm,
text centered, draw=black, fill=orange!30]
\tikzstyle{decision} = [diamond, minimum width=3cm, minimum height=1cm,
text centered, draw=black, fill=green!30]
\tikzstyle{arrow} = [thick,->,>=stealth]
'''))
# Create flowchart
tikz.append(NoEscape(r'''
\node (start) [process] {Start Process};
\node (check) [decision, below of=start, yshift=-1cm] {Check Condition};
\node (process1) [process, below of=check, yshift=-1cm] {Execute Action};
\node (end) [process, below of=process1, yshift=-1cm] {End Process};
\draw [arrow] (start) -- (check);
\draw [arrow] (check) -- node[anchor=west] {Yes} (process1);
\draw [arrow] (process1) -- (end);
\draw [arrow] (check) -| node[anchor=south] {No} (end);
'''))from pylatex import Document, Section, NoEscape
from pylatex.tikz import TikZ, TikZOptions
doc = Document()
# Define custom styles in preamble
doc.preamble.append(NoEscape(r'''
\tikzset{
highlight/.style={draw=red, fill=red!20, thick},
note/.style={draw=blue, dashed, fill=blue!10},
arrow/.style={thick, ->, >=latex}
}
'''))
with doc.create(Section('Custom Styles')):
with doc.create(TikZ()) as tikz:
tikz.append(NoEscape(r'\draw[highlight] (0,0) rectangle (2,1);'))
tikz.append(NoEscape(r'\draw[note] (3,0) circle (0.5);'))
tikz.append(NoEscape(r'\draw[arrow] (2,0.5) -- (2.5,0);'))from pylatex import Document, Package, NoEscape
from pylatex.tikz import TikZ
doc = Document()
doc.packages.append(Package('xcolor'))
# Define color palette
doc.preamble.append(NoEscape(r'''
\definecolor{primary}{RGB}{65, 105, 225}
\definecolor{secondary}{RGB}{220, 20, 60}
\definecolor{accent}{RGB}{255, 165, 0}
'''))
with doc.create(TikZ()) as tikz:
tikz.append(NoEscape(r'\fill[primary] (0,0) rectangle (2,1);'))
tikz.append(NoEscape(r'\fill[secondary] (2.5,0) rectangle (4.5,1);'))
tikz.append(NoEscape(r'\fill[accent] (5,0) rectangle (7,1);'))TikZ functionality requires specific LaTeX packages:
tikz package (automatically added)pgfplots package (automatically added with Axis)pgfplots with 3D capabilitiesfrom pylatex import Document, Package
doc = Document()
# TikZ packages and libraries
doc.packages.append(Package('tikz'))
doc.packages.append(Package('pgfplots'))
doc.packages.append(Package('tikz', options=[
'arrows', 'positioning', 'shapes', 'decorations',
'patterns', 'calc', 'through', 'intersections'
]))
# PGFPlots configuration
doc.preamble.append(NoEscape(r'\pgfplotsset{compat=newest}'))The TikZ system in PyLaTeX provides powerful vector graphics capabilities with programmatic control over complex diagrams, technical illustrations, and data visualizations while maintaining the high quality and precision of LaTeX graphics.
Install with Tessl CLI
npx tessl i tessl/pypi-pylatex