From SimEvents to SimPy: A Practical Guide to Discrete-Event Simulation in Python

From SimEvents to SimPy: A Practical Guide to Discrete-Event Simulation in Python

Also In the Series

Simul8 vs SimPy

FlexSim vs SimPy

Siemens Plant Simulation vs SimPy

Simio vs SimPy

AnyLogic vs SimPy

Arena vs SimPy

Salabim vs SimPy

Introduction

If you're thinking of moving discrete-event simulations from MATLAB’s SimEvents® toolbox to Python’s SimPy library then you're in the right place.

SimPy is a free, open-source framework that offers flexibility, integration with the rich Python ecosystem, and relief from licence fees – all while covering the core needs of queuing and process modelling.

This article maps SimEvents building blocks (entities, queues, servers, etc.) to their SimPy equivalents, highlights why many are making the switch, compares workflows, and provides a simple supply chain example in both environments. We’ll also discuss potential challenges in migrating, so you can transition smoothly.

Why Switch from SimEvents to SimPy

Open-Source Freedom and Cost-Effectiveness

SimEvents is a proprietary add-on to MATLAB, which means organisations must pay for licences to use it. By contrast, SimPy is an MIT-licensed open-source project – free for anyone to use or modify. One engineer I spoke with who recreated their SimEvents models in SimPy called it a “game-changer” – not just to avoid SimEvents’ licence costs, but for the flexibility and freedom to build exactly what they needed in Python. In short, SimPy helps you escape toolboxes and do more with less budget.

Python’s Flexibility and Ecosystem

SimPy runs in pure Python, so your simulations can seamlessly integrate with libraries like NumPy and pandas for data analysis, SciPy for random distributions, or even machine learning frameworks. Python’s popularity in scientific computing means a rich ecosystem for data analysis, visualisation, and integration with larger applications.

For example, you can run a SimPy model and then use pandas or NumPy to analyse results, or embed the simulation in a web application – possibilities that are harder to achieve with a closed environment. In MATLAB, you might export data to workspace and use MATLAB toolboxes; in Python, these capabilities are part of the same environment, giving you one coherent workflow.

Community and Support

While SimEvents is backed by MathWorks support, SimPy enjoys a robust community of users and contributors. Its documentation is thorough, and many examples, forums, and tutorials are available. The community-driven development means new features and fixes are driven by user needs, and you’re not tied to a vendor’s release cycle. Moreover, skills in Python and SimPy are widely transferable and valued across industries, whereas SimEvents expertise is more niche.

Transparency and Customisation

In SimEvents, you typically build models by connecting predefined blocks. This is user-friendly but can be limiting if your scenario doesn’t fit the mould. SimPy, being code-based, lets you model custom logic with fine-grained control. You define how entities behave, how processes work, what events occur, and how resources are managed in plain Python code.

This transparency means you know exactly what the simulation is doing – there’s no “black box” block, since you can inspect or modify every aspect of the logic. It’s easy to prototype ideas and adjust the model on the fly, using version control to track changes (another perk of text-based models).

Continuous simulation aside: It’s worth noting that SimPy focuses on discrete-event simulation (DES) and is not a replacement for Simulink in modelling continuous dynamics or control systems. SimPy shines for process-centric simulations (like warehouses, supply chains, rail networks), but if your model has significant continuous-time components or requires Simulink’s control design features, you may need to co-simulate or stick with Simulink for that part. For pure DES problems, however, Python and SimPy open up a world of possibilities in customisation and scalability that proprietary tools often struggle to match.

Mapping SimEvents Concepts to SimPy

If you’re used to SimEvents, you’ll find that the core concepts carry over to SimPy – they just appear in code form rather than drag-and-drop blocks. Here’s a mapping of SimEvents building blocks to their SimPy equivalents:

Article content

