Using Python from Analytica
New in Analytica 7.0
Requires the Analytica Developer (formerly Analytica Enterprise edition.)
Introduction
Analytica's Python integration is the two-way bridge between Analytica and Python. Analytica can execute Python code, call functions in Python libraries, pass data—including multi-dimensional arrays—to it, and retrieve the results. Conversely, Python code can call back into Analytica to evaluate variables or expressions. Together the two environments combine Analytica’s intuitive influence-diagram interface, intelligent arrays, and built-in uncertainty analysis with Python’s vast open-source ecosystem.
We recommend using Python versions 3.8+', although Theoretically the integration supports Python versions 3.3+,
Watch video on Analytica-Python integration basics
Motivation: Why use Python?
Python offers thousands of purpose-built libraries that extend what you can do in a model. Here are just a few:
| Library | What it adds when used from Analytica |
|---|---|
| NumPy, Pandas | Efficient numerical arrays and data-frame operations that underlie many other Python analytics libraries |
| Pillow | Programmatic image manipulation for tasks such as satellite-image preprocessing before feeding data back into Analytica. |
| Matplotlib, Seaborn | Visualizations not native to Analytica, including violin plots, heatmaps, network graphs, and 3-D surface plots. |
| PyTorch, Tensorflow | Training or running machine-learning models, then passing predictions into Analytica for further probabilistic analysis. |
Advantages: When to use Python in Analytica
| Situation in Analytica | Why using Python helps |
|---|---|
| Want custom visualizations beyond Analytica graphs | Generate plots with Matplotlib or Seaborn, save images, and display them in a Result window |
| Require advanced text or Natural-Language Processing | Apply Python packages like spaCy, NLTK, or built-in re for parsing, classification, and transformation
|
| Need a specialized statistical, ML, or optimization algorithm not built into Analytica | Leverage PyPI libraries such as scikit-learn, pandas, or pulp without re-implementing the math |
Downsides: When native Analytica is sometimes the better choice
| Concern | Why pure Analytica can be preferable |
|---|---|
| Array abstraction | Operating on arrays with different dimensions is a one-liner in Analytica but often requires verbose reshape/broadcast code in NumPy or Pandas. |
| Performance overhead | Transferring data and compiling Python incurs latency; tight loops or lightweight formulas run much faster as native Analytica expressions. For repeated Python calls, define a Callable to compile once and reuse. |
| Monte Carlo | Analytica’s built-in stochastic simulation is deeply integrated; recreating these in Python is rarely worth the effort. |
Setting up a Python environment
Installing Conda
Download and run the Anaconda or Miniconda installer for Windows.
Creating and activating a Python environment
Open the newly installed Anaconda Prompt app and run this command, which will create a new Python 3.11 environment named MyEnv and install the Python libraries Pandas and NumPy:
conda create -n MyEnv python=3.11 pandas numpy
Telling Analytica which Python environment to use
Open the Definition / Application integration / Python submenu.
Set either Python Environment or Python Model Environment to the environment’s name (e.g. MyEnv) or to the full folder path of the Python installation home directory, for example:
C:\Users\username\anaconda3\envs\MyEnv
Python Environment is stored with the Analytica installation and becomes the default for any model that does not set Python Model Environment.
Python Model Environment is saved inside the current model and overrides the installation-wide setting.
See Setting up a Python environment for a detailed walkthrough.
Loading and Unloading of Python
Python (core, environment, and libraries) loads only when your model first executes or evaluates Python code, and unloads when you close the model. Reopening the same model, or opening another that uses Python, starts a fresh Python session; any prior Python state (variables, imports) is lost. If the new model uses a different environment, it may run a different Python release.
If Python is already loaded and you change the Python Environment or Python Model Environment, Python unloads immediately. The selected environment’s Python loads the next time your model runs Python code. Unloading discards all Python state (variables, imports).
Python runs in the same process as Analytica.
The core Analytica functions and system variables for configuring and interacting with Python are found on the Definition / Application integration / Python submenu.

