Other scripting languages
While NEURON currently only officially supports Python and HOC scripting, many other programming environments can be used with NEURON through a Python compatibility layer.
Bringing data recorded in NEURON (e.g. via Vector.record()
) into the other programming
language is sometimes problematic as it may not know how to interpret Vector
objects;
one way to work-around this is to copy them into Python lists using Vector.to_python()
.
We demonstrate with Julia.
Setting up Julia for use with NEURON
By default, Julia uses its own version of Python instead of the system Python.
As such, you’ll need to either change Julia to use the system Python or install
NEURON within Julia itself using pip
. (Currently pip
for NEURON only works
in Linux and macOS.)
To setup Julia to use NEURON on Linux or macOS, open an interactive Julia session by typing julia
and then enter:
import Pkg
Pkg.add("PyCall")
Pkg.add("Plots")
using PyCall
subprocess = pyimport("subprocess")
ENV["PYTHONHOME"] = ""
subprocess.check_call([sys.executable, "-m", "pip", "install", "neuron"])
This additionally installs two Julia packages: PyCall
, the Python-compatibility API, and Plots
which provides graphics functions.
This setup only needs to be performed once.
A simple Julia example
Within any script that is to use NEURON, we begin by getting NEURON’s h
object, which is the primary way of interacting with NEURON in Python as well. To do so, we write:
using PyCall
neuron = pyimport("neuron")
h = neuron.h
We can then use the h
object as described in the Python programmer’s reference.
The following code simulates and plots an action potential in a Hodgkin-Huxley point cell:
using PyCall
using Plots
println("setting up model...")
neuron = pyimport("neuron")
h = neuron.h
h.load_file("stdrun.hoc")
soma = h.Section("soma")
soma.insert(h.hh)
soma.L = 10
soma.diam = 10
ic = h.IClamp(soma(0.5))
ic.amp = 0.5
ic.dur = 0.1
ic.delay = 1
t = h.Vector().record(h._ref_t)
v = h.Vector().record(soma(0.5)._ref_v)
println("simulating...")
h.finitialize(-65)
h.continuerun(10)
println("plotting...")
display(plot(t.to_python(), v.to_python()))
print("Press enter to close...")
readline()

Here the plot
function (from the Plots
library) required us to invoke the Vector.to_python()
which copies it into a list, which Julia interprets as a Vector{Float64}
.
Such conversion is not always necessary; Julia correctly handles NEURON Vector
manipulations like length(v)
, v[4]
, and vector arithmetic v + 2 * v
.
Note
When used inside Julia, NEURON Vector
objects are 1-indexed, as is the Julia convention.
(Python and HOC are 0-indexed.)
That is, vec[1]
returns the first item in vec
not the second item.
julia> vec = h.Vector([5, 72, 16])
PyObject Vector[1]
julia> vec[1]
5.0
Warning
Due to Julia’s auto-type-conversion rules,
invoking Vector.as_numpy()
directly in Julia will cause a numpy
array to be created on the
Python side but then be immediately copied to a Vector{Float64}
; as such, changes to the returned
object would not affect the original Vector
; that is, a direct call to Vector.as_numpy()
in Julia behaves functionally equivalent to calling Vector.to_python()
.
To avoid copying the Vector values, explicitly invoke pycall
and specify PyArray
as the return
type, e.g.
jvec = pycall(vec.as_numpy, PyArray)
Such a jvec
can then be used with e.g. the plot
function.