|
| 1 | +--- |
| 2 | +title: "Getting started with GRASS for Conda" |
| 3 | +author: Brendan Harmon |
| 4 | +date: 2026-07-03 |
| 5 | +date-modified: today |
| 6 | +license: CC BY-SA |
| 7 | +categories: [Python, beginner] |
| 8 | +description: > |
| 9 | + Get started with GRASS for Conda. |
| 10 | +image: images/natural-earth-01.webp |
| 11 | +bibliography: conda.bib |
| 12 | +links: |
| 13 | + grass_projects: "[projects](https://grass.osgeo.org/grass-stable/manuals/grass_projects.html)" |
| 14 | + g_proj: "[g.proj](https://grass.osgeo.org/grass-stable/manuals/g.proj.html)" |
| 15 | + d_rast: "[d.rast](https://grass.osgeo.org/grass-stable/manuals/d.rast.html)" |
| 16 | + d_vect: "[d.vect](https://grass.osgeo.org/grass-stable/manuals/d.vect.html)" |
| 17 | + v_colors: "[v.colors](https://grass.osgeo.org/grass-stable/manuals/v.colors.html)" |
| 18 | + conda_create: "[conda create](https://docs.conda.io/projects/conda/en/stable/commands/create.html)" |
| 19 | + conda_install: "[conda install](https://docs.conda.io/projects/conda/en/stable/commands/install.html)" |
| 20 | + conda_activate: "[conda activate](https://docs.conda.io/projects/conda/en/stable/commands/activate.html)" |
| 21 | +format: |
| 22 | + ipynb: default |
| 23 | + html: |
| 24 | + toc: true |
| 25 | + code-tools: true |
| 26 | + code-copy: true |
| 27 | +engine: jupyter |
| 28 | +execute: |
| 29 | + eval: false |
| 30 | +jupyter: python3 |
| 31 | +--- |
| 32 | + |
| 33 | +This is a very short introduction to installing GRASS distributed via |
| 34 | +[Conda](https://grass.osgeo.org/download/conda/). |
| 35 | +With the Conda distribution of GRASS, |
| 36 | +you can install GRASS |
| 37 | +and the rest of the Python stack for data science |
| 38 | +with a single command. |
| 39 | +This means that you can easily integrate GRASS |
| 40 | +into data science workflows |
| 41 | +using the Python scientific ecosystem. |
| 42 | +This brief tutorial covers: |
| 43 | + |
| 44 | +* Installing the Conda package and environment manager |
| 45 | +* Creating a GRASS environment with Conda |
| 46 | +* Running GRASS in a Jupyter notebook |
| 47 | + |
| 48 | +## Manager |
| 49 | + |
| 50 | +Conda is an open source package and environment manager. |
| 51 | +Many open source projects |
| 52 | +use Conda to publish their software. |
| 53 | +With Conda, you can easily install |
| 54 | +collections of these packages |
| 55 | +in isolated environments |
| 56 | +to avoid conflicting software dependencies. |
| 57 | +With Conda, packages are distributed via channels, |
| 58 | +remote repositories that host packages. |
| 59 | +GRASS is distributed via conda-forge, |
| 60 | +a community smithy and repository |
| 61 | +[@condaforge]. |
| 62 | +There are several different distributions of Conda. |
| 63 | +For this tutorial, |
| 64 | +install [Miniforge](https://conda-forge.org/download/), |
| 65 | +a minimal distribution of Conda |
| 66 | +that uses conda-forge as its default channel |
| 67 | +[@Miniforge]. |
| 68 | +We recommend Miniforge |
| 69 | +because it is the easiest, cleanest way to |
| 70 | +install the GRASS Conda Package. |
| 71 | +Other distributions may be incompatible with conda-forge, |
| 72 | +requiring proper |
| 73 | +[configuration](https://conda-forge.org/docs/user/transitioning_from_defaults/) |
| 74 | +to work. |
| 75 | + |
| 76 | +::: {.callout-note title="Unix"} |
| 77 | +On Unix-like platforms - |
| 78 | +including {{< fa brands linux >}} Linux, |
| 79 | +{{< fa brands apple >}} MacOS, |
| 80 | +and {{< fa brands microsoft >}}{{< fa brands linux >}} |
| 81 | +Windows Subsystem for Linux - |
| 82 | +download the installation shell script |
| 83 | +and then run it in a terminal: |
| 84 | +```{bash} |
| 85 | +bash Miniforge3-$(uname)-$(uname -m).sh |
| 86 | +``` |
| 87 | +::: |
| 88 | + |
| 89 | +::: {.callout-note title="Windows"} |
| 90 | +For {{< fa brands microsoft >}} Windows, |
| 91 | +download and run the binary installer. |
| 92 | +See [here](https://github.com/conda-forge/miniforge#install) |
| 93 | +for more detailed instructions. |
| 94 | +::: |
| 95 | + |
| 96 | +## Environment |
| 97 | + |
| 98 | +Now that Conda is installed, |
| 99 | +let's use it to create an environment for GRASS. |
| 100 | +In this environment, |
| 101 | +we will install the following Python packages |
| 102 | +complete with their dependencies: |
| 103 | +GRASS, Jupyter Lab, and requests. |
| 104 | +In a terminal, |
| 105 | +run {{< meta links.conda_create >}} |
| 106 | +to create an environment named `grass`. |
| 107 | +Then use {{< meta links.conda_install >}} |
| 108 | +to install the GRASS package. |
| 109 | +Next, run {{< meta links.conda_activate >}} |
| 110 | +to start the environment. |
| 111 | + |
| 112 | +```{bash} |
| 113 | +conda create --name grass |
| 114 | +conda activate grass |
| 115 | +conda install grass jupyterlab requests |
| 116 | +``` |
| 117 | + |
| 118 | +You can do this with just one line of code: |
| 119 | +```{bash} |
| 120 | +conda create -n grass grass jupyterlab requests && conda activate grass |
| 121 | +``` |
| 122 | + |
| 123 | +If you use a Conda distribution other than Miniforge, |
| 124 | +you will need to specify the conda-forge channel |
| 125 | +when creating the environment with |
| 126 | +`-c conda-forge`. |
| 127 | +You may also need to override your default channel settings |
| 128 | +with `--override-channels` to prevent conflicts. |
| 129 | + |
| 130 | +## Notebook |
| 131 | + |
| 132 | +Let's try the newly installed GRASS Conda package |
| 133 | +in a Jupyter notebook. |
| 134 | +We will use scripting to display maps |
| 135 | +from a sample dataset. |
| 136 | +We will download the dataset, |
| 137 | +start a GRASS session, |
| 138 | +and then display raster and vector maps |
| 139 | +from the dataset. |
| 140 | +Let's begin by launching Jupyter Lab from the terminal. |
| 141 | +This will open a new Jupyter notebook |
| 142 | +in a web browser window. |
| 143 | + |
| 144 | +```{bash} |
| 145 | +jupyter lab |
| 146 | +``` |
| 147 | + |
| 148 | +### Start GRASS |
| 149 | + |
| 150 | +To start a GRASS session, |
| 151 | +we need to define a project |
| 152 | +and its coordinate reference system. |
| 153 | +For this demonstration, |
| 154 | +we will use the Natural Earth Dataset for GRASS [@NaturalEarth]. |
| 155 | +This dataset is a GRASS project |
| 156 | +with a collection of global raster and vector data |
| 157 | +in the World Geodetic System 1984. |
| 158 | +In your Jupyter notebook, |
| 159 | +use Python to download and unarchive the dataset. |
| 160 | +Then start a GRASS session using the dataset as a project. |
| 161 | +Read more about {{< meta links.grass_projects >}} in GRASS here. |
| 162 | +Since the dataset is approximately 120MB, |
| 163 | +it may take a couple of minutes to download. |
| 164 | +As a test that GRASS started correctly, |
| 165 | +run {{< meta links.g_proj >}} with flag `g` |
| 166 | +to print the current projection. |
| 167 | + |
| 168 | +```{python} |
| 169 | +# Import libraries |
| 170 | +import os |
| 171 | +import sys |
| 172 | +import subprocess |
| 173 | +from pathlib import Path |
| 174 | +import requests |
| 175 | +from zipfile import ZipFile |
| 176 | +
|
| 177 | +# Find GRASS Python packages |
| 178 | +sys.path.append( |
| 179 | + subprocess.check_output( |
| 180 | + ["grass", "--config", "python_path"], |
| 181 | + text=True |
| 182 | + ).strip() |
| 183 | + ) |
| 184 | +
|
| 185 | +# Import GRASS packages |
| 186 | +import grass.jupyter as gj |
| 187 | +from grass.tools import Tools |
| 188 | +
|
| 189 | +# Download dataset |
| 190 | +url = "https://zenodo.org/records/13370131/files/natural_earth_dataset.zip?download=1" |
| 191 | +filepath = Path.cwd() / "natural_earth_dataset.zip" |
| 192 | +request = requests.get(url, allow_redirects=True) |
| 193 | +if request.status_code != 200: |
| 194 | + raise ConnectionError(f"Error downloading file: {request.status_code}") |
| 195 | +filepath.write_bytes(request.content) |
| 196 | +
|
| 197 | +# Unarchive dataset |
| 198 | +with ZipFile(filepath, 'r') as archive: |
| 199 | + archive.extractall() |
| 200 | +
|
| 201 | +# Delete archive |
| 202 | +os.remove(filepath) |
| 203 | +
|
| 204 | +# Start GRASS in project |
| 205 | +home = Path.cwd() |
| 206 | +project = "natural_earth_dataset" |
| 207 | +session = gj.init(home, project) |
| 208 | +tools = Tools() |
| 209 | +
|
| 210 | +# Print projection information |
| 211 | +tools.g_proj(format="shell", flags="p") |
| 212 | +``` |
| 213 | + |
| 214 | +### Display raster map |
| 215 | + |
| 216 | +The Natural Earth raster is a global basemap |
| 217 | +with land cover and shaded relief |
| 218 | +rendered with a natural color scheme. |
| 219 | +Display the Natural Earth raster map |
| 220 | +with {{< meta links.d_rast >}}. |
| 221 | + |
| 222 | +```{python} |
| 223 | +# Display natural earth raster |
| 224 | +m = gj.Map(width=800) |
| 225 | +m.d_rast(map="natural_earth") |
| 226 | +m.show() |
| 227 | +``` |
| 228 | + |
| 229 | + |
| 230 | + |
| 231 | +### Display vector map |
| 232 | + |
| 233 | +Now display a vector map of global rivers. |
| 234 | +First apply a thematic color gradient to the rivers |
| 235 | +based on their stream order |
| 236 | +with {{< meta links.v_colors >}}. |
| 237 | +Then display the map with |
| 238 | +{{< meta links.d_vect >}}, |
| 239 | +scaling the line width by stream order. |
| 240 | + |
| 241 | +```{python} |
| 242 | +# Display rivers |
| 243 | +m = gj.Map(width=800) |
| 244 | +tools.v_colors(map="rivers", use="attr", column="scalerank", color="water") |
| 245 | +m.d_vect(map="rivers", width_column="strokeweig", width_scale=2) |
| 246 | +m.show() |
| 247 | +``` |
| 248 | + |
| 249 | + |
| 250 | + |
| 251 | +## Reproducibility |
| 252 | + |
| 253 | +Conda environments can also be created |
| 254 | +from an environment definition file |
| 255 | +that specifies the environment name, channel, and packages. |
| 256 | +This is an easy way to share and reproduce your environment. |
| 257 | +While you can specify versions for given packages, |
| 258 | +this example just installs the latest compatible versions |
| 259 | +for simplicity's sake. |
| 260 | +To do this, first use a text editor to create |
| 261 | +a YAML file named `environment.yml` |
| 262 | +with the following contents: |
| 263 | + |
| 264 | +```yaml |
| 265 | +# environment.yml |
| 266 | +name: grass |
| 267 | +channels: |
| 268 | + - conda-forge |
| 269 | +dependencies: |
| 270 | + - grass |
| 271 | + - jupyterlab |
| 272 | + - requests |
| 273 | +``` |
| 274 | +
|
| 275 | +Then run {{< meta links.conda_env_create >}} |
| 276 | +using `--file` to specify your path to the environment definition file: |
| 277 | + |
| 278 | +```bash |
| 279 | +conda env create --file environment.yml |
| 280 | +``` |
0 commit comments