CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pylatex

A comprehensive Python library for programmatically creating and compiling LaTeX documents and snippets.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

quantities.mddocs/

Physical Quantities and Units

Scientific notation and unit handling with SIunits integration for proper typesetting of measurements and quantities. PyLaTeX provides seamless integration with Python's quantities package and LaTeX's siunitx package for professional scientific notation, unit formatting, and uncertainty representation.

Capabilities

Quantity Class

The Quantity class converts Python quantity objects into properly formatted LaTeX output using the siunitx package.

class Quantity(Command):
    def __init__(self, quantity, *, options=None, format_cb=None):
        """
        Create properly formatted physical quantities with units.
        
        Parameters:
        - quantity: quantities.Quantity, UncertainQuantity, or numeric value
        - options: dict, str, list, or Options, siunitx formatting options
        - format_cb: callable, custom number formatting function (default: numpy.array_str)
        
        Requires:
        - siunitx package (automatically added)
        - quantities Python package for quantity objects
        
        Examples:
        - Simple quantity: Quantity(3.14159 * meter / second)
        - With uncertainty: Quantity(UncertainQuantity(16.0, meter, 0.3))
        - Plain number: Quantity(6.022e23)
        """

Usage example:

from pylatex import Document, Section
from pylatex.quantities import Quantity
import quantities as pq

doc = Document()

with doc.create(Section('Physical Measurements')):
    # Basic quantities with units
    speed = 299792458 * pq.meter / pq.second
    doc.append('Speed of light: ')
    doc.append(Quantity(speed, options={'round-precision': 4, 'round-mode': 'figures'}))
    
    # Force measurement
    force = 9.81 * pq.newton
    doc.append(' Force: ')
    doc.append(Quantity(force))
    
    # Energy calculation
    mass = 2.5 * pq.kilogram
    energy = 0.5 * mass * (10 * pq.meter/pq.second)**2
    doc.append(' Kinetic energy: ')
    doc.append(Quantity(energy))

Uncertainty Handling

Automatic formatting of measurements with uncertainties using proper scientific notation.

from pylatex import Document, Section
from pylatex.quantities import Quantity
import quantities as pq

doc = Document()

with doc.create(Section('Experimental Results')):
    # Measurements with uncertainties
    length = pq.UncertainQuantity(16.0, pq.meter, 0.3)
    width = pq.UncertainQuantity(12.5, pq.meter, 0.2)
    
    doc.append('Length: ')
    doc.append(Quantity(length))
    doc.append(' Width: ')
    doc.append(Quantity(width))
    
    # Calculated quantities with error propagation
    area = length * width
    doc.append(' Area: ')
    doc.append(Quantity(area))
    
    # Temperature measurements
    temp = pq.UncertainQuantity(23.5, pq.celsius, 0.1)
    doc.append(' Temperature: ')
    doc.append(Quantity(temp))

Scientific Notation for Numbers

Format large numbers and scientific notation without units.

from pylatex import Document, Section
from pylatex.quantities import Quantity

doc = Document()

with doc.create(Section('Scientific Constants')):
    # Avogadro's number
    avogadro = 6.022140857e23
    doc.append('Avogadro constant: ')
    doc.append(Quantity(avogadro, options={'round-precision': 4}))
    
    # Planck constant
    planck = 6.62607015e-34
    doc.append(' Planck constant: ')
    doc.append(Quantity(planck, options={'scientific-notation': True}))
    
    # Very small number
    small_number = 1.234e-12
    doc.append(' Small measurement: ')
    doc.append(Quantity(small_number, options={'round-precision': 3, 'round-mode': 'figures'}))

Advanced Quantity Formatting

Custom Formatting Options

Control the appearance of quantities using siunitx options.

from pylatex import Document, Section
from pylatex.quantities import Quantity
import quantities as pq

doc = Document()