Despite differences in implementation, both SimEvents and SimPy are fundamentally doing discrete-event scheduling. A queue-server pair in SimEvents will have an equivalent SimPy representation using a resource and process logic. This conceptual alignment makes it straightforward for SimEvents users to map their knowledge onto SimPy’s constructs once the initial syntax gap is overcome.

Workflow: SimEvents vs SimPy

Model Building

The biggest change is moving from a graphical model to a code-based model. In SimEvents, you assemble a block diagram – dragging blocks for sources, queues, servers, and so on, then setting their parameters via dialogues. For example, you might connect an Entity Generator → Queue → Server → Terminator to model a basic queueing system.

In SimPy, you write a Python script that defines your processes and resources. There’s no GUI – the model lives in your code. This means you have to explicitly program the logic, but the flip side is that this code is flexible. You can use loops to create multiple servers, easily change logic for different scenarios (if-conditions instead of needing different blocks), and version-control your model definitions.

Running Simulations

In SimEvents, you typically hit “Run” in Simulink, and the simulation clock starts ticking, processing events until you stop or reach a defined stop time. You might use Simulink’s dashboard or scopes to visualise results during the run, or let the simulation run to completion and then examine output statistics (SimEvents blocks can output metrics like queue length, or you use the MATLAB workspace to analyse logs).

In SimPy, you start the simulation by calling env.run(until=time) or until a certain event. The simulation runs as fast as possible by default (since it’s not tied to real-time unless you program it to). There’s no built-in animation, so typically you collect data in lists or logs within your process code (e.g. record wait times, count departures) for analysis after the run. If you want live feedback, you can insert print() statements or use a plotting library to update a chart during the run, but this requires a bit of custom coding.

SimPy deliberately does not include GUI or visualisation tools out-of-the-box – it focuses purely on simulation logic and leaves visualisation to the user or external libraries. This is a key workflow difference: SimEvents provides an integrated modelling-and-analysis environment, whereas with SimPy you will typically run the simulation and then use Python tools for analysis/visualisation.

Integration and Iteration

In MATLAB/SimEvents, integrating with other MATLAB code (for pre- or post-processing) is straightforward since it’s all in the MATLAB environment. With SimPy, integration means you can directly use Python’s vast toolkit. Need to change input distributions? Use NumPy’s random module. Need to optimise parameters? Hook your SimPy model into an optimisation loop using libraries like SciPy or even simple Python scripts. Need to post-process results? Put them into a pandas DataFrame and utilise its analysis capabilities.

The workflow tends to be: edit code → run simulation → analyse in Python (often in a Jupyter notebook or script). This can feel more manual at first compared to SimEvents’ GUI, but it becomes highly efficient for batch runs and automated experiments. For example, running 100 simulation replications with varying parameters is trivial to script in Python, whereas in SimEvents it might require the Simulink GUI or additional MATLAB scripting to loop runs.

Learning Curve

If you are not already comfortable with Python, there is an upfront learning curve. SimEvents users are used to thinking in terms of blocks and flows; transitioning to code means you’ll think in terms of functions and events. The good news is that SimPy code is quite readable – it’s designed to be straightforward and “Pythonic.”

A SimPy process reads like a description of the entity’s journey. Once you get the hang of yield statements and SimPy’s API (which is small: basically Environment, process functions, and Resource/Store classes), building models becomes second nature. Many SimEvents concepts like queues, servers, and attributes translate almost one-to-one into SimPy logic, as we saw above.

Example: A Simple Supply Chain Queue in SimEvents vs SimPy

To make this concrete, let’s consider a supply chain scenario: say a warehouse where orders arrive, queue up, get processed by a single server (e.g. a packing station), and then depart. We’ll outline how one might implement this in SimEvents, and then show equivalent code in SimPy.

