prep.generate_animation_df
prep.generate_animation_df(
full_entity_df,
event_position_df,
wrap_queues_at=20,
wrap_resources_at=20,
step_snapshot_max=60,
step_snapshot_max_overrides=None,
gap_between_entities=10,
gap_between_resources=10,
gap_between_resource_rows=30,
gap_between_queue_rows=30,
queue_direction='left',
time_col_name='time',
entity_col_name='entity_id',
event_type_col_name='event_type',
event_col_name='event',
resource_col_name='resource_id',
debug_mode=False,
custom_entity_icon_list=None,
include_fun_emojis=False,
save_intermediate_outputs=False,
minimize_output_df=_UNSET,
run_col_name='auto',
step_snapshot_limit_gauges=False,
gauge_segments=10,
gauge_max_override=None,
step_snapshot_reveal_pop_in=False,
spawn_in_from_arrival=True,
)Generate a DataFrame for animation purposes by adding position information to entity data.
This function takes entity event data and adds positional information for visualization, handling both queuing and resource use events.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| full_entity_df | pd.DataFrame | Output of reshape_for_animation(), containing entity event data. | required |
| event_position_df | pd.DataFrame | DataFrame with columns ‘event’, ‘x’, and ‘y’, specifying initial positions for each event type. | required |
| wrap_queues_at | int | Number of entities in a queue before wrapping to a new row (default is 20). | 20 |
| wrap_resources_at | int | Number of resources to show before wrapping to a new row (default is 20). | 20 |
| step_snapshot_max | int | Maximum number of patients to show in each snapshot (default is 60). Acts as the fallback for any event not named in step_snapshot_max_overrides. Must match the value passed to reshape_for_animations. |
60 |
| step_snapshot_max_overrides | dict | A mapping of event name to a per-event step_snapshot_max, used here to place the + n more overflow label. Must match what was passed to reshape_for_animations, which is where the row-shedding actually happens. Default None. |
None |
| gap_between_entities | int | Horizontal spacing between entities in pixels (default is 10). | 10 |
| gap_between_resources | int | Horizontal spacing between resources in pixels (default is 10). | 10 |
| gap_between_queue_rows | int | Vertical spacing between rows in pixels (default is 30). | 30 |
| gap_between_resource_rows | int | Vertical spacing between rows in pixels (default is 30). | 30 |
| queue_direction | (left, right) | Which way queues (and rows of resources) build out from their anchor. “left” (the default, and byte-identical to previous versions) stacks entities up to the left of the anchor x, so the anchor is the front of the queue / bottom-right corner. “right” mirrors this - the anchor becomes the bottom-left corner and the queue extends rightwards, which suits entity emojis that face right. Overridden per event by a direction column on event_position_df where one is present. |
"left" |
| time_col_name | str | Name of the column in event_log that contains the timestamp of each event. Timestamps should represent the number of time units since the simulation began. |
"time" |
| entity_col_name | str | Name of the column in event_log that contains the unique identifier for each entity (e.g., “entity_id”, “entity”, “patient”, “patient_id”, “customer”, “ID”). |
"entity_id" |
| event_type_col_name | str | Name of the column in event_log that specifies the category of the event. Supported event types include ‘arrival_departure’, ‘resource_use’, ‘resource_use_end’, and ‘queue’. |
"event_type" |
| resource_col_name | str | Name of the column for the resource identifier. Used for ‘resource_use’ events. | "resource_id" |
| event_col_name | str | Name of the column in event_log that specifies the actual event that occurred. |
"event" |
| debug_mode | bool | If True, print debug information during processing (default is False). | False |
| custom_entity_icon_list | list | If provided, will be used as the list for entity icons. Once the end of the list is reached, it will loop back around to the beginning (so e.g. if a list of 8 icons is provided, entities 1 to 8 will use the provided emoji list, and then entity 9 will use the same icon as entity 1, and so on.) | None |
| include_fun_emojis | bool | If True, include the more ‘fun’ emojis, such as Santa Claus. Ignored if a custom entity icon list is passed. | False |
| save_intermediate_outputs | bool | str | None | For debugging purposes. If True or a string, output a series of csvs with intermediate transformed dataframes. If a string is passed, this will be interpreted as the path to prefix the dataframes with. Default is False. | False |
| minimize_output_df | .. deprecated:: This parameter has never had any effect and is ignored. All columns are retained regardless of the value passed. Passing it emits a DeprecationWarning. Column dropping is planned for vidigi 3.0. | _UNSET |
|
| run_col_name | str or None | Name of the column identifying which simulation run (replication) each row belongs to, used to reject data containing more than one replication. Default is “auto”, which looks for a column named (case-insensitively) one of ‘run’, ‘run_number’, ‘replication’, ‘rep’ or ‘run_id’. Pass an explicit column name to override the search, or None to disable the check. |
'auto' |
| step_snapshot_limit_gauges | If True, replaces the text ‘+ x more’ with a gauge. The upper limit of the gauge is set by the maximum queue length observed across the simulation. | False |
|
| step_snapshot_reveal_pop_in | bool | If True, an entity that re-appears as an individually-drawn icon after being hidden by step_snapshot_max “pops in” at its queue position instead of visibly flying in from the top-left of the plot - the same top-left fly-in a brand new point always gets from Plotly when it first enters a frame’s text trace. Works by inserting one invisible phantom row (a zero-width space) for that entity at the snapshot immediately before the reveal, so the point already exists - just invisibly - by the time the real icon appears; it then only needs a content swap, not a position transition, so there is nothing left for Plotly to animate as movement. A genuine new arrival is never affected - only entities that were already present but suppressed by the cap (see hidden_run_before on reshape_for_animations’s output) get a phantom, so arrivals still fly in, which is usually the clearer visual cue for “joining the system”. The + N more overflow row is also unaffected - it already has its own stable-identity fix for this same problem. Costs exactly one extra row per reveal (not per entity hidden, and not per snapshot an entity spends hidden). Requires reshape_for_animations’s hidden_run_before column; a full_entity_df built by hand without it makes this a silent no-op rather than an error, the same way a missing opacity column is handled elsewhere in the pipeline. Hover text is not blanked on phantom rows - since they are invisible and zero-width, hovering one precisely is unlikely, and doing so would only show accurate (if one-snapshot-early) data for the entity about to appear. An entity_annotation_by label, which unlike hover is always visibly rendered, is blanked on phantom rows by generate_animation. The default False is a verified no-op - output is byte-identical to omitting the argument. This default is planned to change to True at the next major version (3.0), since “pop in” is closer to correct than “fly in” for a reveal; pass it explicitly either way to pin your animation’s behaviour across that release. |
False |
| spawn_in_from_arrival | bool | When True (the default), a genuinely new entity glides into the animation from the event_position_df anchor named "arrival" instead of flying in from the plot’s top-left corner (the default Plotly behaviour for any point new to a frame’s text trace - see step_snapshot_reveal_pop_in). This is the arrival-side mirror of how the synthetic depart step makes an exit land at a chosen anchor. Pass False to restore the pre-2.0.0 top-left fly-in. Works by inserting, for each such entity, a visible row at the arrival anchor one snapshot before its first real position (so Plotly animates it moving from there) plus one invisible phantom row (a zero-width space) the snapshot before that (so the spawn row itself has nothing to fly in from). The synthetic rows land on existing snapshot slots, so no new frames are created. Only entities that arrive at least two snapshots after the animation window opens are affected - an entity already present when the window opens has no earlier slot to spawn from and keeps the top-left fly-in. An entity that arrives straight into an over-cap queue (represented by the + N more overflow row rather than drawn individually) is likewise unaffected until it emerges, at which point it is a reveal handled by step_snapshot_reveal_pop_in, not an arrival. Requires an event_position_df row with event == "arrival" and reshape_for_animations’s hidden_run_before column; without either this is a silent no-op, so a layout that never positioned "arrival" is unaffected. Independent of step_snapshot_reveal_pop_in - both may be set. Express backend only (the go backend always behaves as False). |
True |
Returns
| Name | Type | Description |
|---|---|---|
| pd.DataFrame | A DataFrame with added columns for x and y positions, and icons for each entity. |
Notes
- This function positions a single replication only. Data containing more than one run is rejected with a
ValueError. The run column survivesreshape_for_animations, so a multi-replication log is caught here as well as there. - The function handles both queuing and resource use events differently.
- It assigns unique icons to entities for visualization.
- Queues can be wrapped to multiple rows if they exceed a specified length.
- The function adds a visual indicator for additional entities when exceeding the snapshot limit.
- If an event is ever an entity’s most-recently-logged step at a rendered snapshot but has no matching row in
event_position_df, that entity is silently dropped from the frame instead of drawn (it reappears once a positioned event takes over). This function warns automatically when that happens - it only checks events actually selected for rendering, so an event that is always simultaneous with (and so superseded by) its successor, and therefore never rendered, does not trigger it.
TODO
- Write a test to ensure that no entity ID appears in multiple places at a single time unit.