Skip to main content

A Python library for tornado chart generation and analysis

Project description

TornadoPy

A Python library for tornado chart generation and analysis. TornadoPy provides tools for processing Excel-based tornado data and generating professional tornado charts for uncertainty analysis.

Features

  • TornadoProcessor: Process Excel files containing tornado analysis data

    • Parse multi-sheet Excel files with complex headers
    • Extract and compute statistics (p90p10, mean, median, minmax, percentiles)
    • Filter data by properties and dynamic fields
    • Case selection with weighted criteria
    • Batch processing for multiple parameters
  • tornado_plot: Generate professional tornado charts

    • Customizable colors, fonts, and styling
    • Support for p90/p10 ranges with automatic label placement
    • Reference case lines
    • Custom parameter ordering
    • Export to various image formats

Installation

From source

git clone https://github.com/kkollsga/tornadopy.git
cd tornadopy
pip install -e .

For development

pip install -e ".[dev]"

Quick Start

Processing Tornado Data

from tornadopy import TornadoProcessor

# Load Excel file with tornado data
processor = TornadoProcessor("tornado_data.xlsb")

# Get available parameters
parameters = processor.get_parameters()
print(f"Parameters: {parameters}")

# Get properties for a parameter
properties = processor.get_properties(parameter="Parameter1")
print(f"Properties: {properties}")

# Compute statistics
result = processor.compute(
    stats="p90p10",
    parameter="Parameter1",
    filters={"property": "npv"},
    multiplier=1e-6  # Convert to millions
)
print(f"P90/P10: {result['p90p10']}")

Generating Tornado Charts

from tornadopy import TornadoProcessor, tornado_plot

# Get tornado data
processor = TornadoProcessor("tornado_data.xlsb")
tornado_data = processor.get_tornado_data(
    parameters="all",
    filters={"property": "npv"},
    multiplier=1e-6
)

# Convert to sections format for plotting
sections = []
for param, data in tornado_data.items():
    sections.append({
        "parameter": param,
        "minmax": [data["p10"], data["p90"]],
        "p90p10": [data["p10"], data["p90"]]
    })

# Generate tornado chart
fig, ax, saved = tornado_plot(
    sections=sections,
    title="NPV Tornado Chart",
    subtitle="Base case = 100.0 MM USD",
    base=100.0,
    unit="MM USD",
    outfile="tornado_chart.png"
)

Advanced Usage

Multi-property Analysis

# Compute statistics for multiple properties
result = processor.compute(
    stats=["p90p10", "mean", "median"],
    parameter="Parameter1",
    filters={"property": ["npv", "irr"]}
)
print(f"NPV P90/P10: {result['p90p10'][0]}")
print(f"IRR P90/P10: {result['p90p10'][1]}")

Case Selection with Weighted Criteria

# Find closest cases to p90/p10 with custom weights
result = processor.compute(
    stats="p90p10",
    parameter="Parameter1",
    filters={"property": "npv"},
    case_selection=True,
    selection_criteria={
        "weights": {"npv": 0.6, "irr": 0.4}
    }
)

# Access closest cases
for case in result["closest_cases"]:
    print(f"Case {case['case']}: idx={case['idx']}, value={case['npv']}")

Batch Processing

# Process all parameters at once
results = processor.compute_batch(
    stats="p90p10",
    parameters="all",
    filters={"property": "npv"},
    multiplier=1e-6
)

for result in results:
    print(f"{result['parameter']}: {result['p90p10']}")

Custom Chart Styling

# Create custom styled tornado chart
settings = {
    "figsize": (12, 8),
    "dpi": 200,
    "pos_dark": "#1E88E5",
    "neg_dark": "#D32F2F",
    "show_values": ["min", "max", "p10", "p90"],
    "show_percentage_diff": True,
}

fig, ax, saved = tornado_plot(
    sections=sections,
    title="Custom Styled Tornado Chart",
    base=100.0,
    reference_case=110.0,
    preferred_order=["Param1", "Param2", "Param3"],
    settings=settings,
    outfile="custom_tornado.png"
)

Excel File Format

TornadoPy expects Excel files with the following structure:

[Info rows - optional metadata]
Header Row 1    | Dynamic Field 1 | Dynamic Field 1 | ...
Header Row 2    | Value A         | Value B         | ...
Case            | Property 1      | Property 2      | ...
1               | 123.45          | 67.89           | ...
2               | 234.56          | 78.90           | ...
...
  • Multiple header rows are supported and will be combined
  • The "Case" row marks the start of data
  • Dynamic fields in column A define metadata columns
  • Property names are extracted from the last header row

API Reference

TornadoProcessor

Methods

  • get_parameters(): Get list of available parameters (sheet names)
  • get_properties(parameter): Get available properties for a parameter
  • get_unique(field, parameter): Get unique values for a dynamic field
  • get_info(parameter): Get metadata for a parameter
  • get_case(index, parameter): Get data for a specific case
  • compute(stats, parameter, filters, multiplier, options, case_selection, selection_criteria): Compute statistics
  • compute_batch(...): Batch compute for multiple parameters
  • get_tornado_data(...): Get tornado chart formatted data

tornado_plot

Parameters

  • sections: List of section dictionaries with parameter data
  • title: Chart title
  • subtitle: Chart subtitle
  • outfile: Output file path
  • base: Base case value
  • reference_case: Reference case line value
  • unit: Unit label
  • preferred_order: List of parameter names for custom ordering
  • settings: Dictionary of visual settings

Returns

  • fig: Matplotlib figure object
  • ax: Matplotlib axes object
  • saved: Path to saved file (if outfile specified)

Requirements

  • Python >= 3.8
  • numpy >= 1.20.0
  • polars >= 0.18.0
  • pyxlsb >= 1.0.9
  • matplotlib >= 3.5.0

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues and questions, please open an issue on GitHub.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tornadopy-0.1.4.tar.gz (22.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tornadopy-0.1.4-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file tornadopy-0.1.4.tar.gz.

File metadata

  • Download URL: tornadopy-0.1.4.tar.gz
  • Upload date:
  • Size: 22.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for tornadopy-0.1.4.tar.gz
Algorithm Hash digest
SHA256 29943f33713fa0b6c978cccd7036a986b86fa3ce9e2573bc65b1581eeae17c9d
MD5 45094ef8bbf71525a22f7d4e61f7cb96
BLAKE2b-256 5febb2097ebfca08c7a1bc977658700ec81783d44667cbf996180f5fbe9d3eb0

See more details on using hashes here.

File details

Details for the file tornadopy-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: tornadopy-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for tornadopy-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e1bde2fd460d54247f5628ccd7f481c00f295b7f50d8eaa1679a637062f2ea1a
MD5 873d2bf849a4613f78e9a13a80a9cf06
BLAKE2b-256 a5da297c38449a4cedee18e72907d092ce61fa33a69c587f41d01ba897e2970a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page