In MATLAB SimEvents: You would create a Simulink model and add SimEvents blocks as follows:

  • Entity Generator: to create order entities (e.g. with an exponential inter-arrival time to simulate random orders). You set the Interarrival time parameter of this block (perhaps to a MATLAB expression like exprnd(mean_IAT) for randomness).
  • Entity Queue (FIFO): to hold orders if the packing station is busy. This block will queue entities in first-in-first-out order by default
  • Entity Server: to represent the packing station processing an order. You set its Service time (could be a fixed value or a distribution, e.g. unifrnd(minService, maxService)). The server will seize an entity, delay it for the service duration, then release it.
  • Entity Terminator: to remove the entity from the simulation after processing (representing the order leaving the system).

These blocks are connected in series: Generator → Queue → Server → Terminator, meaning each order entity flows through that pipeline. During simulation, SimEvents will generate orders at random times, queue them if the server is busy, process them one by one, and count them out. You could attach output ports or use scopes to monitor metrics like queue length or server utilisation. (In SimEvents, many performance metrics can be obtained by attaching probe blocks or enabling statistics on queue/server blocks.)

In Python with SimPy: We achieve the same logic with a few simple components of code. Here’s a snippet illustrating this model:

import simpy
import random

def order(env, order_id, server):
    arrival = env.now
    print(f"Order {order_id} arrives at time {arrival:.2f}")
    # Request the server (this will queue if server is busy)

    with server.request() as req:
        yield req  # wait until the request is granted
        wait = env.now - arrival
        print(f"Order {order_id} starts processing after waiting {wait:.2f}")
        # Simulate processing delay
        service_time = random.uniform(2, 5)  # e.g. 2-5 time units uniformly
        yield env.timeout(service_time)
        print(f"Order {order_id} departs at time {env.now:.2f}")

def order_generator(env, rate, server):
    """Generate orders with a given arrival rate (orders per unit time)."""
    order_id = 0
    while True:
        # Wait for next arrival
        interarrival = random.expovariate(rate)  # e.g. exponential IAT
        yield env.timeout(interarrival)
        # Create a new order process
        env.process(order(env, order_id, server))
        order_id += 1

# Set up the environment and resources
env = simpy.Environment()
server = simpy.Resource(env, capacity=1)  # one packing station

# Start the order arrival process (e.g. rate = 0.2 orders/unit time for mean IAT=5)
env.process(order_generator(env, rate=0.2, server=server))

# Run the simulation for a certain period
env.run(until=50)        

In this SimPy code:

  • We define an order process to model what happens to each order: it arrives, requests the server resource (queuing if necessary), then experiences a processing delay, and finally leaves. We use env.now to get the current simulation time (SimEvents analog: the simulation clock). The with server.request() as req: yield req line is where the order may wait in queue – SimPy handles the queue internally when the resource is busy.
  • We define an order_generator process that creates new orders indefinitely. It yields an env.timeout(interarrival) between each creation, using an exponential distribution for interarrival times. Each time, it starts a new order process via env.process(...).
  • We set up the Environment and a Resource named server with capacity 1 (single server). We start the generator and then run the simulation for 50 time units.

The print statements will show the chronology of events (arrivals, service start, departures) and can be replaced or augmented to collect statistics (e.g. recording each order’s waiting time in a list). After simulation, you might use pandas to analyse all recorded wait times and service times, for instance.

Despite superficial differences, the SimEvents model and the SimPy model are doing the same thing. In SimEvents, the logic is implicit in block connections and parameters; in SimPy, it’s spelled out in code. This example is intentionally simple – more complex supply chain simulations (with multiple queues, parallel servers, or resource pools) can be built in a similar fashion by extending the code. For instance, adding a second processing step would just mean another function or another yield for a second resource, whereas in SimEvents you’d drag in another Server block and connect it.

Challenges and Pitfalls When Migrating

