Unit 10 - Python intro

Python programming language is very popular in the field of GIS and data science in general. Python is also the main scripting platform for Esri products (see arcpy package). GRASS is not an exception. In reality, many GRASS modules are basically Python scripts, eg. r.mask (see Source Code section).

GRASS Python environment consists various libraries, see GRASS documentation for details. Let’s focus on three main libraries related to this workshop:

PyGRASS is designed as an object-oriented Python API for GRASS GIS. This is a major difference to GRASS Scripting Library which consists of procedures - Python functions. It is important to highlight that PyGRASS is not a replacement for GRASS Scripting Library. The both libraries are living next to each other. It is up to a user which library will use in his/her scripts. It’s also possible to compine both libraries in one single script (not recommended).

Let’s do our first steps towards Python scripting in Python tab.


Fig. 70 Interactive prompt in Python tab.

Let’s perform a simple computation workflow below in Python:

  1. Set computation extent based on Jena city region, align computational region to Sentinel bands
  2. Extend computation region by 1km offset
  3. Set mask based on cloud vector map
  4. Compute NDVI
  5. Compute NDVI values statistics, print min, max and mean NDVI values

The workflow is represented by a set of GRASS commands (map names shorten):

# 1.
g.region vector=jena_boundary align=B04_10m
# 2.
g.region n=n+1000 s=s-1000 e=e+1000 w=w-1000
# 3.
r.mask -i vector=MaskFeature
# 4.
i.vi red=B04_10m output=ndvi viname=ndvi nir=B08_10m
# 5.
r.univar map=ndvi


GRASS modules run from Console and GUI dialogs can be logged into file by Log file (click to start/stop logging). Logged commands can be used as a starting point for your first Python script.


Fig. 71 Log GRASS commands into file.

The commands needs to be changed to satisfy Python syntax. In this unit GRASS Scripting Library will be used since Python tab already includes this library as gs. Only basic syntax will be explained. In next units we will switch to object-oriented PyGRASS library.

GRASS commands can be run by core.run_command function.

# 1.
gs.run_command('g.region', vector='jena_boundary', align='L2A_T32UPB_20170706T102021_B04_10m')
# 2.
gs.run_command('g.region', n='n+1000', s='s-1000', e='e+1000', w='w-1000') # 3.
gs.run_command('r.mask', flags='i', vector='MaskFeature', overwrite=True)
# 4.
gs.run_command('i.vi', red='L2A_T32UPB_20170706T102021_B04_10m', output='ndvi',
                  viname='ndvi', nir='L2A_T32UPB_20170706T102021_B08_10m', overwrite=True)
# 5.
gs.run_command('r.univar', map='ndvi')


Python shell has its history, previous commands can be browsed by Alt+P, next commands by Alt+N.

Output of r.univar tool is ignored by core.run_command function. r.univar must be run by core.read_command which returns an output of the command. But it is still not perfect, statistics is printed to standard output and cannot be processed by Python commands. It would be feasible to retrieve command’s output as Python object, a dictionary. This can be done by:

  • running r.univar with -g to enable shell script (parse-able) output
  • and using core.parse_command function which parses output and store result as a Python dictionary object
# 5.
stats = gs.parse_command('r.univar', flags='g', map='ndvi')
print('NDVI min value: {0:.4f}'.format(float(stats['min'])))
print('NDVI max value: {0:.4f}'.format(float(stats['max'])))
print('NDVI mean value: {0:.4f}'.format(float(stats['mean'])))

Fig. 72 Running Python code in Python tab.

Resultant NDVI raster map can be displayed easily by calling AddLayer() function directly from Python shell.


Graphical Modeler and Python

Model created in Graphical Modeler can be easily converted into Python script. Let’s open the model created in Unit 09 - Model tuning: ndvi-v3.gxm and switch to Python editor tab.


Fig. 73 Python editor integrated in Graphical Modeler. Python code can be modified, run or saved into file (ndvi-v3.py).