Skip to content

Getting started

Install plotsim, generate a dataset, look at the files. Target: first CSV on disk in under sixty seconds.

Install

pip install plotsim

That's the core engine — numpy, scipy, pandas, pydantic, pyyaml. For Parquet output add the optional extra:

pip install "plotsim[parquet]"

Run a bundled template

The fastest path is a bundled template. Six ship with the package: banking, health, hr, marketing, retail, saas. The CLI flow:

plotsim template saas -o saas.yaml
plotsim run saas.yaml -o ./output

The first command writes the SaaS template's YAML to saas.yaml. The second generates the dataset into ./output/. You should see something like:

Generating dataset from saas.yaml (seed=1729)...
Wrote 9 table(s), 4812 total row(s) to output/

Open output/ — you'll find one CSV per table plus config.yaml, validation_report.txt, and manifest.json.

Run from Python

The same flow from Python:

from plotsim import load_template, generate_tables, write_tables

config = load_template("saas")
tables = generate_tables(config)
write_tables(tables, config, output_dir="./output")
plotsim template saas -o saas.yaml
plotsim run saas.yaml -o ./output

tables is a dict[str, pandas.DataFrame] keyed by table name — you can inspect rows directly without leaving Python.

Build your own config

Skip the template and describe the dataset in keyword arguments. The minimum viable config:

from plotsim import create, generate_tables, write_tables

config = create(
    about="Subscription customers",
    unit="customer",
    window=("2024-01", "2024-12", "monthly"),
    seed=42,
    metrics=[
        {"name": "engagement", "type": "score", "polarity": "positive"},
        {"name": "payments",   "type": "count", "polarity": "positive"},
    ],
    segments=[
        {"name": "active",   "count": 50, "archetype": "growth"},
        {"name": "inactive", "count": 30, "archetype": "decline"},
    ],
)
tables = generate_tables(config)
write_tables(tables, config, output_dir="./output")
about: Subscription customers
unit: customer
window: { start: "2024-01", end: "2024-12", every: monthly }
seed: 42

metrics:
  - { name: engagement, type: score, polarity: positive }
  - { name: payments,   type: count, polarity: positive }

segments:
  - { name: active,   count: 50, archetype: growth }
  - { name: inactive, count: 30, archetype: decline }
plotsim run config.yaml -o ./output

That config generates a three-table dataset: dim_date, dim_customer, and fct_customer (one row per customer per month). When you don't declare dimensions, facts, and events, plotsim auto-generates a sensible schema from the metrics and segments.

What just happened

  1. Each segment got an archetype — growth (a sigmoid rise) or decline (an exponential fall). The archetype defines a master trajectory over the time window.
  2. For each entity at each time period, plotsim evaluated the archetype curve, producing a position in [0, 1].
  3. Each metric value was derived from that position — high position means high engagement and high payments (both positive polarity).
  4. The same seed produces the same output every run.

That trajectory-first contract is the core of how plotsim works — every metric for a given entity at a given period traces back to one trajectory position. See How plotsim works.

Next steps