Synopsis
Say you rely on ImageJ2/Fiji for data analysis and know some Python… It is probably easier than you think to write a plugin in Python using the Jython interpreter shipped with Fiji!
TL;DR - view an example Jython plugin at this Github repo.
This post is based on ImageJ’s Jython tutorial.
This work is licensed under CC BY-SA 4.0
Jython interpreter of ImageJ2/Fiji
ImageJ2/Fiji supports scripting in various languages using JVM-based interpreters. Python scripting is supported by Jython and R scripting is based on Renjin 1.
As of March 2024 and probably for a few more years, Jython is an implementation of Python 2.7. Therefore, 1) recent Python 3 features are not supported, and 2) you can only use standard Python v2.7 library (no numpy, pandas, etc.)
Although Jython is limited to standard Python library, it allows access to Java packages in the jars/
directory. This means that the following Java packages are available:
- ImageJ, Fiji, Bio-Formats and other ImageJ2 core stack packages.
- Other packages shipped with Fiji or installed from update sites.
For example, the following Jython code displays an image supported by Bio-formats (e.g., Zeiss czi, Nikon nd2)2.
|
|
Modular Jython plugin
Jython plugins may be modularized in this way:
- A single Jython script that is run when the plugin is executed (frontend)
- An arbitrary number of Jython packages (backend and frontend helpers)
For instance, the file organization below will
- Create an entry
My Plugin
under the ImageJ Plugins menu for executingMy_Plugin.py
. - Create a submenu
My Collection
under the ImageJ Plugins menu. - Allow import of
my_jython_package
from any Jython script/module3.
|
|
A bit more detail on why this works:
- Scripts in the
scripts/Plugins/
folder that starts with an uppercase are automatically added to the ImageJ/Plugins menu4. - The Jython interpreter has a default search path of
jars, jars/Libs
. - Modules under
jars/Libs
are compiled into Java classes during the first time the modules are imported. Compilation creates Java class files in the Jython packages. - Scripts under
scripts/Plugins/
are never compiled into Java and are rather interpreted every time the scripts are executed5.
There are other ways to organize modular Jython plugins. Most notably, one can organize Jython scripts and modules into JAR files using the SciJava Common discovery mechanism. This repo provides a stub example for organizing scripts with the SJC discovery mechanism.
Support for various scripts is implemented by
org.scijava.script.ScriptService
. It is based on the Java Scripting API (JSR 223). ↩︎ij.io is part of the ImageJ1 API. A comparison of ImageJ1 vs ImageJ2 API is found here. In a ImageJ2 Jython script, you may use the SciJava script parameters to ask for a file:
↩︎1 2
#@ File od file_path = od.getPath()
my_jython_package
follows standard Python package structure (optional__init__.py
with modules). ↩︎Underscores are displayed as spaces in the ImageJ Menu UI. Alternatively, scripts in the
plugins/
folder with an underscore prefix will also be added to the ImageJ/Plugins menu. ↩︎In contrast, Jython modules under
jars/Libs
are compiled into Java classes using the Jython compilerjythonc
. This has one important implication - SciJava Script Parameters are only usable in scripts underscripts/
orplugins/
and NOT Jython modules underjars/Libs
. ↩︎