🖥️ Lecture slides — Session 02 (Fri Oct 2)
What do you need to run your Python code?¶
Python. Most packages today require Python 3.10 or newer; this book uses Python 3.12. Your laptop may come with Python preinstalled, but never rely on the system Python — use an environment manager (below).
Some code: files with a
.pyextension, or notebooks.Dependencies: modules that contain related functions (e.g., numpy, scipy, pandas, scikit-learn), imported in the Python code as
import numpy as np
To run Python code with the proper dependencies, you define an environment: a version of Python + some packages + versions of those packages.
What are virtual environments?¶
A virtual environment is an isolated copy of a specific Python interpreter together with specific versions of external libraries.
- You may have different projects on your computer needing different versions of packages.
- You give your code to a friend, or to an AI assistant running it on another machine.
- Some of your packages depend on other packages, at specific versions. How do you make sure everyone has the right version of everything?
The answer is: you never install packages “globally”. Each project gets its own environment, declared in a file that lives in the project repository.
The tools of 2026¶
Several tools manage environments. Here is the map:
- pixi — what this book uses. A fast, project-based manager that installs conda-forge and PyPI packages and writes a lockfile automatically.
- uv — a fast manager for pure-Python projects (PyPI packages only). A good choice when you need no compiled geospatial or GPU stack from conda-forge.
- miniforge / mamba — a minimal conda distribution preconfigured for the community conda-forge channel, with
mambaas a fast solver. Use this if you want classic conda workflows. - conda — the original scientific package manager. Still everywhere, and its concepts (channels,
environment.yml) remain background knowledge worth having.
We no longer recommend downloading Anaconda: the Anaconda distribution’s licensing changed in 2024 and its default channel now requires a paid license for many institutional uses. miniforge with conda-forge avoids the issue entirely.
pixi: what this book uses¶
pixi manages environments per project. The environment is declared in pixi.toml, resolved into pixi.lock, and installed under .pixi/ inside the project directory. There is no “activate the right environment” step to forget: pixi run always uses the project’s own environment.
Install pixi itself first (once per machine). On macOS and Linux:
curl -fsSL https://pixi.sh/install.sh | shor, on macOS with Homebrew, brew install pixi. Restart the terminal, then verify:
pixi --versionOn Windows, work inside WSL2 and use the Linux command above; see the setup walkthrough in 1.9.
Start a project:
pixi init myproject
cd myprojectAdd packages:
pixi add python=3.12 numpy pandas matplotlibThis edits pixi.toml:
[workspace]
name = "myproject"
channels = ["conda-forge"]
platforms = ["osx-arm64", "linux-64"]
[dependencies]
python = "3.12.*"
numpy = ">=2"
pandas = ">=2.2"
matplotlib = "*"and writes pixi.lock, which records the exact version and hash of every package (including transitive dependencies) for every listed platform. Commit both files.
Run things inside the environment:
pixi run python analysis.py
pixi run jupyter labThis book itself is built this way: pixi install then pixi run build from the repository root.
Lockfiles are reproducibility. pixi.toml says what you asked for (“numpy, at least version 2”); pixi.lock says what you actually got (numpy 2.5.0, this build, this hash). Someone who clones your repository and runs pixi install on the same platform gets the identical set of packages — next month, or on a cloud machine. The lockfile pins packages per platform: each entry under platforms in pixi.toml gets its own resolved list, so a collaborator on another OS gets the same package versions in that OS’s builds, not a byte-identical environment. Numerical results can still differ slightly across platforms and hardware; 5.1 treats reproducibility as agreement within a stated tolerance for exactly this reason. Pinned environments are the difference between “works on my machine” and a reproducible analysis, and they are the foundation of the workflow practices in Chapter 5.
uv: for pure-Python projects¶
uv plays the same role for PyPI-only projects, using the standard pyproject.toml:
uv init myproject
uv add numpy pandas
uv run python analysis.pyIt writes a uv.lock with the same reproducibility logic. If your project needs conda-forge packages (GDAL, CUDA-enabled PyTorch builds, obspy), prefer pixi.
conda background¶
You will encounter environment.yml files in many geoscience repositories, so you should be able to read and use them. With miniforge installed:
conda env create --file environment.yml
conda env list
conda activate myenv
conda deactivate
conda env remove --yes --name myenv(With mamba, replace conda with mamba for faster solves.)
Example environment.yml¶
name: mlgeo
channels:
- conda-forge
dependencies:
- python=3.12
- jupyter
- matplotlib
- numpy>=2
- pandas>=2.2
- scipy
- scikit-learn
- pytorchpixi can import these: pixi init --import environment.yml.
Freezing a pip environment¶
The older idiom for recording exact versions in pip-based workflows:
pip freeze > requirements.txtwhich produces pinned entries like
matplotlib==3.10.0
numpy==2.2.1
pandas==2.2.3This is a flat snapshot, without hashes or platform information — a lockfile’s weaker ancestor. It still works, but for new projects prefer pixi or uv, which maintain the lockfile for you.