Volumetric Density-Equalizing Reference Map — 3D shape deformation and 2D cartogram generation
Project description
pyVDERM
Volumetric Density-Equalizing Reference Map — a Python implementation of the VDERM algorithm for 3D shape deformation and (new in v2.0) 2D cartogram generation from GeoJSON / Shapefile inputs.
Overview
pyVDERM implements the Volumetric Density-Equalizing Reference Map (VDERM) method by Choi & Rycroft (2020). VDERM is a 3D generalization of the diffusion-based cartogram method, enabling volume-preserving deformations of 3D objects based on prescribed density distributions.
v2.0 extends this to 2D using the same diffusion-advection process — no FFTs, just the VDERM physics with one spatial dimension removed — making 2D cartograms straightforward to produce from standard geographic files.
Applications
- 3D data visualization and cartograms
- 2D geographic cartograms from GeoJSON / Shapefiles
- Adaptive mesh refinement
- Shape modeling and morphing
Key Features
- 3D: Fast regular grid interpolation, STL / VTK / XYZ export, optional PyMeshLab mesh support
- 2D (new): GeoJSON and Shapefile input, GeoTIFF built-in densities, 2D scatter / heatmap visualization
- Comprehensive matplotlib animations for both 2D and 3D pipelines
- Progress tracking with intermediate state exports
- Automatic grid sizing with customizable padding
Installation
Base / lite (no optional dependencies)
pip install pyVDERM
With 2-D geographic I/O (GeoJSON, Shapefile, GeoTIFF)
pip install pyVDERM[2D]
With 3-D mesh support (STL, OBJ, Poisson reconstruction)
pip install pyVDERM[3D]
Full installation
pip install pyVDERM[all]
Development
git clone https://github.com/jspector792/pyVDERM.git
cd pyVDERM
pip install -e .[all]
Quick Start — 3D
import pyVDERM as vd
import numpy as np
# 1. Load a mesh and sample a surface point cloud
surface_points, normals = vd.create_pcd('mesh.stl', n_pts=25000)
# 2. Create computational grid (automatically sized)
params = vd.make_initial_grid(surface_points, max_points=32768)
# 3. Initialize VDERM grid and set density
grid = vd.VDERMGrid(params['shape'], params['h'], params['min_bounds'])
def my_density(x, y, z):
r = np.sqrt((x - 1.5)**2 + (y - 1.5)**2 + (z - 1.5)**2)
return 1.0 + 3.0 * np.exp(-5 * r**2)
grid.set_density(my_density)
# 4. Run deformation
result = vd.run_VDERM(grid, n_max=100, max_eps=0.02)
# 5. Apply deformation to surface and export
final_surface = vd.interpolate_to_surface(
surface_points, params, result.get_displacement_field()
)
vd.export_mesh_file('deformed_mesh.stl', final_surface)
Quick Start — 2D Cartogram
import pyVDERM as vd
# 1. Load geographic boundary (GeoJSON or Shapefile)
pts, crs = vd.read_geojson('countries.geojson') # or read_shapefile()
# 2. Create 2D grid sized to the data
params = vd.make_initial_grid_2d(pts, max_points=16384)
grid = vd.VDERMGrid2D(params['shape'], params['h'], params['min_bounds'])
# 3. Set density from a GeoTIFF (e.g. population raster)
vd.density_from_geotiff(grid, 'population.tif')
# or define analytically: grid.set_density(lambda x, y: ...)
# 4. Run deformation — run_VDERM works for both 2D and 3D grids
result = vd.run_VDERM(grid, n_max=200, max_eps=0.02)
# 5. Apply deformation to map points
deformed = vd.interpolate_to_map_2d(
pts, params, result.get_displacement_field()
)
# 6. Visualize
dens = vd.interpolate_densities_2d(pts, result)
vd.plot_map_before_after(pts, deformed, densities=dens,
title='Population Cartogram')
Examples
Detailed Jupyter notebook examples are in the examples/ directory:
- 01_quickStart.ipynb: Basic 3-D workflow and concepts
- 02_boundaryConditions.ipynb: Boundary condition effects
- 03_densityFields.ipynb: Different density functions
- 04_tracking.ipynb: Animations and intermediate exports
- 05_pyVDERMlite.ipynb: 3-D point-cloud workflow without mesh dependencies
- 06_2D_quickStart.ipynb: 2-D quick start — 2×2 grid from scratch (base install)
- 07_worldCartogram.ipynb: World population cartogram from GeoJSON / Shapefile / GeoTIFF (
pip install pyVDERM[2D]) - 08_2D_lite.ipynb: 2-D lite mode — XY CSV files only (base install)
File Formats
3D — XYZ (space-delimited text)
# 3 cols: positions only
x y z
# 4 cols: positions + density
x y z rho
# 6 cols: positions + normals / velocities
x y z n_x n_y n_z
# 7 cols: complete
x y z n_x n_y n_z rho
2D — CSV (space-delimited text)
# 2 cols: positions only
x y
# 3 cols: positions + density
x y rho
Geographic inputs: GeoJSON, Shapefile (via geopandas), GeoTIFF density rasters (via rasterio).
Tips
Grid Resolution
- Quick test / 2D: 4 000–16 000 points (64²–128²)
- Standard 3D: 30 000–50 000 points (30–35³)
- High quality 3D: 100 000–250 000 points (45–60³)
Density Field Design
- Keep densities positive: ρ > 0
- Avoid sharp discontinuities near object boundaries
- Embed large gradients in a uniform density sea rather than against a wall
Numerical Stability
If epsilon becomes very large or negative, reduce the timestep:
vd.run_VDERM(grid, dt=0.001)
Dependencies
| Dependency | Required for |
|---|---|
| numpy, scipy, matplotlib, tqdm | Always required |
| geopandas, rasterio, shapely | 2-D geographic I/O (pip install pyVDERM[2D]) |
| pymeshlab | 3-D mesh I/O and reconstruction (pip install pyVDERM[3D]) |
Citation
@article{choi2021volumetric,
title={Volumetric density-equalizing reference map with applications},
author={Choi, Gary Pui-Tung and Rycroft, Chris H},
journal={Journal of Scientific Computing},
volume={86},
number={3},
pages={1--26},
year={2021},
publisher={Springer}
}
@software{vderm2026,
title={pyVDERM: A Python implementation of the Volumetric Density-Equalizing Reference Map},
author={Jonah Spector},
year={2026},
url={https://github.com/jspector792/pyVDERM}
}
License
MIT — see LICENSE.
Acknowledgments
- Original VDERM algorithm: Gary P.T. Choi and Chris H. Rycroft
- Diffusion cartogram method: Gastner & Newman (2004)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyvderm-0.2.0.tar.gz.
File metadata
- Download URL: pyvderm-0.2.0.tar.gz
- Upload date:
- Size: 50.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
475b49d815749f28b8c291789dbf760fc82988de3fb4372c3e6c209e3931ea9e
|
|
| MD5 |
ac22b7105c78f6600375f350b2b7ffab
|
|
| BLAKE2b-256 |
6a48b3a0082d612cf3cc2c5f066a6b597df748759f1811181a25e3f55cec4f03
|
File details
Details for the file pyvderm-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pyvderm-0.2.0-py3-none-any.whl
- Upload date:
- Size: 41.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9cc0f46a5e6c1b0f965cc050fa428ed00e6919d985f1fee34efa45e277dc1b0c
|
|
| MD5 |
0cf3a171f6bc51c592852c417e973ef0
|
|
| BLAKE2b-256 |
4593830158f89bbd5557909bd73c28c609622be3a63cfefc99465b5b1cdedf25
|