with doc.create(Section('Formatting Examples')):
    value = 1234.5678 * pq.meter
    
    # Different rounding modes
    doc.append('Default: ')
    doc.append(Quantity(value))
    doc.append(' Rounded to 2 places: ')
    doc.append(Quantity(value, options={'round-precision': 2, 'round-mode': 'places'}))
    doc.append(' 3 significant figures: ')
    doc.append(Quantity(value, options={'round-precision': 3, 'round-mode': 'figures'}))
    
    # Scientific notation control
    large_value = 123456789 * pq.joule
    doc.append(' Scientific notation: ')
    doc.append(Quantity(large_value, options={'scientific-notation': True}))
    doc.append(' Fixed notation: ')
    doc.append(Quantity(large_value, options={'scientific-notation': False}))

Unit Formatting and Combinations

Handle complex unit combinations and formatting preferences.

from pylatex import Document, Section, Package
from pylatex.quantities import Quantity
import quantities as pq

doc = Document()

# Configure siunitx options globally
doc.packages.append(Package('siunitx', options=[
    'per-mode=symbol',
    'group-separator={,}',
    'output-decimal-marker={.}'
]))

with doc.create(Section('Complex Units')):
    # Velocity
    velocity = 15.5 * pq.meter / pq.second
    doc.append('Velocity: ')
    doc.append(Quantity(velocity))
    
    # Acceleration  
    acceleration = 9.81 * pq.meter / (pq.second**2)
    doc.append(' Acceleration: ')
    doc.append(Quantity(acceleration))
    
    # Power
    power = 750 * pq.watt
    doc.append(' Power: ')
    doc.append(Quantity(power))
    
    # Pressure
    pressure = 101325 * pq.pascal
    doc.append(' Pressure: ')
    doc.append(Quantity(pressure, options={'per-mode': 'fraction'}))
    
    # Density
    density = 1000 * pq.kilogram / (pq.meter**3)
    doc.append(' Density: ')
    doc.append(Quantity(density))

Custom Number Formatting

Implement custom formatting functions for specialized number presentation.

from pylatex import Document, Section
from pylatex.quantities import Quantity
import quantities as pq
import numpy as np

doc = Document()

def engineering_format(value):
    """Format numbers in engineering notation (powers of 1000)."""
    if value == 0:
        return "0"
    
    exponent = int(np.floor(np.log10(abs(value)) / 3) * 3)
    mantissa = value / (10 ** exponent)
    
    if exponent == 0:
        return f"{mantissa:.3f}"
    else:
        return f"{mantissa:.3f}e{exponent:+d}"

def percent_format(value):
    """Format as percentage with 1 decimal place."""
    return f"{value:.1f}"

with doc.create(Section('Custom Formatting')):
    # Engineering notation
    resistance = 47000 * pq.ohm
    doc.append('Resistance: ')
    doc.append(Quantity(resistance, format_cb=engineering_format))
    
    # Percentage format for efficiency
    efficiency = 0.856
    doc.append(' Efficiency: ')
    doc.append(Quantity(efficiency * 100, format_cb=percent_format))
    doc.append('%')
    
    # Custom precision for angles
    angle = np.pi / 4 * pq.radian
    doc.append(' Angle: ')
    doc.append(Quantity(angle, format_cb=lambda x: f"{x:.4f}"))

Integration with Calculations

Experimental Data Analysis

from pylatex import Document, Section, Subsection
from pylatex.quantities import Quantity
from pylatex.table import Tabular, Table
import quantities as pq
import numpy as np

doc = Document()

