-
Notifications
You must be signed in to change notification settings - Fork 27
Tutorial: getting started with conda #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,261 @@ | ||
| --- | ||
| title: "Getting started with GRASS for Conda" | ||
| author: Brendan Harmon | ||
| date: last-modified | ||
| license: CC BY-SA | ||
| categories: [Python, beginner] | ||
| description: > | ||
| Get started with GRASS for Conda. | ||
| image: images/natural-earth-01.webp | ||
| bibliography: conda.bib | ||
| csl: ../../../acm.csl | ||
| links: | ||
| grass_projects: "[projects](https://grass.osgeo.org/grass-devel/manuals/grass_projects.html)" | ||
| g_proj: "[g.proj](https://grass.osgeo.org/grass-stable/manuals/g.proj.html)" | ||
| d_rast: "[d.rast](https://grass.osgeo.org/grass-stable/manuals/d.rast.html)" | ||
| d_vect: "[d.vect](https://grass.osgeo.org/grass-stable/manuals/d.vect.html)" | ||
| v_colors: "[v.colors](https://grass.osgeo.org/grass-stable/manuals/v.colors.html)" | ||
| conda_create: "[conda create](https://docs.conda.io/projects/conda/en/stable/commands/create.html)" | ||
| conda_install: "[conda install](https://docs.conda.io/projects/conda/en/stable/commands/install.html)" | ||
| conda_activate: "[conda activate](https://docs.conda.io/projects/conda/en/stable/commands/activate.html)" | ||
| format: | ||
| ipynb: default | ||
| html: | ||
| toc: true | ||
| code-tools: true | ||
| code-copy: true | ||
| engine: jupyter | ||
| execute: | ||
| eval: false | ||
| jupyter: python3 | ||
| --- | ||
|
|
||
|  | ||
|
|
||
| This is a very short introduction to | ||
| the [GRASS Python package](https://grass.osgeo.org/download/conda/) | ||
| distributed via Conda. | ||
| With the GRASS Python package, | ||
| you can call GRASS tools | ||
| in Python scripts | ||
| or Jupyter notebooks. | ||
| This means that you can easily integrate GRASS | ||
| into data science workflows | ||
| using the Python scientific ecosystem. | ||
| This brief tutorial covers: | ||
|
|
||
| * Installing the Conda package and environment manager | ||
| * Creating a GRASS environment with Conda | ||
| * Running GRASS in a Jupyter notebook | ||
|
|
||
| <!-- | ||
| ::: {.callout-note title="In-depth tutorial"} | ||
| For a more in-depth guide covering | ||
| installers, package managers, computational notebooks, | ||
| and integrated development environments, | ||
| please see the | ||
| [GRASS for Conda](conda.qmd) tutorial. | ||
| ::: | ||
| --> | ||
|
|
||
| ## Manager | ||
|
|
||
| Conda is an open source package and environment manager. | ||
| Many open source projects | ||
| use Conda to publish their software | ||
| as Python packages. | ||
| With Conda, you can easily install | ||
| collections of these packages | ||
| in isolated environments | ||
| to avoid conflicting software dependencies. | ||
| With Conda, packages are distributed via channels, | ||
| remote repositories that host packages. | ||
| The GRASS Python package is distributed via conda-forge, | ||
| a community smithy and repository | ||
| [@condaforge]. | ||
| There are several different distributions of Conda. | ||
| For this tutorial, | ||
| install [Miniforge](https://conda-forge.org/download/), | ||
| a minimal distribution of Conda | ||
| that uses conda-forge as its default channel | ||
| [@Miniforge]. | ||
| We recommend Miniforge | ||
| because it is the easiest, cleanest way to | ||
| install the GRASS Python Package. | ||
| Other distributions may be incompatible with conda-forge, | ||
| requiring proper | ||
| [configuration](https://conda-forge.org/docs/user/transitioning_from_defaults/) | ||
| to work. | ||
|
|
||
| ::: {.callout-note title="Unix"} | ||
| On Unix-like platforms - | ||
| including {{< fa brands linux >}} Linux, | ||
| {{< fa brands apple >}} MacOS, | ||
| and {{< fa brands microsoft >}}{{< fa brands linux >}} | ||
| Windows Subsystem for Linux - | ||
| download the installation shell script | ||
| and then run it in a terminal: | ||
| ```{bash} | ||
| bash Miniforge3-$(uname)-$(uname -m).sh | ||
| ``` | ||
| ::: | ||
|
|
||
| ::: {.callout-note title="Windows"} | ||
| For {{< fa brands microsoft >}} Windows, | ||
| download and run the binary installer. | ||
| See [here](https://github.com/conda-forge/miniforge#install) | ||
| for more detailed instructions. | ||
| ::: | ||
|
|
||
| ## Environment | ||
|
|
||
| Now that Conda is installed, | ||
| let's use it to create an environment for GRASS. | ||
| We will install the GRASS and Jupyter Lab Python packages | ||
| and all of their dependencies into this environment. | ||
| In a terminal, | ||
| run {{< meta links.conda_create >}} | ||
| to create a GRASS environment named `grass`. | ||
| Then use {{< meta links.conda_install >}} | ||
| to install the GRASS package. | ||
| Next, run {{< meta links.conda_activate >}} | ||
| to start the environment. | ||
|
|
||
| ```{bash} | ||
| conda create --name grass | ||
| conda install grass jupyterlab | ||
| conda activate grass | ||
| ``` | ||
|
|
||
| You can do this with just one line of code: | ||
| ```{bash} | ||
| conda create -n grass grass jupyterlab && conda activate grass | ||
| ``` | ||
|
|
||
| If you use a Conda distribution other than Miniforge, | ||
| you will need to specify the conda-forge channel | ||
| when creating the environment with | ||
| `-c conda-forge`. | ||
| You may also need to override your default channel settings | ||
| with `--override-channels` to prevent conflicts. | ||
|
|
||
| ## Notebook | ||
|
|
||
| Let's try the GRASS Python package | ||
| in a Jupyter notebook. | ||
| We will using scripting to display maps | ||
| from a sample dataset. | ||
| We will download the dataset, | ||
| start a GRASS session in the dataset, | ||
| and then display raster and vector maps | ||
| from the dataset. | ||
| Let's begin by launching Jupyter Lab from the terminal. | ||
| This will open an new Jupyter notebook | ||
| in a web browser window. | ||
|
|
||
| ```{bash} | ||
| jupyter lab | ||
| ``` | ||
|
|
||
| ### Start GRASS | ||
|
|
||
| To start a GRASS session, | ||
| we need to define a project | ||
| and its coordinate reference system. | ||
| For this demonstration, | ||
| we will use the Natural Earth Dataset for GRASS [@NaturalEarth]. | ||
| This dataset is a GRASS project | ||
| with a collection of global raster and vector data | ||
| in the World Geodetic System 1984. | ||
| In your Jupyter notebook, | ||
| use Python to download and unarchive the dataset. | ||
| Then start a GRASS session using the dataset as a project. | ||
| Read more about {{< meta links.grass_projects >}} in GRASS here. | ||
| Since the dataset is approximately 120MB, | ||
| it may take a couple of minutes to download. | ||
| As a test that GRASS started correctly, | ||
| run {{< meta links.g_proj >}} with flag `g` | ||
| to print the current projection. | ||
|
|
||
| ```{python} | ||
| # Import libraries | ||
| import os | ||
| import sys | ||
| import subprocess | ||
| from pathlib import Path | ||
| import requests | ||
| from zipfile import ZipFile | ||
|
|
||
| # Find GRASS Python packages | ||
| sys.path.append( | ||
| subprocess.check_output( | ||
| ["grass", "--config", "python_path"], | ||
| text=True | ||
| ).strip() | ||
| ) | ||
|
|
||
| # Import GRASS packages | ||
| import grass.script as gs | ||
| import grass.jupyter as gj | ||
|
|
||
| # Set GRASS database | ||
| gisdbase = Path.home() / "grassdata" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's omit using gisdbase and grassdata... We are trying to put projects in the spotlight and avoid the traditional directory structure. We can have projects anywhere, so perhaps just download the zip in the current directory, no need to create a grassdata for a zip file.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @veroandreo Okay. gs.setup.init and gj.init require a project path though. So I think I need to include a path in the call: Alternatively, we could create a temporary directory and project like in many of the other tutorials. Perhaps just using the current directory, however, is a little simpler and an example of a different way to work. |
||
|
|
||
| # Download dataset | ||
| url = "https://zenodo.org/records/13370131/files/natural_earth_dataset.zip?download=1" | ||
| filepath = gisdbase / "natural_earth_dataset.zip" | ||
| request = requests.get(url, allow_redirects=True) | ||
| if request.status_code != 200: | ||
| raise ConnectionError(f"Error downloading file: {request.status_code}") | ||
| filepath.write_bytes(request.content) | ||
|
|
||
| # Unarchive dataset | ||
| with ZipFile(filepath, 'r') as archive: | ||
| archive.extractall(gisdbase) | ||
|
|
||
| # Delete archive | ||
| os.remove(filepath) | ||
|
|
||
| # Start GRASS in project | ||
| session = gj.init(gisdbase / "natural_earth_dataset") | ||
|
|
||
| # Print projection information | ||
| gs.run_command("g.proj", flags="g") | ||
| ``` | ||
|
|
||
| ### Display raster map | ||
|
|
||
| The Natural Earth raster is a global basemap | ||
| with land cover and shaded relief | ||
| rendered with a natural color scheme. | ||
| Display the Natural Earth raster map | ||
| with {{< meta links.d_rast >}}. | ||
|
|
||
| ```{python} | ||
| # Display natural earth raster | ||
| m = gj.Map(width=800) | ||
| m.d_rast(map="natural_earth") | ||
| m.show() | ||
| ``` | ||
|
|
||
|  | ||
|
|
||
| ### Display vector map | ||
|
|
||
| Now display a vector map of global rivers. | ||
| First apply a thematic color gradient to the rivers | ||
| based on their stream order | ||
| with {{< meta links.v_colors >}}. | ||
| Then display the map with | ||
| {{< meta links.d_vect >}}, | ||
| scaling the line width by stream order. | ||
|
|
||
| ```{python} | ||
| # Display rivers | ||
| m = gj.Map(width=800) | ||
| gs.run_command("v.colors", map="rivers", use="attr", column="scalerank", color="water") | ||
| m.d_vect(map="rivers", width_column="strokeweig", width_scale=2) | ||
| m.show() | ||
| ``` | ||
|
|
||
|  | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| @misc{condaforge, | ||
| author = {{conda-forge community}}, | ||
| title = {{The conda-forge Project:} Community-based Software | ||
| Distribution Built on the conda Package Format and | ||
| Ecosystem | ||
| }, | ||
| month = {7}, | ||
| year = {2015}, | ||
| publisher = {Zenodo}, | ||
| doi = {10.5281/zenodo.4774217}, | ||
| url = {https://conda-forge.org/}, | ||
| } | ||
|
|
||
| @software{Miniforge, | ||
| title = {Miniforge}, | ||
| author = {{conda-forge community}}, | ||
| year = {2026}, | ||
| license = {BSD 3-Clause License}, | ||
| url = {https://conda-forge.org/download/}, | ||
| version = {26.3.2-0}, | ||
| repository= {https://github.com/conda-forge/miniforge} | ||
| } | ||
|
|
||
| @dataset{NaturalEarth, | ||
| author = {Harmon, Brendan and van Breugel, Paulo}, | ||
| title = {Natural Earth Dataset for GRASS GIS}, | ||
| year = 2020, | ||
| publisher = {Zenodo}, | ||
| version = {2.0.0}, | ||
| doi = {10.5281/zenodo.3762773} | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we wait to merge this tutorial until the conda package for Windows is ready? Or maybe we say something like "Conda package for Windows is coming soon!"?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@veroandreo After some reflection, I think I'd prefer publishing this now and then updating it. I commented out the Windows instructions and replaced it with a coming soon statement. I don't know how long it will be before the Windows package is released. When GRASS 8.5 for Conda is out, I will update the tutorial to use the new GRASS Tools API. I also plan to write another, more in-depth tutorial.