Importing Python libraries
The preferred way to make Python libraries available in Analytica models is to place their import statements in the system variable PythonStartupCode. These lines execute when Python gets loaded, so the libraries are ready for use in later Python code.
If you edit PythonStartupCode after Python has already been loaded in the current Analytica model, you must reload the model (or close and reopen Analytica) for the modified startup code to take effect.
Importing from nodes
When creating a filed Analytica library or module, it is highly recommended to perform imports within a Variable or Callable node inside the library/module itself. This practice ensures that the library/module remains self-contained, as PythonStartupCode is not saved as part of a filed module or library. You should then create dependencies from nodes that use the Python libraries to the import node(s) to ensure the Python libraries are loaded before use.
Python supports two main import styles:
- Module import – e.g.,
import numpy - Selective / wildcard import – e.g.,
from numpy import array, zerosorfrom numpy import *
When an import statement is the final expression, Analytica returns its value:
| Import statement | Return value when it is the last statement | Output image |
|---|---|---|
import numpy as np, os
|
The module’s string representation e.g.,«Python <module 'numpy' from …>»«Python <module 'os' from …>»)
|
|
from numpy import array, zeros
|
A list of the imported names (alias names if provided, otherwise the original names) |
Python py:: namespace
Analytica exposes the embedded Python interpreter through the py:: namespace prefix. Any name visible at the top level of the interpreter—global variables, functions, classes, or imported modules—can be accessed through Analytica with the same spelling and case, preceded by py::.
Example: Incrementing a Python global variable counter by 2
py::counter := py::counter + 2;
Calling a Python function
Invoking a Python function from Analytica is as simple as writing it:
py::len(MyArray)
Arguments may be:
- Analytica scalars
- Analytica arrays (which get array abstracted)
- Python objects
Keyword arguments (kwargs)
When a Python function accepts keyword arguments (**kwargs), use a syntax similar to Analytica’s name-based function calls, a colon after the parameter name, followed by the parameter value, instead of the equal sign used in Python.
py::my_func("arg1", kwarg1:1, kwarg2:"abc")
The equivalent call in native Python is:
my_func("arg1", kwarg1=1, kwarg2="abc")
Python print() function
The standard Python print() function sends its text output to Analytica's Typescript console window, just as it appears in a native Python console.
- When called from Analytica with
py::print(), the printed text will appear in the window. - When called inside a Python script executed by Analytica, any
print()statements also stream to the window.
Using Python classes
Using an existing Python class
To instantiate a Python class, call its constructor with the py:: prefix and pass any arguments exactly as you would in native Python.
py::MyClass(42, 'widgets')
Arrow operator (->)
The arrow operator (->) lets you access the attributes and methods of a Python object, analogous to the dot operator (.) in Python:
ColNames := MyDf->columns { attribute }Head5 := MyDf->head(5) { method }
You can chain these accesses and calls:
FirstName := MyDf->columns->tolist()
You can also assign through the arrow operator; the assignment will update the underlying Python object:
MyObj->value := 42
Using Python code in a definition
When you choose Python expr from the Definition drop-down, the entire definition is passed verbatim to the embedded Python interpreter.
Defining a UDF with a Python expr definition
When you set a Function node’s Definition to Python expr, you can write the entire body in Python. Analytica recompiles that code every time the function is evaluated, which can noticeably slow large array computations. To eliminate this overhead, place the code in a reusable Python Callable so the compiled version remains cached between calls.
Inside Python expr, Analytica function parameters behave like local Python variables.
Callables
Callables let you embed full Python functions or classes directly inside Analytica, then invoke them like any other UDF.
Creating a Python Callable node
- Create a new Variable node.
- In the node’s Object window, change the Class dropdown from Variable to Callable.
- Enter your Python code in the Definition pane.
Writing Python Callable code
Use standard Python syntax to define a def function or a class inside the Definition pane of your Callable. For example:
def compound_interest(p, r, n):
return p * (1 + r) ** n
Caching compiled functions in Callables
When you evaluate a node, Analytica compiles your function and caches the resulting callable object as the node’s value. This differs from UDFs which cannot store a value, so they compile every time they run.
Parameters attribute
Callables do not have a Parameters attribute; all arguments are declared in your def or class signature.
Importing custom Python modules
Import modules exactly as you would in native Python. For example:
import myutils from mylib.finance import NPV
Ensure the module is on Python’s sys.path by appending the module's directory to the path. For additional guidance, see the official Python documentation on modules.
Dependencies
Analytica's automatic dependency graph is a key advantage over working in environments like Jupyter notebooks or regular Python scripts, where you are responsible for manually re-running cells or scripts to reflect changes.
When integrating Python code, however, Analytica's dependency system cannot parse the Python script to automatically detect when an Analytica node is being used. You must explicitly declare these dependencies by drawing influence arrows. Drawing an influence arrow from any node to a node that uses Python Expr creates a true dependency, adding it to Analytica's dependency graph.
As an alternative for nodes that access Python global variables without using Python Expr, you can establish a dependency by including the Identifier of the influencing node directly within the Definition of the dependent node.
If dependencies for Python nodes are not manually defined with arrows, your model will not invalidate results correctly. Updates to an input variable will not trigger re-computation in the Python node that depends on it, leaving it with a stale, incorrect value.
Functions for evaluating Python code
PyEval
PyEval is used to evaluate a single Python expression and return its value to Analytica. It is designed to be side-effect-free, meaning it won't change the state of variables or objects in Python. This makes it ideal for safe, simple calculations.
Since PyEval only evaluates a single expression, it cannot execute multi-line code or statements like variable assignments or imports.
It also includes an optional excludeTypes parameter, which allows you to specify Python types that should not be converted to Analytica Values.
PyExec
PyExec is used to execute a block of Python code, which can contain multiple lines or statements. Unlike PyEval, PyExec is intended to have side effects. You can use it to import libraries, define functions, or set the values of variables in the Python environment.
Use PyExec when you need to run a script to set up an environment or perform operations that modify the Python state for use in later evaluations.
PyCall
PyCall offers a direct and efficient way to call a specific Python function. You provide the callable Python function object followed by its positional and keyword arguments.
This is the preferred function when your primary goal is to execute an existing Python function and retrieve its result.
Non-scalar data structures
Any Python object that is not converted automatically to an Analytica type comes back as an opaque wrapper displayed as «Python …», where the ellipsis is the object’s repr. Keep this wrapper when the object merely passes between Python calls, and invoke PyExplode when the data must be examined or manipulated within Analytica.
Converting from Python data to Analytica
When a Python function invoked from Analytica returns a result, Analytica automatically attempts to convert the Python data into the most appropriate Analytica value. For complex data structures, the dedicated PyExplode function is available to perform more specific conversions.
Automatic conversions
The following Python types are automatically converted to their corresponding Analytica equivalents without any extra steps:
| Python type | Analytica type | Notes |
|---|---|---|
int |
Integer |
If the int exceeds the 64-bit signed-integer range, Analytica converts it to a double floating-point Number instead of an Integer.
|
float |
Number |
|
bool |
Boolean |
|
complex |
ComplexNumber |
|
str |
Text |
|
None |
Null |
|
date |
DateTime |
|
time |
DateTime |
|
datetime |
DateTime |
|
analytica.Value |
Unwrapped Analytica value | |
| Any other Python object | Python opaque wrapper | Can be passed to other Python function calls or converted with PyExplode.
|
PyExplode
The PyExplode function provides explicit control for converting complex Python objects that are not converted automatically.
Key capabilities include:
- Unpacking Python built-in collections, like
list,tuple,set, into a 1D Analytica array. - Converting a Python
dictinto a 1D Analytica array, using the dictionary keys to create a new local index. - Using nested calls to convert multi-dimensional data into multi-dimensional Analytica arrays.
- Fully converting a NumPy Array into an n-dimensional Analytica array.
- Converting image objects from PIL.Image or matplotlib.figure.Figure directly into Analytica images.
- Optionally excluding specific Python types from conversion with
excludeTypes, which keeps them as opaque Python object handles.
To convert a Pandas DataFrame, you must use the PyExplodeDataFrame function. This function is not built-in and requires you to include the Python Pandas library in your model.
Converting from Analytica to Python data structures
The bridge between Analytica and Python performs two kinds of mappings: automatic scalar conversions and explicit conversion functions for arrays.
Automatic scalar conversions
| Analytica type | Python type |
|---|---|
Text |
str
|
Integer |
int
|
Number |
float
|
Boolean |
bool
|
ComplexNumber |
complex
|
DateTime |
datetime.datetime / datetime.time / datetime.date
|
Handle |
analytica.Object
|
Null / Undefined |
None
|
| Python opaque wrapper | unwrapped Python object |
Reference |
setof the dereferenced contents
|
Image |
PIL.Image.Image
|
| Everything else | analytica.Value (wrapper for Analytica Values)
|
Explicit conversion functions for arrays
Analytica has a single collection type—the array—whereas Python offers several (list, tuple, dict, set, numpy.ndarray, …). Because there is no one-to-one mapping, arrays are not converted implicitly; instead call one of the system functions below.
PyList, PyTuple, PySet, PyDict create a Python collection over the single dimension that you specify. In contrast, PyArray converts an entire Analytica array into a single numpy.ndarray.
- PyList – Creates a Python
listfrom the specified index, retaining other dimensions in Analytica. - PyTuple – Creates a Python
tuplefrom the chosen index of the array, retaining other dimensions in Analytica. - PySet – Creates a Python
setfrom the specified index, duplicate entries will be removed. - PyDict – Creates a Python
dictfrom an Analytica vector. The elements of a specified index are used as keys and the corresponding vector values become the dictionary values. The input vector must be indexed by the key index. - PyArray – Converts an entire Analytica array into a single multi-dimensional
numpy.ndarray. This function always converts all dimensions. The optional index parameters are used to specify the order of the axes in the resulting NumPy array. For any Analytica dimension not explicitly passed as a parameter, a local, positional index is created for that axis in the NumPy array. An optionaldtypestring passes directly to NumPy.
Using Analytica locals from Python code
Analytica locals are visible by default to PyEval and PyExec when called within the same definition that introduces them (e.g., a definition using Local or a Function with parameters). To change visibility, pass explicit Python globals and locals mappings; providing an empty locals isolates the Python code from Analytica locals.
Example: Local a := 5; PyEval("a + 1") returns 6 because a is visible to the Python expression in that evaluation.
Accessing Analytica objects from Python code
To interact with your Analytica model from Python, use the analytica module. This module is bundled with your Analytica installation and provides the necessary functions to access, evaluate, and manipulate objects within your model directly from Python.
To begin, you must import the module in your Python code:
import analytica
Getting a handle to an Analytica object
You can obtain a handle to any object in your model usinganalytica.get('object_identifier') in Python. This is useful when you want to refer to an object itself rather than its computed value. The function takes the identifier of the Analytica object as its argument and returns an analytica.Object.
Example:
To get a handle to a variable named Revenue, you would use:
revenue_handle = analytica.get('Revenue')
This assigns an analytica.Object representing the Revenue Analytica variable to the revenue_handle Python variable.
Evaluating an Analytica expression
To evaluate an Analytica expression, use analytica.eval('Analytica_expression'). This function processes its string argument as an Analytica expression within the context of your model.
analytica.eval() is the primary method for retrieving the calculated value of a variable. When it returns a value, it will implicitly convert many Analytica data types into their Python equivalents.
Example:
To get the computed value of the Revenue variable, you would evaluate its identifier:
revenue_result = analytica.eval('Revenue')
This executes the expression for Revenue and stores its final value in the revenue_result Python variable.
Enable comment auto-refresher