sequenceDiagram participant AAL as animate_activity_log participant GAD as generate_animation_df participant Layout as event_position_df (The Blueprint) participant Log as Event Log participant Scenario as scenario object AAL->>GAD: Calculate positions for all patients at all times GAD->>Log: Get patient P's event & resource_id at time T GAD->>Layout: Get base (x, y) & resource name for event alt Event is Resource Use GAD->>Scenario: Get total count for resource name GAD->>GAD: Calculate position based on base(x,y), resource_id, total count else Event is Queue GAD->>GAD: Calculate queue position offset from base(x,y) else Event is Arrival/Depart GAD->>GAD: Use base(x,y) directly end GAD-->>AAL: Return DataFrame with calculated positions
Chapter 3: Layout Configuration (event_position_df
)
In Chapter 2: Event Log, we learned about the event_log
, which is like the detailed script telling vidigi
what happened, when, and to whom. But just knowing the script isn’t enough to make a movie – you also need to know where the scenes take place! Where is the entrance? Where’s the waiting area? Where are the treatment rooms located on the screen?
That’s where the Layout Configuration, represented by the event_position_df
DataFrame, comes in. It’s the blueprint or map for your animation’s background.
Setting the Stage: Why We Need a Layout
Imagine you’re setting up a stage play. You need to decide:
- Where will actors enter? (Stage Left)
- Where is the waiting bench? (Center Stage)
- Where is the doctor’s office set piece? (Stage Right)
Without this plan, the actors wouldn’t know where to go, and the audience would be confused.
Similarly, vidigi
needs a map to know where to place the icons representing your patients or entities on the screen. The event_position_df
provides exactly this map. For every key step (event) in your process, it defines a specific (X, Y) coordinate on the animation screen.
What Does the Layout Blueprint Look Like?
The event_position_df
is typically a pandas
DataFrame – essentially a table. Each row in this table describes a specific location or stage in your process.
Here are the essential columns you need in this table:
event
: This column contains the exact name of the event from your Event Log that corresponds to this location. For example,'arrival'
,'start_wait'
,'treatment_begins'
. This is howvidigi
links the location map to the event script.x
: The horizontal coordinate (position from left to right) for this event’s base location on the screen.y
: The vertical coordinate (position from top to bottom) for this event’s base location on the screen.
Think of the (X, Y) coordinates as anchor points.
- For queues (like
'start_wait'
), patients will line up extending leftwards from this anchor point. - For resources (like
'treatment_begins'
), the available resource slots (e.g., treatment beds) will be placed near this anchor point, usually extending leftwards too. - For arrivals and departures, patients will appear or disappear at this exact anchor point.
You’ll often include these helpful optional columns too:
label
: A human-readable name for the stage (like"Arrival Area"
,"Waiting Room"
,"Treatment Bays"
).vidigi
can display these labels on the animation to make it easier to understand.resource
: This column links events associated with resource usage (like'treatment_begins'
) to the name of the resource capacity defined in an external object (often calledscenario
). For example, if you have an event'treatment_begins'
and yourscenario
object says you havescenario.n_nurses = 5
nurses, you would put'n_nurses'
in theresource
column for the'treatment_begins'
row. This tellsvidigi
how many resource slots to draw and manage for that step.
A Simple Blueprint Example
Let’s create a basic event_position_df
for the simple clinic example we’ve been using.
import pandas as pd
# Create the layout DataFrame
= {
layout_data 'event': ['arrival', 'start_wait', 'treatment_begins', 'depart', 'exit'], # Must match event names in the log!
'x': [50, 200, 200, 350, 350], # Horizontal positions
'y': [200, 250, 150, 150, 50], # Vertical positions
'label': ['Entrance', 'Waiting Area', 'Treatment Bays', 'Discharge', 'Exit Point'], # Human-friendly names
'resource': [None, None, 'n_cubicles', None, None] # Link 'treatment_begins' to the number of cubicles
}= pd.DataFrame(layout_data)
my_layout
print(my_layout)
-*Output:**
event x y label resource
0 arrival 50 200 Entrance None
1 start_wait 200 250 Waiting Area None
2 treatment_begins 200 150 Treatment Bays n_cubicles # This step uses 'n_cubicles' resources
3 depart 350 150 Discharge None
4 exit 350 50 Exit Point None
Let’s break this down:
- Row 0: Anyone recorded with the
event
‘arrival’ in the log will appear at coordinates (X=50, Y=200). This spot will be labelled “Entrance”. - Row 1: When a patient’s
event
becomes ‘start_wait’, they move towards (X=200, Y=250). If others are already waiting, they’ll queue up extending to the left from this point. This area is labelled “Waiting Area”. - Row 2: When a patient’s
event
is ‘treatment_begins’, they move towards (X=200, Y=150). Because this row has'n_cubicles'
in theresource
column,vidigi
knows this involves using a resource. It will look up how manyn_cubicles
are available (from thescenario
object you provide) and place the patient icon in the correct cubicle slot near (200, 150). This area is labelled “Treatment Bays”. - Row 3 & 4: Patients move to (350, 150) for ‘depart’ and finally vanish at the ‘exit’ point (350, 50).
-(Note: We added an ‘exit’ event here, which wasn’t in the Chapter 2 log but is often added automatically by vidigi
’s internal processing to ensure entities cleanly leave the screen).*
Using the Blueprint
You provide this event_position_df
(our my_layout
variable) directly to the main animate_activity_log
function:
# (Assuming my_event_log and scenario_details from Chapter 1 & 2 exist)
from vidigi.animation import animate_activity_log
# --- Our layout from above ---
# my_layout = pd.DataFrame(...)
# --- Pretend we have these ---
# my_event_log = pd.DataFrame(...) from Chapter 2
# class SimpleScenario: n_cubicles = 2 # From Chapter 1 layout example
# scenario_details = SimpleScenario()
# --- Call the animation function ---
= animate_activity_log(
my_animation =my_event_log,
event_log=my_layout, # <-- Pass the layout here!
event_position_df=scenario_details, # <-- Needed for resource counts ('n_cubicles')
scenario# ... other options like time_display_units, icon_size etc.
)
# my_animation.show()
When you run this, vidigi
uses my_layout
to determine where to draw everything. Patients arrive near (50, 200), queue leftwards from (200, 250), occupy one of the (in this case 2) treatment slots near (200, 150), and then depart via (350, 150) and (350, 50).
How vidigi
Reads the Blueprint (Under the Hood)
You don’t usually need to worry about the deep internals, but it helps to understand the basics. When animate_activity_log
needs to figure out the exact position of every patient at every snapshot in time, it uses a helper function called generate_animation_df
.
Here’s a simplified idea of what generate_animation_df
does:
- Get Base Position: For a patient
P
whose currentevent
is, say,'start_wait'
at timeT
, it looks up'start_wait'
in theevent_position_df
to find the base coordinates (e.g., X=200, Y=250). - Handle Queues: If the
event_type
is'queue'
, it checks how many other patients are also in the'start_wait'
state at timeT
. It calculates an offset (usually moving left and wrapping to new rows if needed) from the base (X, Y) based on the patient’s position in the queue. - Handle Resources: If the
event_type
is'resource_use'
(like'treatment_begins'
), it checks theresource
column inevent_position_df
(e.g.,'n_cubicles'
). It then asks thescenario
object, “How manyn_cubicles
are there?”. It also looks at the patient’s specificresource_id
from the event log (e.g., they are using cubicle1
). It then calculates the exact position for cubicle1
relative to the base (X, Y) for'treatment_begins'
. - Assign Final Position: It stores these calculated (X, Y) coordinates for patient
P
at timeT
.
This process repeats for every patient at every time snapshot.
Here’s a simplified diagram showing the interaction:
Tips for Setting Up Your Layout
- Match Event Names: The
event
names inevent_position_df
must exactly match theevent
names used in yourevent_log
. - Coordinates are Anchors: Remember (X, Y) are often the bottom-right anchor for queues and resources, which typically extend leftwards and potentially upwards in rows.
- Use
setup_mode
: When first creating your layout, passsetup_mode=True
toanimate_activity_log
. This will display grid lines and coordinate axes on the animation, making it much easier to figure out good X and Y values! - Iterate: Getting the layout perfect often takes a few tries. Run the animation, see how it looks, adjust the X/Y values in your DataFrame, and run it again.
Conclusion
The event_position_df
is your essential blueprint for the visual layout of your vidigi
animation. It’s a simple table (DataFrame) that tells vidigi
the base (X, Y) coordinates for each key event, allows you to add descriptive labels, and connects resource-using events to their capacities defined in a scenario
object. By carefully crafting this layout, you control where queues form, where resources are located, and how entities move across the screen, turning your raw event data into an understandable visual story.
Now that we understand the script (event_log
) and the stage map (event_position_df
), we need to look closer at the actors that use specific props – the resources. How does vidigi
handle knowing exactly which cubicle or which nurse a patient is using? That involves enhancing how we define and use resources in our simulation model, which is the topic of our next chapter.
Next up: Chapter 4: Simpy Resource Enhancement (CustomResource
, Store
, populate_store
)
Generated by AI Codebase Knowledge Builder