Switching from a GUI-driven tool to code and from MATLAB to Python can present a few challenges. Being aware of these will help you avoid common pitfalls:

  • No Built-in GUI or Visualisation: As noted, SimPy doesn’t have a graphical interface or built-in animation of entities moving through a flow
  • Learning the SimPy API and Python Syntax: If you’re new to Python, you’ll need to get comfortable with the language (indentation, syntax, data structures) and the concept of generator functions with yield. SimPy’s paradigm is process-oriented simulation using Python coroutines
  • Recreating Analysis and Statistics Collection: SimEvents blocks often come with ready-made stats (e.g. queue block can output queue length, server block can output utilisation or number of entities departed). When you move to SimPy, you’ll be responsible for capturing those metrics yourself. This typically means initializing counters or lists and updating them in your process logic. For example, to measure waiting times, you’d record the time just before an entity yields for a resource and just after it gets the resource. It’s extra work, but Python’s data handling makes it easy to store and analyse this data (and you can structure your code to collect metrics in a reusable way). Be careful to collect enough data for your needs (and reset or separate data between simulation runs). The lack of built-in statistics is by design – SimPy’s philosophy is “bring your own tools” for analysis
  • Feature Gaps and Workarounds: Some advanced features of SimEvents might not have direct counterparts in SimPy. For instance, SimEvents supports hybrid simulations with Simulink (mixing continuous and discrete systems), which SimPy cannot do natively. If your SimEvents model interacts with continuous-time components, you’ll need to find a workaround (perhaps approximate the continuous part, or run a separate continuous simulation and feed events into SimPy). Another example: SimEvents has the concept of entity attributes that travel with each entity (like a struct of data). In SimPy, you implement this by attaching attributes to your process (via parameters or by using objects to represent entities). It’s doable (and quite flexible – you can use full-fledged Python classes), but not a one-click translation. Additionally, SimEvents provides a library of pre-built blocks (e.g. for routing, gating, etc.); in SimPy you code the logic for routing (e.g. simple if/else to decide which resource an entity goes to). This offers freedom to implement any rule, but you need to ensure you haven’t missed any logic that SimEvents would handle (like releasing resources properly – though context managers in SimPy help prevent mistakes by automatically releasing on exit of the with block).
  • Performance Considerations: Both SimEvents and SimPy are capable of handling a large number of events, but performance tuning might differ. SimEvents benefits from MATLAB’s optimisations under the hood, whereas SimPy runs in Python (which is single-threaded by default). For most moderate-sized simulations, SimPy is fast enough, but extremely large models might require careful optimisation or considering alternatives (like using PyPy, or splitting workload). Python’s speed can often be improved by using numpy for heavy computations or writing custom extensions, whereas in SimEvents you might rely on MATLAB vectorisation. Keep an eye on performance when porting complex models – ensure that the level of detail in the simulation is truly needed (this is a general DES best practice, not just for SimPy).

Despite these challenges, you may find that the benefits far outweigh the initial hurdles. Once the model is up and running in SimPy, you gain a level of control and extensibility that makes further development and experimentation much easier.

Next Steps

Switching from MATLAB SimEvents to SimPy is a rewarding move for those seeking more flexibility, integration, and cost savings in discrete-event simulation. We’ve seen that the fundamental building blocks - whether called entities and servers or processes and resources - map closely between the two environments.

The workflow shifts from a GUI-centric process to a coding approach, but this unlocks Python’s powerful ecosystem for analytics and scaling. While there are some challenges to overcome (lack of GUI, need to code up metrics), the transition is very achievable for anyone with an intermediate understanding of simulation concepts and a willingness to learn some Python.

If you’re ready to explore SimPy further and want a deeper dive into best practices, examples, and tips for success, we’ve got something for you. Download my free guide to simulation in Python with SimPy for a comprehensive walkthrough of building DES models in Python - from basic queuing systems to complex supply chain networks. It’s packed with code samples and conversion tips for SimEvents users. Download the Free Guide Here and take your simulation skills to the next level in an open-source world!

To view or add a comment, sign in

More articles by Harry Munro

Others also viewed

Explore content categories