Data and code from: The complex swarming dynamics of malaria mosquitoes emerge from simple minimally-interactive behavioral rules
Data files
Aug 21, 2026 version files 240.16 MB
-
Data_S1.zip
12.56 MB
-
Data_S2.zip
98.40 MB
-
README.md
32.29 KB
-
Table_S1.xlsx
14.14 KB
-
Video_S1.mp4
21.14 MB
-
Video_S2.mp4
12.75 MB
-
Video_S3.mp4
94.11 MB
-
Video_S4.mp4
1.14 MB
Abstract
Many insect species exhibit swarming behavior, often to reproduce. In such mating swarms, tens to thousands of male insects congregate near a visual ground marker, and females join for in-flight mating. Despite its importance for reproduction and survival, the biology and physics of insect swarming remains poorly understood. In particular, it is unclear whether swarming insects follow similar highly interactive behavioral rules as flocking birds and schooling fish. In flocking and schooling, neighbors exhibit strong mutual attraction, alignment, and collision avoidance. Here, we combined high-speed videography-based experiments with agent-based modeling to study the mating swarms of male malaria mosquitoes at sunset. By video-tracking the three-dimensional flight kinematics of swarming mosquitoes, we revealed that these animals exhibited highly stereotypic flight behaviors. Swarming mosquitoes tend to fly straight across the swarm center, and perform sharp saccadic turns at the swarm boundaries. Based on these observations, we derived parsimonious behavioral rules for swarming: for flight path alignment and swarm centering, mosquitoes rely on visual cues of the ground marker and sunset; and interactions between conspecifics only occur at very short distances, to avoid collisions. Using agent-based modelling and systematic simulations, we showed that this small set of behavioral rules is both necessary and sufficient to reproduce the complex emergent flight kinematics and coordinated patterns observed in real swarms. This suggests that, unlike highly interactive bird flocking and fish schooling, insect swarming may be primarily driven by responses to environmental cues instead of mutual interactions.
Dataset DOI: 10.5061/dryad.69p8cz9bw
Associated publication
Cribellier A., Poda B.S., Dabiré R.K., Diabaté A., Roux O., Muijres F.T. The complex swarming dynamics of malaria mosquitoes emerge from simple minimally-interactive behavioral rules. Submitted to PLOS Computational Biology.
Corresponding author: Antoine Cribellier, Experimental Zoology Group, Wageningen University, Wageningen, The Netherlands (antoine.cribellier@wur.nl).
Description of the data and file structure
Aim and scope of the dataset
Male malaria mosquitoes (Anopheles coluzzii) aggregate at dusk in station-keeping swarms above a visually contrasting ground object (the swarm marker), where females come to mate. This deposit contains the two datasets that underlie the study: (i) the measured three-dimensional flight tracks of An. coluzzii males swarming above a 40 x 40 cm black marker in a laboratory arena under simulated-sunset conditions (Data S1), and (ii) the simulated three-dimensional flight tracks produced by the agent-based model (ABM) that reproduces the observed swarming dynamics from a minimal set of individual behavioral rules (Data S2).
The central hypothesis tested with these data is that swarm-level structure and dynamics do not require rich mosquito-to-mosquito interactions, but emerge from two simple, mostly non-social rules: (1) individuals perform saccadic turns triggered by the apparent size of the marker in their visual field (the marker viewing angle, α), and (2) individuals avoid collisions with nearby conspecifics at short range. Data S1 provides the empirical flight kinematics and the empirical turn-angle distributions used to parameterise the model; Data S2 provides the model output for the two key model variants (with and without the collision-avoidance rule) that are compared against the measurements in the manuscript.
Overview of the deposited files
| File | Type | Content |
|---|---|---|
Data_S1.zip |
ZIP archive containing one MATLAB .mat file |
Measured 3D flight tracks of swarming An. coluzzii males (6 experiments) |
Data_S2.zip |
ZIP archive containing two MATLAB .mat files |
Simulated 3D flight tracks from the agent-based model (2 model variants x 20 replicates) |
Table_S1.xlsx |
Excel spreadsheet | Complete list of agent-based model parameters, their symbols, names in the MATLAB code, descriptions, default values, units, and sources |
Video_S1.mp4 |
MPEG-4 video | Swarming flight of an initiator mosquito (measured) |
Video_S2.mp4 |
MPEG-4 video | Flight kinematics of a single swarming mosquito (measured) |
Video_S3.mp4 |
MPEG-4 video | Swarming flight of multiple mosquitoes (measured) |
Video_S4.mp4 |
MPEG-4 video | Swarming flight of ten simulated mosquitoes (agent-based model, with collision avoidance) |
Conventions shared by all .mat files
File format. All .mat files are MATLAB v7.3 files, i.e., HDF5 containers. They open natively in MATLAB (load('filename.mat')) and can also be read in Python with h5py, or in R with rhdf5. They cannot be read with scipy.io.loadmat, which supports only MATLAB v5-v7.2 files. Note that HDF5 stores MATLAB arrays in transposed order, so an N x 1 MATLAB column vector appears as shape (N, 1) in h5py but character arrays appear as arrays of uint16 character codes that must be converted back to text.
Top-level structure. Each .mat file contains a single MATLAB structure named all_data with two branches:
all_data.cst— constants that apply to the whole dataset (frame rate; for Data S2, all model parameters).all_data.exp— one sub-structure per experiment (Data S1) or per simulation replicate (Data S2), each holdingmetadataandtracks.
Coordinate system. All positions are in metres, in the world reference frame defined in Figure 1 of the manuscript: the origin is at the centre of the swarm marker on the ground, z points vertically upwards, y points horizontally towards the simulated sun / sunset horizon, and x is horizontal and parallel to the sunset horizon, completing a right-handed frame. Velocities are in m s⁻¹ in the same frame. Angles are in degrees unless stated otherwise.
Time base. Tracks were sampled at 50 Hz (all_data.cst.fps = 50). frames is the video frame index and time = frames / fps is the elapsed time in seconds from the start of the recording session (Data S1) or from the start of the simulation (Data S2).
Missing values. Missing samples are encoded as NaN. In Data S1, NaN marks frames within an individual's tracked interval in which the mosquito was not detected in enough camera views to be reconstructed in 3D (typically short gaps between stitched track segments). Data S2 contains no missing values.
Data S1 (Data_S1.zip): measured flight tracks of swarming Anopheles coluzzii males
The archive contains a single file:
all_data-exp1-coluzzii_males-selection_swarming.mat — 3D flight tracks of male An. coluzzii mosquitoes swarming above a 40 x 40 cm black marker in a climate-controlled laboratory arena (2.0 x 0.7 x 1.8 m) under simulated-sunset lighting. Trajectories were reconstructed from synchronised multi-camera video as described in the Materials and Methods of the manuscript. As the file name indicates, the deposit contains a selection of the recorded swarming episodes: the swarm onset, plus fixed time windows sampling the build-up, plateau and decay phases of each swarm (see dynamic below).
Structure
all_data
├── cst
│ └── fps 50 (Hz), frame rate of all tracks
└── exp
├── exp20221007_183000 one field per experiment (6 in total)
│ ├── metadata
│ │ ├── species 'coluzzii'
│ │ ├── sex 'male'
│ │ ├── age age of the mosquitoes at the time of the experiment (days)
│ │ ├── nb number of mosquitoes released in the arena
│ │ ├── date date and time of the experiment (MATLAB datetime)
│ │ └── marker x, y, z: position of the marker centre in the raw
│ │ tracking frame of the arena (m); tracks are already
│ │ expressed relative to this point
│ └── tracks
│ └── object
│ ├── obj1 one field per tracked individual
│ ├── obj2
│ └── ...
├── exp20221010_183000
└── ...
Experiment fields are named expYYYYMMDD_HHMMSS after the date and start time of the recording session (all sessions started at 18:30 local time).
Per-experiment metadata
| Experiment | Mosquito age (days) | Mosquitoes released | Tracked individuals |
|---|---|---|---|
exp20221007_183000 |
5 | 30 | 162 |
exp20221010_183000 |
6 | 30 | 137 |
exp20221012_183000 |
7 | 30 | 182 |
exp20221028_183000 |
6 | 50 | 137 |
exp20221030_183000 |
6 | 50 | 209 |
exp20221103_183000 |
7 | 50 | 111 |
| Total | 938 |
Together the six experiments contain 938 individual trajectories, 1,816 raw track segments and 709,920 valid 3D position samples (≈ 3.9 h of tracked flight at 50 Hz).
Variables inside each obj<n>
Each obj<n> is one tracked individual mosquito over one continuous tracked interval. objN (together with the experiment name) is the unique identifier of a trajectory in this dataset. The time-series fields below are all N x 1 column vectors of the same length N, aligned sample by sample.
| Variable | Type / size | Units | Description |
|---|---|---|---|
frames |
N x 1 double |
— | Video frame index, counted from the start of the recording session. Consecutive (step 1) over the tracked interval. |
time |
N x 1 double |
s | Elapsed time since the start of the recording session, time = frames / 50. |
x |
N x 1 double |
m | Position along the horizontal axis parallel to the sunset horizon. NaN where the mosquito was not reconstructed. |
y |
N x 1 double |
m | Position along the horizontal axis pointing towards the simulated sun. |
z |
N x 1 double |
m | Height above the plane of the swarm marker. |
x_vel |
N x 1 double |
m s⁻¹ | Velocity component along x, obtained by numerical differentiation of the (smoothed) position. |
y_vel |
N x 1 double |
m s⁻¹ | Velocity component along y. |
z_vel |
N x 1 double |
m s⁻¹ | Velocity component along z. |
track_id |
N x 1 double |
— | Identifier of the raw track segment that produced each sample. Individuals whose trajectory was interrupted and re-acquired are represented by several segments stitched into one obj<n>; track_id records which segment each sample came from. NaN in the gaps between segments. |
Scalars inside each obj<n>.scalars (constant for that individual)
| Variable | Type / size | Description |
|---|---|---|
mosqID |
1 x 1 double |
Index of the individual within its swarm phase (see dynamic_id). Not globally unique — use the experiment name plus obj<n> as the primary key. |
sex |
char | Sex of the mosquito; 'male' throughout. |
dynamic |
char | Phase of the swarm during which the individual was tracked: 'increasing' (swarm forming), 'top' (swarm at its plateau), 'decreasing' (swarm dispersing). |
dynamic_id |
1 x 1 double |
Numeric code of the swarm phase, with a finer split than dynamic: 1 = swarm initiator (the first male to start swarming; dynamic = 'increasing'), 2 = build-up phase (dynamic = 'increasing'), 3 = plateau, a window of up to 150 s starting 900 s after the start of the session (dynamic = 'top'), 4 = decay, the last ~150 s of the session (dynamic = 'decreasing'). |
was_initiator |
1 x 1 logical |
true for the single initiator of each experiment (6 individuals in total, one per experiment), false otherwise. |
num_recording |
1 x 1 double |
Index of the video recording, within the session, that contains this trajectory (each session was captured as several successive recordings). |
start_recording |
1 x 1 logical |
true if the individual was already being tracked at the first frame of that recording, i.e. the trajectory is truncated at its start. |
trackID |
M x 1 double |
List of the M raw track segments stitched into this individual; the values are those found in the track_id time series. |
trackID_frames |
M x 1 double |
First video frame of each of those M segments. |
trackID_counts |
M x 1 double |
Number of samples in each of those M segments. |
Derived quantities. The kinematic and visual variables analysed in the manuscript — accelerations, jerk, flight speed, angular speed, cylindrical coordinates (r, θ), the marker viewing angles α_x and α_y, saccade detection and saccade properties, swarm-level metrics and heat maps — are not stored in this file. They are recomputed from the raw positions above by the analysis code (see Code/software); main.m and gen_all_data_tracks.m list them explicitly.
Data S2 (Data_S2.zip): simulated flight tracks from the agent-based model
The archive contains two files, one per model variant. Both were produced with the same behavioral rules and the same parameter values (Table S1); they differ only in whether the short-range collision-avoidance rule was active:
| File | Collision avoidance |
|---|---|
all_data-abm-along_y_rand-null-threshold-any-alpha_x_percent-threshold_alpha_x.mat |
off (cst.with_collision_avoidance = 0) |
all_data-abm-along_y_rand-null-threshold-any-alpha_x_percent-threshold_alpha_x-avoid_collisions.mat |
on (cst.with_collision_avoidance = 1, cst.min_distance = 0.006 m) |
The file names encode the model configuration as <saccade_type>-<acceleration_type>-<start_saccade_type>-<start_saccade_combination_type>-<start_saccade_field_names>-<threshold flags>; each of these components is a field of all_data.cst and is defined in Table_S1.xlsx.
Each file contains 20 independent replicate simulations of 10 agents flying for 120 s at 50 Hz (6,000 frames), i.e. 200 simulated trajectories and 1,200,000 position samples per file.
Structure
all_data
├── cst all model parameters (see Table_S1.xlsx)
└── exp
├── rep1 one field per replicate simulation (20 in total)
│ ├── metadata
│ │ ├── species 'boid'
│ │ └── sex 'male'
│ └── tracks
│ └── object
│ ├── boid1 one field per simulated agent (10 per replicate)
│ ├── boid2
│ └── ...
├── rep2
└── ...
all_data.cst: model parameters
Table_S1.xlsx is the authoritative, annotated description of these parameters: it gives, for every parameter, the symbol used in the manuscript, the name used in the MATLAB code (which is the field name used here), a description, the default value, the units, the source or justification, the submodel in which it is used, and whether it is stochastic. Users should consult Table_S1.xlsx for the definition of every field of all_data.cst. For orientation, the fields present are:
| Field | Value in this deposit | Meaning |
|---|---|---|
fps, dt |
50 Hz, 0.02 s | Simulation frame rate and time step |
init_vel |
0.5 m s⁻¹ | Constant flight speed during straight flight |
boid_type |
'swarming_saccades' |
Agent behavioural model used |
sim_name |
see file names above | Full configuration string of the simulation |
saccade_type |
'along_y_rand' |
Rule defining the direction of a saccadic turn |
acceleration_type |
'null' |
No additional acceleration field applied |
start_saccade_type |
'threshold' |
Saccades are triggered by threshold crossing |
start_saccade_field_names |
{'alpha_x_percent'} |
Variable used as the saccade trigger: the relative deviation of the marker viewing angle from its maximum, R_α = (α_max − α)/α_max × 100 % |
start_saccade_combination_type |
'any' |
How multiple trigger criteria are combined |
with_threshold_alpha_x |
1 | Absolute bounds on α are also enforced |
alpha_x_threshold_min, alpha_x_threshold_max |
24°, 55° | Lower and upper bounds on the marker viewing angle that trigger a saccade |
alpha_x_percent_threshold |
4.5 % | Threshold on R_α that triggers a saccade |
use_prev_max_alpha_x |
0 | α_max is taken as the viewing angle at the swarm centre at the agent's current height (not the agent's own previous maximum) |
vel_after_saccade |
'start' |
Speed is reset to init_vel after each saccade |
with_collision_avoidance |
0 or 1 | Collision-avoidance rule off / on (see table above) |
min_distance |
0.006 m | Inter-agent distance below which avoidance is triggered (present only in the collision-avoidance file) |
marker |
x_center = y_center = z_center = 0; x_width = y_width = 0.4 m |
Geometry and position of the swarm marker; x, y, z, r, theta, order give its corner coordinates for plotting |
bounds |
x ∈ [−1.45, 0.55] m, y ∈ [−0.35, 0.35] m, z ∈ [0, 1.8] m | Virtual arena, matching the dimensions of the experimental arena; bounce_bounds = 1 means agents reflect off the walls |
limits |
— | Plotting limits per variable, used by the figure code |
dist |
— | Empirical distributions from which stochastic model quantities are drawn (see below) |
show_vel |
0 | Display flag used by the simulation's live plotting; no effect on the data |
all_data.cst.dist holds the empirical distributions measured in Data S1 and used to draw stochastic quantities in the model. dist.linear contains the fitted/interpolated distributions actually sampled by the model — angle_v_pks_theta_after_linear (azimuth of flight direction after a saccadic turn, degrees) and angle_v_pks_phi_after_linear (climb angle after a saccadic turn, degrees), both shown in Figure S2, plus r_acc. dist.raw contains the corresponding raw measured distributions of a broader set of kinematic variables (flight speed vel, acceleration acc, angular speed angle_v, the velocity and acceleration components x_vel…z_acc, phi_vel, phi_acc, saccade speed angle_v_pks_vel, and the cumulative trigger variables cumsum_alpha_x_percent, cumsum_time_pks, cumsum_distance_pks), retained for reference.
Variables inside each boid<n>
Each boid<n> is one simulated agent over the full 120 s simulation. All time-series fields are 6000 x 1 column vectors with no missing values.
| Variable | Type / size | Units | Description |
|---|---|---|---|
frames |
6000 x 1 double |
— | Simulation frame index, 1 to 6000. |
time |
6000 x 1 double |
s | Elapsed simulation time, time = frames / 50, 0 to 119.98 s. |
x, y, z |
6000 x 1 double |
m | Agent position in the marker-centred world frame (same convention as Data S1). |
x_vel, y_vel, z_vel |
6000 x 1 double |
m s⁻¹ | Agent velocity components. The speed is held at init_vel = 0.5 m s⁻¹ between saccades. |
alpha_x |
6000 x 1 double |
degrees | Marker viewing angle α: the angle subtended at the agent's position by the two edges of the marker along the x axis. This is the visual cue that drives the saccade rule. |
max_alpha_x |
6000 x 1 double |
degrees | Reference maximum viewing angle α_max: the value α would take directly above the marker centre (x = y = 0) at the agent's current height. The saccade trigger is the relative deviation R_α = (α_max − α)/α_max × 100 %. |
state |
1 x 1 double |
— | Behavioural state of the agent; a single state (1) is implemented in this model version, so the field is constant. |
saccades.frames |
K x 1 double |
— | Frame indices at which the agent performed a saccadic turn (K varies per agent; median 185, range 1-212, in the collision-avoidance simulations). The first entry is the initial frame, at which the flight direction is set. |
Scalars inside each boid<n>.scalars
| Variable | Type / size | Units | Description |
|---|---|---|---|
init_r |
1 x 1 double |
m | Radial distance from the z axis at which the agent was initialised (drawn uniformly). |
init_theta |
1 x 1 double |
rad | Azimuth at which the agent was initialised (drawn uniformly in [−π, π]). Agents start flying towards the arena centre. |
init_z |
1 x 1 double |
m | Height at which the agent was initialised (drawn uniformly within the arena bounds). |
is_living |
1 x 1 logical |
— | true while the agent is inside the arena bounds and active. All agents remain active for the full simulation in both deposited files. |
num_replicate |
1 x 1 double |
— | Index of the replicate simulation (1-20), matching the rep<n> field name. |
Table_S1.xlsx
Single sheet ("Table S1") listing all 24 parameters of the agent-based model, one per row, with the columns: Parameter name, Symbol, Name in Matlab code, Description, Default value, Units, Range / values explored, Source / Justification, Used in submodel(s) and Stochastic?. The model description follows a simplified form of the ODD protocol (Grimm et al., 2020, JASSS 23(2):7). This table is the reference documentation for every field of all_data.cst in the Data S2 files and for every parameter of the simulation code.
Videos
All videos are MPEG-4 (H.264) renderings generated from the datasets above with gen_video_tracks.m and gen_video_tracks_vel_acc.m.
Video_S1.mp4: swarming flight of an initiator mosquito. Three-dimensional and two-dimensional views of the flight of the initiator — the first An. coluzzii male to start swarming — recorded above a 40 x 40 cm black swarm marker. Source data: the individual with was_initiator = true in Data S1.
Video_S2.mp4: flight kinematics of a single swarming mosquito. Three-dimensional position, flight speed, acceleration and angular speed of one swarming An. coluzzii male recorded above the same marker. This individual was swarming together with conspecifics. Source data: Data S1.
Video_S3.mp4: swarming flight of multiple mosquitoes. Three-dimensional and two-dimensional views of the simultaneous flight of multiple An. coluzzii males recorded above the same marker. Source data: Data S1.
Video_S4.mp4: swarming flight of ten simulated mosquitoes. Three-dimensional and two-dimensional views of ten agents simulated with the agent-based model including collision avoidance, above a virtual 40 x 40 cm marker. Source data: one replicate of all_data-abm-along_y_rand-null-threshold-any-alpha_x_percent-threshold_alpha_x-avoid_collisions.mat in Data S2.
Code/software
Code is hosted on Zenodo, in the compressed file Code_S1.zip.
Reading the data. The .mat files are MATLAB v7.3 (HDF5). In MATLAB (R2022b or later recommended): load('all_data-exp1-coluzzii_males-selection_swarming.mat') returns the structure all_data. In Python, use h5py (not scipy.io.loadmat), remembering that HDF5 transposes MATLAB arrays and stores MATLAB character arrays as uint16 character codes:
import h5py, numpy as np
f = h5py.File('all_data-exp1-coluzzii_males-selection_swarming.mat', 'r')
track = f['all_data/exp/exp20221007_183000/tracks/object/obj1']
x, y, z = (np.array(track[k]).ravel() for k in ('x', 'y', 'z'))
t = np.array(track['time']).ravel()
Analysis and model code (S1 Code). All original MATLAB code written to run the agent-based model, analyse both datasets and generate the figures of the manuscript is provided as S1 Code with the article. It was developed and run in MATLAB R2022b. Its main entry points are:
_Code/main.m— full analysis pipeline for a dataset: loads anall_datafile, computes the derived kinematic and visual variables (gen_all_data_tracks.m), the swarm-level metrics (gen_all_data_swarms.m) and the spatial heat maps (gen_all_data_heatmaps.m), and produces the corresponding figures (gen_all_fig_swarms.m,gen_all_fig_heatmaps.m). Setexp_num = 1to analyse Data S1, orexp_num = 0together with the appropriatesim_nameto analyse one of the Data S2 files._Code/Agent based model/main_all_abm.m— runs the agent-based model for the listed configurations (20 replicates x 10 agents x 120 s each) and writes theall_data-abm-*.matfiles deposited as Data S2.main_abm.mruns a single simulation, andboids/swarming_saccades/update_boids.mimplements the behavioural rules themselves (saccade triggering, turn-angle sampling, collision avoidance)._Code/get_alpha_xy.mand_Code/Agent based model/get_alpha_x.m— compute the marker viewing angles α_x and α_y from a 3D position, assuming coordinates centred on the marker._Code/gen_video_tracks.m,_Code/gen_video_tracks_vel_acc.m— generate Videos S1-S4.
To reproduce the analysis: unzip the data, place the .mat file in the _Data folder, set data_path at the top of main.m to that location, and run main.m; figures are written to the _Figures folder.
Note that main.m also calls a small number of general-purpose helper functions from the authors' shared MATLAB library (e.g. derivative, save_figures, gen_all_data_split_tracks, gen_all_data_tracks_subset, angle_btw_vectors), which are not part of S1 Code; these can be obtained from the corresponding author.
