### Initialize NetLogo Link and Load Model
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Establishes a connection to NetLogo, loads a specified model, and executes the initial 'setup' command. Requires NetLogo to be installed and accessible.
```python
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("white")
sns.set_context("talk")
import pynetlogo
netlogo = pynetlogo.NetLogoLink(
gui=True,
)
netlogo.load_model("./models/Wolf Sheep Predation_v6.nlogo")
netlogo.command("setup")
```
--------------------------------
### Import SALib Sampling and Analysis Modules
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Imports necessary modules from SALib for Sobol sensitivity analysis. Ensure SALib is installed.
```python
from SALib.sample import sobol as sobol_sample
from SALib.analyze import sobol
```
--------------------------------
### Start Java Virtual Machine (JVM)
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Initialize the Java Virtual Machine with a specified JVM path and the collected JARs in the classpath. This is essential before interacting with Java objects.
```python
jvm_path = "/Users/jhkwakkel/Downloads/jdk-19.0.2.jdk/Contents/MacOS/libjli.dylib"
jpype.startJVM(jvm_path, classpath=jars)
```
--------------------------------
### Setting up Parallel Execution Environment with %%px
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
The `%%px` magic command executes notebook cells on all engines. This example includes necessary imports and model loading for parallel NetLogo simulations.
```python
%%px
import os
os.chdir(cwd) # pushed to all workers via direct_View.push
import pynetlogo
import pandas as pd
netlogo = pynetlogo.NetLogoLink(gui=False)
netlogo.load_model('./models/Wolf Sheep Predation_v6.nlogo')
```
--------------------------------
### Instantiate NetLogoLink
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Create an instance of the NetLogoLink class to establish a connection with NetLogo. Note: This example demonstrates a NameError due to an undefined variable 'gui'.
```python
link = NetLogoLink(jpype.java.lang.Boolean(False), jpype.java.lang.Boolean(thd))
```
--------------------------------
### Run NetLogo Commands and Report Values
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/Untitled.ipynb
Executes NetLogo commands such as 'setup' and 'go', and reports the count of sheep. It also demonstrates reporting a value repeatedly until a condition is met.
```python
netlogo.command("setup")
print(netlogo.report("count sheep"))
netlogo.report_while("count sheep", "count sheep >= 100", max_seconds=5)
```
--------------------------------
### Import Libraries for NetLogo-SALib Interaction
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Imports necessary Python libraries for data manipulation, plotting, and pyNetLogo integration. Ensure these libraries are installed.
```python
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import pyNetLogo
```
--------------------------------
### Initialize ipyparallel Cluster
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Initializes and starts an ipyparallel cluster with a specified number of engines. This is required for parallel execution.
```python
import ipyparallel as ipp
cluster = ipp.Cluster(n=4)
cluster.start_cluster_sync()
```
--------------------------------
### Find NetLogo Home Directory (macOS)
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Locate the NetLogo installation directory on macOS using PyNetLogo's utility function. This is a prerequisite for finding necessary JAR files.
```python
netlogo_home = pynetlogo.core.find_netlogo_mac()
netlogo_home
```
--------------------------------
### Run Simulation Ticks and Plot Agent Energy
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Executes the NetLogo simulation for a specified number of ticks (100 in this example) using either `command` or `repeat_command`. It also prepares to return agent energy values for histogram plotting.
```python
# We can use either of the following commands to run for 100 ticks:
netlogo.command("repeat 100 [go]")
# netlogo.repeat_command('go', 100)
```
--------------------------------
### Example Usage of plot_sobol_indices
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Demonstrates how to use the plot_sobol_indices function with sample data. Sets the figure size and displays the plot. Requires seaborn for styling.
```python
sns.set_style("whitegrid")
fig = plot_sobol_indices(Si, criterion="ST", threshold=0.005)
fig.set_size_inches(7, 7)
plt.show()
```
--------------------------------
### Get Direct View of Engines
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Obtains a direct view of all engines in the ipyparallel cluster, allowing for direct interaction with each engine.
```python
direct_view = rc[:]
```
--------------------------------
### Export Patch Data and Update NetLogo Environment
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Export patch data to an Excel file using Pandas and update the NetLogo environment with new patch values using `patch_set`. This example inverts the 'countdown' values.
```python
countdown_df.to_excel("countdown.xlsx")
netlogo.patch_set("countdown", countdown_df.max() - countdown_df)
```
--------------------------------
### Get NetLogoLink Java Class
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Retrieve the Java class for NetLogo communication using JPype. This class is used to establish a link with NetLogo.
```python
jpype.JClass("netLogoLink.NetLogoLink")
```
--------------------------------
### JPype startJVM Signature and Docstring
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Displays the signature and documentation for the `jpype.startJVM` function, detailing its parameters, keyword arguments, and potential exceptions. Useful for understanding how to configure JVM startup.
```python
?jpype.startJVM
```
--------------------------------
### Initialize NetLogo Instance
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Initializes a NetLogo instance. This is the first step before interacting with any NetLogo models.
```python
netlogo = NetLogo(model_path='model.xml')
```
--------------------------------
### Setting up Parallel Environment with %%px
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
The `%%px` magic command executes a notebook cell on all parallel engines. It's used here to set up the necessary imports and load the NetLogo model on each engine.
```python
%%px
import os
os.chdir(cwd)
import pyNetLogo
import pandas as pd
netlogo = pyNetLogo.NetLogoLink(gui=False)
netlogo.load_model('./models/Wolf Sheep Predation_v6.nlogo')
```
--------------------------------
### Run Sequential Simulations and Collect Results
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Iterates through each parameter set generated by SALib, sets NetLogo global variables, runs the model for 100 ticks using repeat_report, and calculates the mean counts of sheep and wolves. Also tracks elapsed runtime.
```python
import time
t0 = time.time()
for run in range(param_values.shape[0]):
# Set the input parameters
for i, name in enumerate(problem["names"]):
if name == "random-seed":
# The NetLogo random seed requires a different syntax
netlogo.command("random-seed {}".format(param_values[run, i]))
else:
# Otherwise, assume the input parameters are global variables
netlogo.command("set {0} {1}".format(name, param_values[run, i]))
netlogo.command("setup")
# Run for 100 ticks and return the number of sheep and wolf agents at each time step
counts = netlogo.repeat_report(["count sheep", "count wolves"], 100)
# For each run, save the mean value of the agent counts over time
results.loc[run, "Avg. sheep"] = np.mean(counts["count sheep"])
results.loc[run, "Avg. wolves"] = np.mean(counts["count wolves"])
elapsed = time.time() - t0 # Elapsed runtime in seconds
```
--------------------------------
### Create NetLogo Link JAR
Source: https://github.com/quaquel/pynetlogo/blob/master/src/pynetlogo/java/readme.md
Use this command to create a NetLogo link JAR file. Ensure the NetLogo JAR for the specific version is on the build path.
```bash
jar cfv netlogolink63.jar *
```
--------------------------------
### Setting up Direct View for Engines
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Creates a direct view to access all engines in the ipyparallel cluster, enabling parallel execution of tasks.
```python
direct_view = client[:]
```
--------------------------------
### Initialize NetLogo Link and Load Model
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Initializes a pyNetLogo Link object in headless mode and loads the specified NetLogo model. Ensure the model file path is correct.
```python
netlogo = pynetlogo.NetLogoLink(gui=False)
netlogo.load_model("./models/Wolf Sheep Predation_v6.nlogo")
```
--------------------------------
### Initialize and Load NetLogo Model
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/Untitled.ipynb
Initializes a PyNetLogo link to a NetLogo instance without the GUI and loads a specified NetLogo model file.
```python
import os
netlogo = pyNetLogo.NetLogoLink(gui=False)
model_file = os.path.join(
netlogo.netlogo_home, "models/Sample Models/Biology/Wolf Sheep Predation.nlogo"
)
netlogo.load_model(model_file)
```
--------------------------------
### Generating Sobol Samples with SALib
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Generates experimental design samples using the Saltelli sampler from SALib for a Sobol analysis. The sample size is determined by the problem definition and a base sample number 'n'.
```python
n = 1000
param_values = saltelli.sample(problem, n, calc_second_order=True)
```
--------------------------------
### Import Libraries for Sensitivity Analysis
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Imports necessary libraries for numerical operations, plotting, and sensitivity analysis with SALib and pyNetLogo.
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("white")
sns.set_context("talk")
import pynetlogo
# Import the sampling and analysis modules for a Sobol variance-based
# sensitivity analysis
from SALib.sample import sobol as sobolsample
from SALib.analyze import sobol
```
--------------------------------
### Import PyNetLogo
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Import the PyNetLogo library for NetLogo integration.
```python
import pynetlogo
```
--------------------------------
### Run NetLogo Simulations Sequentially
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Iterates through each parameter set, sets NetLogo global variables, runs the model, and collects average agent counts. Records the elapsed time for the entire process.
```python
import time
t0 = time.time()
for run in range(param_values.shape[0]):
# Set the input parameters
for i, name in enumerate(problem["names"]):
if name == "random-seed":
# The NetLogo random seed requires a different syntax
netlogo.command("random-seed {}".format(param_values[run, i]))
else:
# Otherwise, assume the input parameters are global variables
netlogo.command("set {0} {1}".format(name, param_values[run, i]))
netlogo.command("setup")
# Run for 100 ticks and return the number of sheep and wolf agents at each time step
counts = netlogo.repeat_report(["count sheep", "count wolves"], 100, include_t0=False)
# For each run, save the mean value of the agent counts over time
results.loc[run, "Avg. sheep"] = counts["count sheep"].values.mean()
results.loc[run, "Avg. wolves"] = counts["count wolves"].values.mean()
elapsed = time.time() - t0 # Elapsed runtime in seconds
```
--------------------------------
### Initialize Results DataFrame
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Creates an empty Pandas DataFrame to store the simulation results, with columns for average sheep and wolf counts.
```python
results = pd.DataFrame(columns=["Avg. sheep", "Avg. wolves"])
```
--------------------------------
### Generate Sobol Samples
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Generates samples for Sobol sensitivity analysis using the defined problem and a baseline sample size 'n'. Set calc_second_order=True for second-order indices. The sample size will be n*(2p+2).
```python
n = 1024
param_values = sobol_sample.sample(problem, n, calc_second_order=True)
```
--------------------------------
### Running Simulations with Load Balanced View
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Utilize `rc.load_balanced_view()` and `lview.map_sync` to distribute the `simulation` function across experiments. This method efficiently handles simulations of varying durations.
```python
lview = rc.load_balanced_view()
results = pd.DataFrame(lview.map_sync(simulation, param_values))
```
--------------------------------
### command(netlogo_command: str)
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
Execute the supplied command in NetLogo.
```APIDOC
#### command(netlogo_command: str)
Execute the supplied command in NetLogo.
* **Parameters:**
**netlogo_command** (*str*) – Valid NetLogo command
* **Raises:**
[**NetLogoException**](#pynetlogo.core.NetLogoException) – If a LogoException or CompilerException is raised by NetLogo
```
--------------------------------
### Run NetLogo Command from Python
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/Untitled.ipynb
Executes a NetLogo command string. Ensure the command is valid NetLogo syntax.
```python
netlogo.link.sourceFromString(command, True)
```
--------------------------------
### Running Simulations with Load Balanced View
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Utilizes `client.load_balanced_view()` and `map_sync` to distribute the `simulation` function across multiple engines. This method efficiently handles tasks with varying execution times.
```python
lview = client.load_balanced_view()
results = pd.DataFrame(lview.map_sync(simulation, param_values))
```
--------------------------------
### load_model(path: str)
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
Load a NetLogo model.
```APIDOC
#### load_model(path: str)
Load a NetLogo model.
* **Parameters:**
**path** (*str*) – Path to the NetLogo model
* **Raises:**
* **FileNotFoundError** – in case path does not exist
* [**NetLogoException**](#pynetlogo.core.NetLogoException) – In case of a NetLogo exception
```
--------------------------------
### Set Headless Mode for JVM
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Configure the Java Virtual Machine to run in headless mode, which is useful for environments without a graphical display. This prevents AWT-related errors.
```python
jpype.java.lang.System.setProperty("java.awt.headless", "true")
```
--------------------------------
### Visualize Output Distributions with Histograms
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Generates histograms to visualize the distribution of model outputs for each outcome. Requires matplotlib and pandas.
```python
fig, ax = plt.subplots(1, len(results.columns), sharey=True)
for i, n in enumerate(results.columns):
ax[i].hist(results[n], 20)
ax[i].set_xlabel(n)
ax[0].set_ylabel("Counts")
fig.set_size_inches(10, 4)
fig.subplots_adjust(wspace=0.1)
plt.show()
```
--------------------------------
### repeat_command(netlogo_command: str, reps: int)
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
Execute the supplied command in NetLogo a given number of times.
```APIDOC
#### repeat_command(netlogo_command: str, reps: int)
Execute the supplied command in NetLogo a given number of times.
* **Parameters:**
* **netlogo_command** (*str*) – Valid NetLogo command
* **reps** (*int*) – Number of repetitions for which to repeat commands
* **Raises:**
[**NetLogoException**](#pynetlogo.core.NetLogoException) – If a LogoException or CompilerException is raised by NetLogo
```
--------------------------------
### Generate Sobol Sample Values
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Generates sample values using SALib's Sobol sampler for a given problem definition and baseline sample size. This is used for variance-based sensitivity analysis.
```python
n = 1024
param_values = sobolsample.sample(problem, n, calc_second_order=True)
```
--------------------------------
### Parallel NetLogo Simulation with Multiprocessing Pool
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_multiprocessing.ipynb
Initializes and runs NetLogo simulations in parallel using `multiprocessing.Pool`. Ensure the NetLogo model file path is correct and the model is compatible.
```python
from multiprocessing import Pool
import os
import pandas as pd
import pyNetLogo
from SALib.sample import saltelli
def initializer(modelfile):
"""initialize a subprocess
Parameters
----------
modelfile : str
"""
# we need to set the instantiated netlogo
# link as a global so run_simulation can
# use it
global netlogo
netlogo = pyNetLogo.NetLogoLink(gui=False)
netlogo.load_model(modelfile)
def run_simulation(experiment):
"""run a netlogo model
Parameters
----------
experiments : dict
"""
# Set the input parameters
for key, value in experiment.items():
if key == "random-seed":
# The NetLogo random seed requires a different syntax
netlogo.command("random-seed {}".format(value))
else:
# Otherwise, assume the input parameters are global variables
netlogo.command("set {0} {1}".format(key, value))
netlogo.command("setup")
# Run for 100 ticks and return the number of sheep and
# wolf agents at each time step
counts = netlogo.repeat_report(["count sheep", "count wolves"], 100)
results = pd.Series(
[counts["count sheep"].values.mean(), counts["count wolves"].values.mean()],
index=["Avg. sheep", "Avg. wolves"],
)
return results
modelfile = os.path.abspath("./models/Wolf Sheep Predation_v6.nlogo")
problem = {
"num_vars": 6,
"names": [
"random-seed",
"grass-regrowth-time",
"sheep-gain-from-food",
"wolf-gain-from-food",
"sheep-reproduce",
"wolf-reproduce",
],
"bounds": [
[1, 100000],
[20.0, 40.0],
[2.0, 8.0],
[16.0, 32.0],
[2.0, 8.0],
[2.0, 8.0],
],
}
n = 10
param_values = saltelli.sample(problem, n, calc_second_order=True)
# cast the param_values to a dataframe to
# include the column labels
experiments = pd.DataFrame(param_values, columns=problem["names"])
with Pool(initializer=initializer, initargs=(modelfile,)) as executor:
results = []
for entry in executor.map(run_simulation, experiments.to_dict("records")):
results.append(entry)
results = pd.DataFrame(results)
```
--------------------------------
### Handle NetLogoException in Python
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/Untitled.ipynb
Demonstrates how to catch and handle a NetLogoException, which is raised for undefined variables or errors during NetLogo execution. The exception message provides details about the error.
```python
raise NetLogoException(str(ex))
```
--------------------------------
### Displaying First 5 Rows of Results
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
View the initial rows of the results DataFrame to quickly inspect the output of the parallel simulations.
```python
results.head(5)
```
--------------------------------
### Importing Libraries for Analysis
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Imports essential Python libraries for data manipulation, plotting, and interaction with NetLogo.
```python
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import pynetlogo
```
--------------------------------
### Advanced Visualization for Second-Order Interactions
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Sets up plotting functions for visualizing second-order interactions between inputs using SALib's Sobol indices. This snippet includes helper functions for normalization and plotting circles, and a filter function for selecting data based on criteria.
```python
%matplotlib inline
import itertools
from math import pi
def normalize(x, xmin, xmax):
return (x - xmin) / (xmax - xmin)
def plot_circles(ax, locs, names, max_s, stats, smax, smin, fc, ec, lw, zorder):
s = np.asarray([stats[name] for name in names])
s = 0.01 + max_s * np.sqrt(normalize(s, smin, smax))
fill = True
for loc, name, si in zip(locs, names, s):
if fc == "w":
fill = False
else:
ec = "none"
x = np.cos(loc)
y = np.sin(loc)
circle = plt.Circle(
(x, y),
radius=si,
ec=ec,
fc=fc,
transform=ax.transData._b,
zorder=zorder,
lw=lw,
fill=True,
)
ax.add_artist(circle)
def filter(sobol_indices, names, locs, criterion, threshold):
if criterion in ["ST", "S1", "S2"]:
data = sobol_indices[criterion]
data = np.abs(data)
data = data.flatten() # flatten in case of S2
# TODO:: remove nans
```
--------------------------------
### Connect to ipyparallel Cluster
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Connects to the running ipyparallel cluster by creating a client and ensuring all engines are available.
```python
rc = cluster.connect_client_sync()
rc.wait_for_engines(n=4)
rc.ids
```
--------------------------------
### Pushing Variables to Engines with IPyparallel
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Use `direct_view.push` to make notebook variables available on all parallel engines. Ensure the `block=True` argument for synchronous execution.
```python
direct_view.push(dict(problem=problem), block=True)
```
--------------------------------
### Save Results to CSV
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Saves the collected simulation results to a CSV file named 'Sobol_sequential.csv'.
```python
results.to_csv("Sobol_sequential.csv")
```
--------------------------------
### Connecting to ipyparallel Cluster
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Instantiates an ipyparallel client to connect to a running ipcluster controller and its engines. Verifies the number of available engines.
```python
import ipyparallel
client = ipyparallel.Client()
client.ids
```
--------------------------------
### Import JPype
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Import the JPype library to enable Java-Python interoperability.
```python
import jpype
```
--------------------------------
### Import NetLogoLink Class
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Import the NetLogoLink class directly from the Java package for easier use in Python.
```python
from netLogoLink import NetLogoLink
```
--------------------------------
### Find NetLogo JARs
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Identify the required Java Archive (JAR) files for NetLogo integration. This function requires the NetLogo home directory.
```python
jars = pynetlogo.core.find_jars(netlogo_home)
```
--------------------------------
### kill_workspace()
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
Close NetLogo and shut down the JVM.
```APIDOC
#### kill_workspace()
Close NetLogo and shut down the JVM.
```
--------------------------------
### Pushing Variables to Engines
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Use `direct_view.push` to make notebook variables available on the parallel engines. This is useful for sharing simulation parameters or configurations.
```python
direct_view.push(dict(problem=problem))
```
--------------------------------
### Read Results from CSV
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Loads simulation results from the 'Sobol_sequential.csv' file back into a Pandas DataFrame.
```python
results = pd.read_csv("Sobol_sequential.csv", header=0, index_col=0)
```
--------------------------------
### Display Elapsed Runtime
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Prints the total time taken to complete all sequential simulations.
```python
elapsed
```
--------------------------------
### Python 2/3 Compatibility Imports
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Ensures compatibility with both Python 2 and Python 3 by conditionally importing `izip`.
```python
# Ensuring compliance of code with both python2 and python3
from __future__ import division, print_function
try:
from itertools import izip as zip
except ImportError: # will be 3.x series
pass
```
--------------------------------
### Define Problem for SALib
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Defines the problem dictionary for SALib, specifying the number of variables, their names, and their bounds for sensitivity analysis.
```python
problem = {
"num_vars": 6,
"names": [
"random-seed",
"grass-regrowth-time",
"sheep-gain-from-food",
"wolf-gain-from-food",
"sheep-reproduce",
"wolf-reproduce",
],
"bounds": [
[1, 100000],
[20.0, 40.0],
[2.0, 8.0],
[16.0, 32.0],
[2.0, 8.0],
[2.0, 8.0],
],
}
```
--------------------------------
### Calculate Sobol Indices
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Calculates first-order (S1), second-order (S2), and total (ST) Sobol indices to estimate input contributions to output variance and input interactions. Requires SALib.
```python
Si = sobol.analyze(
problem,
results["Avg. sheep"].values,
calc_second_order=True,
print_to_console=False,
)
```
--------------------------------
### report(netlogo_reporter: str)
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
Return values from a NetLogo reporter.
```APIDOC
#### report(netlogo_reporter: str)
Return values from a NetLogo reporter.
Any reporter (command which returns a value) that can be called
in the NetLogo Command Center can be called with this method.
* **Parameters:**
**netlogo_reporter** (*str*) – Valid NetLogo reporter
* **Raises:**
[**NetLogoException**](#pynetlogo.core.NetLogoException) – If a LogoException or CompilerException is raised by NetLogo
```
--------------------------------
### Visualize Output Distributions
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Generates histograms for each outcome variable (Avg. sheep, Avg. wolves) to visualize their distributions. Uses Seaborn for styling.
```python
sns.set_style("white")
sns.set_context("talk")
fig, ax = plt.subplots(1, len(results.columns), sharey=True)
for i, n in enumerate(results.columns):
ax[i].hist(results[n], 20)
ax[i].set_xlabel(n)
ax[0].set_ylabel("Counts")
fig.set_size_inches(10, 4)
fig.subplots_adjust(wspace=0.1)
plt.show()
```
--------------------------------
### Add Custom JAR to Classpath
Source: https://github.com/quaquel/pynetlogo/blob/master/tests/Untitled.ipynb
Append a custom JAR file to the list of JARs to be used by the Java Virtual Machine. Ensure the path to the JAR is absolute.
```python
import os
jars.append(os.path.abspath("test.jar"))
```
--------------------------------
### Load Agent Data from Excel
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Loads agent initial properties, including 'who', 'xcor', and 'ycor', from an Excel file into a Pandas DataFrame. This prepares data for updating agent states in NetLogo.
```python
agent_xy = pd.read_excel("./data/xy_DataFrame.xlsx")
agent_xy[["who", "xcor", "ycor"]].head(5)
```
--------------------------------
### Push Current Working Directory to Engines
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Pushes the current working directory of the notebook to a 'cwd' variable on all engines. This ensures consistency in file paths across the cluster.
```python
import os
# Push the current working directory of the notebook to a "cwd" variable on the engines that can be accessed later
direct_view.push(dict(cwd=os.getcwd()), block=True)
```
--------------------------------
### NetLogoLink Class
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
The NetLogoLink class is the main interface for interacting with NetLogo. It allows you to create a link to a NetLogo instance, load models, execute commands, and retrieve data.
```APIDOC
## class pynetlogo.core.NetLogoLink(gui: bool = False, thd: bool = False, netlogo_home: str | None = None, jvm_path: str | None = None, jvm_args: list[str] | None = None)
Create a link with NetLogo.
Underneath, the NetLogo JVM is started through Jpype.
If netlogo_home, netlogo_version, or jvm_home are not provided, the link will try to identify the correct parameters automatically on Mac or Windows. netlogo_home and netlogo_version are required on Linux.
* **Parameters:**
* **gui** (*bool* *,* *optional*) – If true, displays the NetLogo GUI (not supported on Mac)
* **thd** (*bool* *,* *optional*) – If true, use NetLogo 3D
* **netlogo_home** (*str* *,* *optional*) – Path to the NetLogo installation directory (required on Linux)
* **jvm_path** (*str* *,* *optional*) – path of the jvm
* **jvm_args** (*list* *of* *str* *,* *optional*) – additional arguments that should be used when starting the jvm
```
--------------------------------
### Visualize Parameter-Output Relationships with Scatter Plots
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Generates bivariate scatter plots for each input parameter against a specific output. Uses scipy to calculate Pearson correlation coefficients and annotates each plot with the 'r' value. Ensure 'seaborn' and 'matplotlib' are imported.
```python
import scipy
nrow = 2
col = 3
fig, ax = plt.subplots(nrow, ncol, sharey=True)
sns.set_context("talk")
y = results["Avg. sheep"]
for i, a in enumerate(ax.flatten()):
x = param_values[:, i]
sns.regplot(
x=x,
y=y,
ax=a,
ci=None,
color="k",
scatter_kws={"alpha": 0.2, "s": 4, "color": "gray"},
)
pearson = scipy.stats.pearsonr(x, y)
a.annotate(
"r: {:6.3f}".format(pearson[0]),
xy=(0.15, 0.85),
xycoords="axes fraction",
fontsize=13,
)
if divmod(i, ncol)[1] > 0:
a.get_yaxis().set_visible(False)
a.set_xlabel(problem["names"][i])
a.set_ylim([0, 1.1 * np.max(y)])
fig.set_size_inches(9, 9, forward=True)
fig.subplots_adjust(wspace=0.2, hspace=0.3)
# plt.savefig('JASSS figures/SA - Scatter.pdf', bbox_inches='tight')
# plt.savefig('JASSS figures/SA - Scatter.png', dpi=300, bbox_inches='tight')
plt.show()
```
--------------------------------
### Track Agent Counts Over Time with repeat_report
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Use `repeat_report` to track the counts of 'wolves' and 'sheep' agents over a specified number of ticks. The results are stored in a dictionary.
```python
counts = netlogo.repeat_report(["count wolves", "count sheep"], 200, go="go")
```
--------------------------------
### Defining a Parallel Simulation Function
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
This function processes a single experiment, setting NetLogo parameters, running the simulation, and returning aggregated results. It handles specific parameter types like 'random-seed' and general global variables.
```python
def simulation(experiment):
# Set the input parameters
for i, name in enumerate(problem["names"]):
if name == "random-seed":
# The NetLogo random seed requires a different syntax
netlogo.command("random-seed {}".format(experiment[i]))
else:
# Otherwise, assume the input parameters are global variables
netlogo.command("set {0} {1}".format(name, experiment[i]))
netlogo.command("setup")
# Run for 100 ticks and return the number of sheep and wolf agents at each time step
counts = netlogo.repeat_report(["count sheep", "count wolves"], 100)
results = pd.Series(
[np.mean(counts["count sheep"]), np.mean(counts["count wolves"])],
index=["Avg. sheep", "Avg. wolves"],
)
return results
```
--------------------------------
### Plot Agent Counts and Phase-Space Plot
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Visualize agent counts over time and create a phase-space plot showing the relationship between wolf and sheep populations. Assumes 'counts' DataFrame is available.
```python
fig, (ax1, ax2) = plt.subplots(1, 2)
counts.plot(ax=ax1, use_index=True, legend=True)
ax1.set_xlabel("Ticks")
ax1.set_ylabel("Counts")
ax2.plot(counts["count wolves"], counts["count sheep"])
ax2.set_xlabel("Wolves")
ax2.set_ylabel("Sheep")
for ax in [ax1, ax2]:
ax.set_aspect(1 / ax.get_data_ratio())
fig.set_size_inches(12, 5)
plt.tight_layout()
plt.show()
```
--------------------------------
### Import Libraries for PyNetLogo
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/Untitled.ipynb
Imports necessary Python libraries for data manipulation and visualization, along with the PyNetLogo library.
```python
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import pyNetLogo
```
--------------------------------
### repeat_report(netlogo_reporter: str, reps: int, go: str = 'go', include_t0: bool = True)
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
Return values from a NetLogo reporter over a number of ticks.
```APIDOC
#### repeat_report(netlogo_reporter: str, reps: int, go: str = 'go', include_t0: bool = True)
Return values from a NetLogo reporter over a number of ticks.
> Can be used with multiple reporters by passing a list of strings.
> The values of the returned DataFrame are formatted following the
> data type returned by the reporters (numerical or string data,
> with single or multiple values). If the reporter returns multiple
> values, the results are converted to a numpy array.
> netlogo_reporter
> : Valid NetLogo reporter(s)
> reps
> : Number of NetLogo ticks for which to return values
> go
> : NetLogo command for running the model (‘go’ by default)
> include_t0
> : include the value of the reporter at t0, prior to running the
> go command
dict
: > key is the reporter, and the value is a list order by ticks
NetLogoException
: If reporters are not in a valid format, or if a LogoException
or CompilerException is raised by NetLogo
This method relies on files to send results from netlogo back to
Python. This is slow and can break when used at scale. For such
use cases, you are better of using a model specific way of interfacing.
For example, have a go routine which accumulates the relevant
reporters into lists. First run the model for the required time steps
using command, and next retrieve the lists through report.
```
--------------------------------
### Visualize Parameter-Output Correlations with Scatter Plots
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Generates bivariate scatter plots to visualize the relationship between each input parameter and the model output (average sheep count). Calculates and annotates the Pearson correlation coefficient for each parameter. Requires `matplotlib`, `scipy`, and `seaborn`.
```python
%matplotlib
import scipy
nrow = 2
ncol = 3
fig, ax = plt.subplots(nrow, ncol, sharey=True)
sns.set_context("talk")
y = results["Avg. sheep"]
for i, a in enumerate(ax.flatten()):
x = param_values[:, i]
sns.regplot(
x,
y,
ax=a,
ci=None,
color="k",
scatter_kws={"alpha": 0.2, "s": 4, "color": "gray"},
)
pearson = scipy.stats.pearsonr(x, y)
a.annotate(
"r: {:6.3f}".format(pearson[0]),
xy=(0.15, 0.85),
xycoords="axes fraction",
fontsize=13,
)
if divmod(i, ncol)[1] > 0:
a.get_yaxis().set_visible(False)
a.set_xlabel(problem["names"][i])
a.set_ylim([0, 1.1 * np.max(y)])
fig.set_size_inches(9, 9, forward=True)
fig.subplots_adjust(wspace=0.2, hspace=0.3)
```
--------------------------------
### Pushing Current Working Directory to Engines
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Pushes the current working directory of the notebook to a 'cwd' variable on all engines. This is useful for ensuring engines can access local files, such as the NetLogo model.
```python
import os
# Push the current working directory of the notebook to a "cwd" variable on the engines that can be accessed later
direct_view.push(dict(cwd=os.getcwd()))
```
--------------------------------
### Define and Execute NetLogo Procedure
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/Untitled.ipynb
Defines a NetLogo procedure named 'test' that reports the value 10. This snippet shows how to embed NetLogo code within a Python string.
```python
command = """
to-report test
report 10;
end
"""
# setup;
# let history [];
# repeat 10 [
# go;
# set history lput count sheep history
```
--------------------------------
### Plot Circles for SALib Visualization
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_sequential.ipynb
Helper function to plot circles representing sensitivity indices on a radial plot. It scales circle radii based on normalized index values.
```python
def plot_circles(ax, locs, names, max_s, stats, smax, smin, fc, ec, lw, zorder):
s = np.asarray([stats[name] for name in names])
s = 0.01 + max_s * np.sqrt(normalize(s, smin, smax))
fill = True
for loc, name, si in zip(locs, names, s):
if fc == "w":
fill = False
else:
ec = "none"
x = np.cos(loc)
y = np.sin(loc)
circle = plt.Circle(
(x, y),
radius=si,
ec=ec,
fc=fc,
transform=ax.transData._b,
zorder=zorder,
lw=lw,
fill=True,
)
ax.add_artist(circle)
```
--------------------------------
### Plotting Sobol Indices with SALib
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Visualizes Sobol' indices using a radial plot. Filters variables based on a specified criterion and threshold. Requires SALib, pandas, and matplotlib.
```python
from SALib.plotting.bar import plot as plot_bar
from SALib.plotting.sobol import plot as plot_sobol
from SALib.test_functions import Sobol_G
from SALib import ProblemSpec
# Define the problem
sp = ProblemSpec({'names': ['x1', 'x2', 'x3'], 'num_vars': 3, 'bounds': [[0, 1]] * 3})
# Run Sobol analysis
Si = sp.sobol.analyze(Sobol_G, print_to_console=False)
# Plotting the results
plot_sobol(Si)
plt.show()
plot_bar(Si)
plt.show()
```
--------------------------------
### Report Agent Properties in Python
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Retrieve and sort agent properties like coordinates and energy from NetLogo agents into Python variables. Ensures consistent ordering for plotting.
```python
x = netlogo.report("map [s -> [xcor] of s] sort sheep")
y = netlogo.report("map [s -> [ycor] of s] sort sheep")
energy_sheep = netlogo.report("map [s -> [energy] of s] sort sheep")
energy_wolves = netlogo.report("[energy] of wolves") # NetLogo returns these in random order
```
--------------------------------
### Visualize Agent Data with Matplotlib and Seaborn
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Visualize agent data using Matplotlib and Seaborn. Creates a scatter plot of agent positions colored by energy and histograms of energy distribution for sheep and wolves.
```python
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots(1, 2)
sc = ax[0].scatter(x, y, s=50, c=energy_sheep, cmap=plt.cm.coolwarm)
ax[0].set_xlabel("xcor")
ax[0].set_ylabel("ycor")
ax[0].set_aspect("equal")
divider = make_axes_locatable(ax[0])
cax = divider.append_axes("right", size="5%", pad=0.1)
cbar = plt.colorbar(sc, cax=cax, orientation="vertical")
cbar.set_label("Energy of sheep")
sns.histplot(energy_sheep, kde=False, bins=10, ax=ax[1], label="Sheep")
sns.histplot(energy_wolves, kde=False, bins=10, ax=ax[1], label="Wolves")
ax[1].set_xlabel("Energy")
ax[1].set_ylabel("Counts")
ax[1].legend()
fig.set_size_inches(14, 5)
plt.show()
```
--------------------------------
### report_while
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pynetlogo.md
Returns values from a NetLogo reporter while a specified condition remains true. Execution can be limited by a maximum duration.
```APIDOC
## report_while(netlogo_reporter: str, condition: str, command: str = 'go', max_seconds: int = 10)
### Description
Return values from a NetLogo reporter while a condition is true in the NetLogo model.
### Parameters
#### Path Parameters
- **netlogo_reporter** (str) - Required - Valid NetLogo reporter
- **condition** (str) - Required - Valid boolean NetLogo reporter
- **command** (str) - Optional - NetLogo command used to execute the model (defaults to 'go')
- **max_seconds** (int) - Optional - Time limit used to break execution (defaults to 10 seconds)
### Raises
- **NetLogoException**: If a LogoException or CompilerException is raised by NetLogo
```
--------------------------------
### Simulation Function for Parallel Execution
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/SALib_ipyparallel.ipynb
Defines a function to run a single simulation experiment. It sets NetLogo parameters, runs the model for a specified duration, and returns aggregated results as a pandas Series.
```python
def simulation(experiment):
# Set the input parameters
for i, name in enumerate(problem["names"]):
if name == "random-seed":
# The NetLogo random seed requires a different syntax
netlogo.command("random-seed {}".format(experiment[i]))
else:
# Otherwise, assume the input parameters are global variables
netlogo.command("set {0} {1}".format(name, experiment[i]))
netlogo.command("setup")
# Run for 100 ticks and return the number of sheep and wolf agents at each time step
counts = netlogo.repeat_report(["count sheep", "count wolves"], 100)
results = pd.Series(
[counts["count sheep"].values.mean(), counts["count wolves"].values.mean()],
index=["Avg. sheep", "Avg. wolves"],
)
return results
```
--------------------------------
### Visualize Updated Patch Data
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Retrieve and visualize the updated patch data after using `patch_set` to confirm the changes. This uses `patch_report` and `sns.heatmap`.
```python
countdown_update_df = netlogo.patch_report("countdown")
fig, ax = plt.subplots(1)
patches = sns.heatmap(
countdown_update_df,
xticklabels=5,
yticklabels=5,
cbar_kws={\"label\": \"countdown\"},
ax=ax,
)
ax.set_xlabel("pxcor")
ax.set_ylabel("pycor")
```
--------------------------------
### Report Value from NetLogo
Source: https://github.com/quaquel/pynetlogo/blob/master/examples/Untitled.ipynb
Reports a value from the NetLogo model. This will raise a NetLogoException if the reported variable or primitive is not defined.
```python
netlogo.report("test")
```
--------------------------------
### Report List Data with repeat_report
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Use `repeat_report` to collect list data, such as agent energy, over a number of ticks. Results for list reporters are converted to NumPy arrays. The last element of the energy array is plotted.
```python
results = netlogo.repeat_report(
[
"[energy] of wolves",
"[energy] of sheep",
"[sheep_str] of sheep",
"count sheep",
"glob_str",
],
5,
)
fig, ax = plt.subplots(1)
sns.histplot(results["[energy] of wolves"][-1], kde=False, bins=20, ax=ax)
ax.set_xlabel("Energy")
ax.set_ylabel("Counts")
fig.set_size_inches(4, 4)
plt.show()
```
--------------------------------
### Convert Sobol Indices to DataFrame
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/SALib_ipyparallel.ipynb
Filters and converts the Sobol indices dictionary returned by SALib into a pandas DataFrame for easier manipulation and visualization. Requires pandas.
```python
Si_filter = {k: Si[k] for k in ["ST", "ST_conf", "S1", "S1_conf"]}
Si_df = pd.DataFrame(Si_filter, index=problem["names"])
```
--------------------------------
### Display Sensitivity Analysis DataFrame
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/pyNetLogo demo - SALib sequential.ipynb
Displays the pandas DataFrame containing the calculated Sobol indices (S1 and ST) and their confidence intervals.
```python
Si_df
```
--------------------------------
### Inspect repeat_report Keys
Source: https://github.com/quaquel/pynetlogo/blob/master/docs/source/_docs/introduction.ipynb
Display the keys of the dictionary returned by `repeat_report`, which correspond to the reporters used in the call.
```python
list(results.keys())
```