Converting between raster formats¶
Dataset.to_file(path) picks the output driver from the file extension, so most raster
conversions are one call. NetCDF has its own notebook
(GeoTIFF ↔ NetCDF); this page covers the rest.
| Target | Extension / call | Notes |
|---|---|---|
| GeoTIFF | .tif |
the default raster format |
| ASCII grid | .asc |
single band only (pass band=) |
| Cloud Optimized GeoTIFF | to_file(driver='COG') |
tiled + overviews |
| Zarr | to_zarr(...) / from_zarr(...) |
chunked, cloud-native ([lazy] extra) |
Setup¶
%matplotlib inline
import tempfile
from pathlib import Path
import numpy as np
DATA = Path('../../../examples/data')
WORK = Path(tempfile.mkdtemp(prefix='pyramids-convert-')) # scratch dir for outputs
DATA.is_dir(), WORK.is_dir()
(True, True)
from pyramids.dataset import Dataset
ds = Dataset.read_file(DATA / 'acc4000.tif')
ds.shape, ds.epsg
2026-07-11 14:37:25 | INFO | pyramids.base.config | Logging is configured.
((1, 13, 14), 32618)
Plot the source raster band before converting it — every format below holds this same data.
ds.plot(band=0, title='Source GeoTIFF (acc4000)')
<cleopatra.array_glyph.ArrayGlyph at 0x7f12548a8ad0>
/home/runner/work/pyramids/pyramids/.pixi/envs/docs/lib/python3.14/site-packages/matplotlib/colors.py:816: RuntimeWarning: overflow encountered in multiply xa *= self.N
GeoTIFF ↔ ASCII grid¶
Esri ASCII grids hold a single band, so pass the band index. The extension drives the driver.
asc = WORK / 'acc.asc'
ds.to_file(asc, band=0)
# Round-trip back to GeoTIFF.
back = Dataset.read_file(asc)
tif_again = WORK / 'from_asc.tif'
back.to_file(tif_again)
back.shape, Dataset.read_file(tif_again).shape
((1, 13, 14), (1, 13, 14))
The ASCII grid read back (back) is pixel-identical to the source — plot it to confirm the round-trip preserved the data.
back.plot(band=0, title='Round-tripped from ASCII grid')
<cleopatra.array_glyph.ArrayGlyph at 0x7f13088311d0>
/home/runner/work/pyramids/pyramids/.pixi/envs/docs/lib/python3.14/site-packages/matplotlib/colors.py:816: RuntimeWarning: overflow encountered in multiply xa *= self.N
GeoTIFF → Cloud Optimized GeoTIFF (COG)¶
Pass driver='COG' to write a tiled, overview-bearing COG that streams efficiently over HTTP.
cog = WORK / 'acc_cog.tif'
ds.to_file(cog, driver='COG')
cog.exists(), cog.stat().st_size > 0
(True, True)
GeoTIFF ↔ Zarr¶
Zarr stores the raster as chunked arrays (one file per chunk) with the geobox in the metadata —
ideal for parallel/cloud workflows. Needs the [lazy] extra.
store = WORK / 'acc.zarr'
ds.to_zarr(store, chunks=(1, 16, 16), mode='w')
sorted(p.name for p in store.iterdir())[:5]
['data', 'spatial_ref', 'x', 'y', 'zarr.json']
# Reopen the store and write it back to GeoTIFF.
from_zarr = Dataset.from_zarr(store)
tif_from_zarr = WORK / 'from_zarr.tif'
from_zarr.to_file(tif_from_zarr)
from_zarr.epsg, Dataset.read_file(tif_from_zarr).shape
(32618, (1, 13, 14))
Reopening the Zarr store yields the same raster — plot from_zarr to verify the chunked store preserved the geobox and values.
from_zarr.plot(band=0, title='Reopened from Zarr')
<cleopatra.array_glyph.ArrayGlyph at 0x7f124a4a2c10>
/home/runner/work/pyramids/pyramids/.pixi/envs/docs/lib/python3.14/site-packages/matplotlib/colors.py:816: RuntimeWarning: overflow encountered in multiply xa *= self.N
Notes¶
to_fileinfers the driver from the extension (.tif,.asc, …); passdriver=to override (e.g.'COG').- ASCII grids are single-band — convert one band at a time.
- See also: GeoTIFF ↔ NetCDF and Vector formats.