with doc.create(Section('Experimental Analysis')):
    # Sample experimental data
    measurements = [
        pq.UncertainQuantity(12.3, pq.meter, 0.1),
        pq.UncertainQuantity(12.5, pq.meter, 0.1),
        pq.UncertainQuantity(12.1, pq.meter, 0.1),
        pq.UncertainQuantity(12.4, pq.meter, 0.1),
        pq.UncertainQuantity(12.2, pq.meter, 0.1)
    ]
    
    with doc.create(Subsection('Raw Data')):
        with doc.create(Table(position='htbp')) as table:
            table.add_caption('Length Measurements')
            
            with table.create(Tabular('cc')) as tabular:
                tabular.add_row(['Trial', 'Length'])
                tabular.add_hline()
                
                for i, measurement in enumerate(measurements, 1):
                    tabular.add_row([str(i), Quantity(measurement)])
    
    with doc.create(Subsection('Statistical Analysis')):
        # Calculate statistics
        values = [m.magnitude for m in measurements]
        mean_value = np.mean(values)
        std_value = np.std(values, ddof=1)
        
        mean_quantity = pq.UncertainQuantity(mean_value, pq.meter, std_value/np.sqrt(len(values)))
        
        doc.append('Mean length: ')
        doc.append(Quantity(mean_quantity, options={'round-precision': 3}))
        
        doc.append(' Standard deviation: ')
        doc.append(Quantity(std_value * pq.meter, options={'round-precision': 3}))

Unit Conversions and Calculations

from pylatex import Document, Section
from pylatex.quantities import Quantity
from pylatex.math import Math
import quantities as pq

doc = Document()

with doc.create(Section('Physics Calculations')):
    # Kinematic calculation
    initial_velocity = 0 * pq.meter / pq.second
    acceleration = 9.81 * pq.meter / (pq.second**2)
    time = 3.5 * pq.second
    
    # Calculate final velocity: v = v₀ + at
    final_velocity = initial_velocity + acceleration * time
    
    doc.append('Initial velocity: ')
    doc.append(Quantity(initial_velocity))
    doc.append(' Acceleration: ')
    doc.append(Quantity(acceleration))
    doc.append(' Time: ')
    doc.append(Quantity(time))
    doc.append(' Final velocity: ')
    doc.append(Quantity(final_velocity))
    
    # Distance calculation: s = v₀t + ½at²
    distance = initial_velocity * time + 0.5 * acceleration * (time**2)
    doc.append(' Distance traveled: ')
    doc.append(Quantity(distance))
    
    # Energy calculations
    mass = 2.5 * pq.kilogram
    kinetic_energy = 0.5 * mass * (final_velocity**2)
    potential_energy = mass * acceleration * distance
    
    doc.append(' Kinetic energy: ')
    doc.append(Quantity(kinetic_energy))
    doc.append(' Potential energy: ')
    doc.append(Quantity(potential_energy))

Multi-Unit Systems

from pylatex import Document, Section
from pylatex.quantities import Quantity
import quantities as pq

doc = Document()

with doc.create(Section('Unit Systems Comparison')):
    # Same quantity in different units
    distance_m = 1000 * pq.meter
    distance_km = distance_m.rescale(pq.kilometer)
    distance_mile = distance_m.rescale(pq.mile)
    
    doc.append('Distance in meters: ')
    doc.append(Quantity(distance_m))
    doc.append(' In kilometers: ')
    doc.append(Quantity(distance_km))
    doc.append(' In miles: ')
    doc.append(Quantity(distance_mile, options={'round-precision': 2}))
    
    # Temperature conversions
    temp_c = 25 * pq.celsius
    temp_f = temp_c.rescale(pq.fahrenheit)
    temp_k = temp_c.rescale(pq.kelvin)
    
    doc.append(' Temperature in Celsius: ')
    doc.append(Quantity(temp_c))
    doc.append(' Fahrenheit: ')
    doc.append(Quantity(temp_f))
    doc.append(' Kelvin: ')
    doc.append(Quantity(temp_k))

Package Configuration

Global SIunitx Settings

Configure siunitx package options for consistent formatting throughout the document.

from pylatex import Document, Package, NoEscape, Command
from pylatex.quantities import Quantity

doc = Document()

# Configure siunitx globally
doc.packages.append(Package('siunitx', options=[
    'separate-uncertainty=true',
    'multi-part-units=single',
    'bracket-numbers=false',
    'per-mode=symbol',
    'group-separator={,}',
    'group-minimum-digits=4',
    'round-mode=figures',
    'round-precision=3'
]))

