plots.plot_warm_up_diagnostic

plots.plot_warm_up_diagnostic(
    event_log,
    *,
    series='queue',
    event=None,
    first_event=None,
    second_event=None,
    method='welch',
    windows=(5, 10, 20),
    every_x_time_units=1,
    limit_duration=None,
    show_ensemble=True,
    show_runs=False,
    **col_kwargs,
)

Plot a Welch (or cumulative-mean) diagnostic for choosing warm_up=.

Ensemble-averages a per-run series across replications, then smooths it (see vidigi.analysis.welch_moving_average) so the point at which the curve stops drifting - the visual signal a modeller reads off to pick warm_up= for the other analysis functions in this module - is legible.

Parameters

Name Type Description Default
event_log pandas.DataFrame Long-format event log spanning one or more runs. required
series (queue, occupancy, duration) What per-run series to diagnose: - "queue": queue length at regular snapshots, from vidigi.analysis.queue_size_over_time. Requires event= naming the queue’s event. - "occupancy": resource occupancy at regular snapshots, from vidigi.analysis.resource_occupancy_over_time. Requires event= naming the resource step. - "duration": per-entity durations in arrival order, from vidigi.analysis.event_durations. Requires first_event= and second_event=. There is no time axis for this series - the x-axis is the entity’s position in arrival order, not simulated time, so a cutoff read off this plot is an entity count, not a time. Apply it via event_durations’s own warm_up= (a pairing is excluded by when it started, i.e. first_time) - note this is a genuinely different truncation rule from warm_up= on the other two series, which censor/clip a bout rather than exclude an atomic observation by its start time. See vidigi.analysis.event_durations’s warm_up parameter. "queue"
event str The queue’s or resource step’s event name. Required, and only used, for series="queue"/"occupancy". None
first_event str The two events to pair. Required, and only used, for series="duration". None
second_event str The two events to pair. Required, and only used, for series="duration". None
method (welch, cumulative, none) Smoothing procedure - see vidigi.analysis.welch_moving_average. "welch" overlays one curve per entry in windows; "cumulative" and "none" each draw a single curve and ignore windows. "cumulative" is the “time series inspection” technique the DES RAP book demonstrates (Heather et al., 2026 - https://pythonhealthdatascience.github.io/des_rap_book/pages/guide/output_analysis/length_warmup.html); "none" is the raw ensemble average with no smoothing at all - a further step beyond that, not itself what the DES RAP book shows. "none" is drawn the same way show_ensemble’s reference line would be, so show_ensemble is a no-op under it to avoid drawing the identical line twice. "welch"
windows sequence of int Window half-widths to overlay when method="welch". More smoothing (a larger window) gives a shorter usable curve - see vidigi.analysis.welch_moving_average. (5, 10, 20)
every_x_time_units float Snapshot granularity. Only used for series="queue"/"occupancy". 1
limit_duration float End of the window snapshots are taken over. None (default) uses the latest time seen anywhere in the trial. Only used for series="queue"/"occupancy". None
show_ensemble bool If True, also draws the raw (unsmoothed) ensemble-average series as a thin dotted line, for comparison against the smoothed curve(s). Ignored when method="none" - see method above. True
show_runs bool If True, also draws every individual replication’s own raw series - the same idea as the DES RAP book’s own per-replication traces (though those plot each run’s cumulative mean, matching method="cumulative" above, rather than the fully raw series drawn here), and useful with any method for seeing how much cross-replication spread the smoothing/pooling is hiding. Drawn at opacity=0.2 under one shared legend entry (“individual runs”) rather than one entry per run, since with a realistic replication count a full per-run legend would swamp the windows=/ method entries that are the actual point of this plot - unlike plot_queue_size/plot_resource_utilisation_over_time, which plot one series at a time and so can afford to label each run. Drawn at each run’s own full length, not truncated to the shortest run the way the summary trace(s) are. False
**col_kwargs dict Column-name keyword arguments forwarded to whichever underlying vidigi.analysis function series selects (queue_size_over_time/resource_occupancy_over_time/ event_durations) - e.g. run_col_name=, or match= for series="duration". {}

Returns

Name Type Description
plotly.graph_objects.Figure

Raises

Name Type Description
ValueError If series is not one of the three supported values; if the event= (for series="queue"/"occupancy") or first_event=/second_event= (for series="duration") the chosen series requires is missing, or an argument for a different series is given; or (series="occupancy") if event names a step that never occurred.

Notes

There is deliberately no automatic warm-up-length selector - see vidigi.analysis.welch_moving_average.

See Also

vidigi.analysis.welch_moving_average : The underlying smoothing procedure.

Examples

>>> plot_warm_up_diagnostic(trial.to_dataframe(), series="queue", event="waiting")
<plotly.graph_objs._figure.Figure>
Back to top