import simpy
import pandas as pd
import random
from vidigi.animation import animate_activity_log
from vidigi.utils import EventPosition, create_event_position_dfStep 2. Set up simulation parameters
A very simple example with one server - avoiding the vidigi logger class
If you would prefer to implement your own approach to logging, you can avoid the use of the EventLogger class, and instead manually build your event logs, as shown in this example.
Step 1. Import required libraries
vidigisimpy- for simulation model (or see the Ciw functions and examples elsewhere in this documentation)random- for generating random arrivalspandas- for managing dataframes
# Simple simulation parameters
SIM_DURATION = 50
NUM_SERVERS = 1
ARRIVAL_RATE = 1.0
SERVICE_TIME = 3.0Step 3. Write model code with event logs
Create a simple simulation model using simpy.
On the left is a basic simpy model. If not familiar check out simpy documentation for intro to simpy.
On the right is how we incorporate vidigi. Information for vidigi collected in a list of dictionaries which we will convert into a dataframe. You need a arrival_departure event.
Simple SimPy Model
def patient_generator(env, server, event_log):
"""Generate patients arriving at the shop"""
patient_id = 0
while True:
patient_id += 1
# Start the patient process
env.process(patient_process(env, patient_id, server, event_log))
# Wait for next arrival
yield env.timeout(random.expovariate(ARRIVAL_RATE))
def patient_process(env, patient_id, server, event_log):
"""Process a single patient through the system"""
# Request server
with server.request() as request:
yield request
# Service time
service_duration = random.expovariate(1.0/SERVICE_TIME)
yield env.timeout(service_duration)
# Run the simulation
def run_simulation():
env = simpy.Environment()
server = simpy.Resource(env, capacity=NUM_SERVERS)
event_log = []
# Start patient generator
env.process(patient_generator(env, server, event_log))
# Run simulation
env.run(until=SIM_DURATION)With Vidigi Modifications
def patient_generator(env, server, event_log):
"""Generate patients arriving at the shop"""
patient_id = 0
while True:
patient_id += 1
# Log arrival
event_log.append({
'patient': patient_id,
'event': 'arrival',
'event_type': 'arrival_departure',
'time': env.now
})
# Start the patient process
env.process(patient_process(env, patient_id, server, event_log))
# Wait for next arrival
yield env.timeout(random.expovariate(ARRIVAL_RATE))
def patient_process(env, patient_id, server, event_log):
"""Process a single patient through the system"""
# Log start of queue wait
event_log.append({
'patient': patient_id,
'event': 'queue_wait_begins',
'event_type': 'queue',
'time': env.now
})
# Request server
with server.request() as request:
yield request
# Log service start
event_log.append({
'patient': patient_id,
'event': 'service_begins',
'event_type': 'resource_use',
'time': env.now,
'resource_id': 1
})
# Service time
service_duration = random.expovariate(1.0/SERVICE_TIME)
yield env.timeout(service_duration)
# Log service end
event_log.append({
'patient': patient_id,
'event': 'service_complete',
'event_type': 'resource_use_end',
'time': env.now,
'resource_id': 1
})
# Log departure
event_log.append({
'patient': patient_id,
'event': 'depart',
'event_type': 'arrival_departure',
'time': env.now
})
# Run the simulation
def run_simulation():
env = simpy.Environment()
server = simpy.Resource(env, capacity=NUM_SERVERS)
event_log = []
# Start patient generator
env.process(patient_generator(env, server, event_log))
# Run simulation
env.run(until=SIM_DURATION)
return pd.DataFrame(event_log) Step 4. Run simulation
# Run simulation and get event log
event_log_df = run_simulation()
print(f"Generated {len(event_log_df)} events")Generated 161 events
Step 5. Create event positions dataframe
# Define positions for animation
event_positions = create_event_position_df([
EventPosition(event='arrival', x=0, y=350, label="Entrance"),
EventPosition(event='queue_wait_begins', x=250, y=250, label="Queue"),
EventPosition(event='service_begins', x=250, y=150, resource='server', label="Being Served"),
EventPosition(event='depart', x=250, y=50, label="Exit")
])Step 6. Create animation
Explaining:
plotly_heightandplotly_widthoverride_x_maxandoverride_y_maxsetup_modeevery_x_time_units
# Create animation
animate_activity_log(
event_log=event_log_df,
event_position_df=event_positions,
entity_col_name="patient",
every_x_time_units=1,
plotly_height=600,
override_x_max=360,
limit_duration=SIM_DURATION
)