Skip to content

Time Series

Generate realistic temporal sequences with trend, seasonality, noise, and anomaly injection — metrics, sensor data, KPIs, DAU curves, revenue forecasts.

Quick start

import misata

# Story-driven — Misata infers everything from plain English
ts = misata.generate_timeseries(
    "Daily active users over 1 year, growing 10% monthly "
    "with weekly seasonality and a viral spike",
    start_value=5_000,
    seed=42,
)

print(ts.head())
#         date  daily_active_users    trend  seasonal  is_anomaly
# 2023-01-01             4812.3   5000.0    -187.7       False
# 2023-01-02             5231.4   5010.0     221.4       False
# ...

ts.plot(x="date", y="daily_active_users")

Config-driven

from misata.timeseries import TimeSeriesConfig, Trend, Seasonality, Anomaly

config = TimeSeriesConfig(
    metric="revenue",
    periods=365,
    freq="D",                        # "D" daily | "h" hourly | "W" weekly | "ME" monthly
    start_date="2024-01-01",
    start_value=10_000,
    trend=Trend(type="exponential", rate=0.003),   # ~0.3%/day compound growth
    seasonality=[
        Seasonality(type="weekly",  amplitude=0.25, peak_offset=4),   # Fri peak
        Seasonality(type="yearly",  amplitude=0.40, peak_offset=355), # Dec peak
    ],
    noise_std=0.05,
    noise_type="gaussian",           # "gaussian" or "poisson" (for count data)
    anomalies=[
        Anomaly(at_period=170, magnitude=4.0, duration=3, shape="spike"),  # viral moment
        Anomaly(at_period=290, magnitude=0.2, duration=1, shape="flat"),   # outage
    ],
    min_value=0.0,
    seed=42,
)

ts = misata.generate_timeseries(config=config)

Output columns

Column Description
date Timestamp at the chosen frequency
<metric> The generated value (trend + seasonal + noise + anomalies)
trend Pure trend component (no seasonality or noise)
seasonal Seasonal contribution added to trend
is_anomaly True for periods covered by an Anomaly

Story inference

The story parser extracts:

  • Metric name — "daily active users" → daily_active_users, "revenue" → revenue
  • Periods — "over 2 years" → 730 days; "for 6 months" → 180 days
  • Trend — "growing 15% monthly" → exponential rate=0.005; "declining" → negative rate
  • Seasonality — "weekly seasonality" → weekly component; "summer peak" → yearly component
  • Anomalies — "viral spike" → 4× magnitude spike; "outage" or "crash" → 0.1× drop

Trend types

type Description Key param
linear Constant absolute growth per period rate (units/period)
exponential Compounding percentage growth rate (fraction/period, e.g. 0.003)
stepwise Step-function changes at specified periods steps list of (period, value)
none Flat baseline

Seasonality types

type Period peak_offset unit
daily 24 hours Hour of day (0–23)
weekly 7 days Day of week (0=Mon … 6=Sun)
monthly 30 days Day of month (1–28)
yearly 365 days Day of year (0–364)

Multiple series

# Generate correlated series manually
import pandas as pd

dau = misata.generate_timeseries("Daily active users, growing 8% monthly", start_value=10_000, seed=1)
rev = misata.generate_timeseries("Revenue, growing 12% monthly with weekly seasonality", start_value=5_000, seed=2)

combined = dau[["date", "daily_active_users"]].merge(rev[["date", "revenue"]], on="date")
combined["arpu"] = combined["revenue"] / combined["daily_active_users"]