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.3.tar.gz (22.5 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.3-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: tornadopy-0.1.3.tar.gz
  • Upload date:
  • Size: 22.5 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.3.tar.gz
Algorithm Hash digest
SHA256 b3f979e75656b6bda8bf843066c265cbe5973bdf2ceaeee6caac71d683dd093a
MD5 0faa87151486fc0c5e19adabc2bbd77d
BLAKE2b-256 28b731c8d5b5bf46b7858e5806309bfbd51bbaf30d8293859d5224ce49ea8e42

See more details on using hashes here.

File details

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

File metadata

  • Download URL: tornadopy-0.1.3-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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 978b871d8619add9dafbcfa341905347d8f1f82c76d402ba28e208244562d3d6
MD5 fa49502a7f4b64e66a0eb7725a958065
BLAKE2b-256 7569149f04ddbdaff813bcc334c4421441d52eb594ecec779a24f0017236f655

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