# Add custom units
doc.preamble.append(Command('DeclareSIUnit', arguments=[NoEscape(r'\rpm'), 'rpm']))
doc.preamble.append(Command('DeclareSIUnit', arguments=[NoEscape(r'\ppm'), 'ppm']))
doc.preamble.append(Command('DeclareSIUnit', arguments=[NoEscape(r'\year'), 'year']))

Unit Name Translations

Handle unit name differences between Python quantities and siunitx.

# The UNIT_NAME_TRANSLATIONS dictionary in quantities.py handles conversions:
UNIT_NAME_TRANSLATIONS = {
    "Celsius": "celsius",
    "revolutions_per_minute": "rpm",
    "v": "volt",
    # Add custom translations as needed
}

# Custom units can be added to the document
from pylatex import Document, Command, NoEscape

doc = Document()

# Define custom units in preamble
custom_units = [
    (r'\rpm', 'rpm'),
    (r'\ppm', 'ppm'), 
    (r'\percent', r'\%'),
    (r'\year', 'year'),
    (r'\bit', 'bit'),
    (r'\byte', 'B')
]

for unit_command, unit_name in custom_units:
    doc.preamble.append(Command('DeclareSIUnit', arguments=[NoEscape(unit_command), unit_name]))

Error Handling and Validation

Handling Invalid Units

from pylatex import Document, Section
from pylatex.quantities import Quantity
import quantities as pq

doc = Document()

try:
    # This might fail if the unit isn't recognized
    custom_measurement = 42 * pq.meter  # This should work
    doc.append(Quantity(custom_measurement))
    
except Exception as e:
    doc.append(f"Error formatting quantity: {e}")
    
# Fallback for unsupported units
def safe_quantity(value, unit=None, **options):
    """Safely create quantity with fallback formatting."""
    try:
        if unit is not None:
            return Quantity(value * unit, **options)
        else:
            return Quantity(value, **options)
    except Exception:
        # Fallback to plain number
        return str(value) + (f" {unit}" if unit else "")

Best Practices

Consistent Formatting

from pylatex import Document, Section
from pylatex.quantities import Quantity
import quantities as pq

# Define standard formatting options
STANDARD_OPTIONS = {
    'round-precision': 3,
    'round-mode': 'figures',
    'scientific-notation': False
}

SCIENTIFIC_OPTIONS = {
    'round-precision': 3,
    'round-mode': 'figures', 
    'scientific-notation': True
}

doc = Document()

with doc.create(Section('Consistent Formatting')):
    # Use consistent options throughout
    speed = 299792458 * pq.meter / pq.second
    doc.append('Speed of light: ')
    doc.append(Quantity(speed, options=SCIENTIFIC_OPTIONS))
    
    charge = 1.602176634e-19 * pq.coulomb
    doc.append(' Elementary charge: ')
    doc.append(Quantity(charge, options=SCIENTIFIC_OPTIONS))

Documentation Standards

from pylatex import Document, Section, Subsection
from pylatex.quantities import Quantity
import quantities as pq

doc = Document()

with doc.create(Section('Material Properties')):
    # Always include uncertainties when available
    density_steel = pq.UncertainQuantity(7850, pq.kilogram/(pq.meter**3), 50)
    doc.append('Steel density: ')
    doc.append(Quantity(density_steel))
    
    # Use appropriate significant figures
    youngs_modulus = 200e9 * pq.pascal
    doc.append(' Young\'s modulus: ')
    doc.append(Quantity(youngs_modulus, options={
        'round-precision': 3,
        'scientific-notation': True
    }))
    
    # Include measurement conditions when relevant
    doc.append(' (measured at room temperature)')

The quantities system in PyLaTeX enables professional scientific notation and unit handling with automatic formatting, uncertainty propagation, and seamless integration between Python calculations and LaTeX typesetting.

Install with Tessl CLI

npx tessl i tessl/pypi-pylatex

docs

base-classes.md

configuration.md

document.md

figures.md

index.md

layout.md

lists.md

math.md

quantities.md

references.md

sectioning.md

tables.md

text-formatting.md

tikz.md

utilities.md

tile.json