Skip to main content

Volumetric Density-Equalizing Reference Map — 3D shape deformation and 2D cartogram generation

Project description

pyVDERM

PyPI version GitHub release Python 3.8+ License: MIT

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

pyvderm-0.2.0.tar.gz (50.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyvderm-0.2.0-py3-none-any.whl (41.0 kB view details)

Uploaded Python 3

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

Hashes for pyvderm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 475b49d815749f28b8c291789dbf760fc82988de3fb4372c3e6c209e3931ea9e
MD5 ac22b7105c78f6600375f350b2b7ffab
BLAKE2b-256 6a48b3a0082d612cf3cc2c5f066a6b597df748759f1811181a25e3f55cec4f03

See more details on using hashes here.

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

Hashes for pyvderm-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9cc0f46a5e6c1b0f965cc050fa428ed00e6919d985f1fee34efa45e277dc1b0c
MD5 0cf3a171f6bc51c592852c417e973ef0
BLAKE2b-256 4593830158f89bbd5557909bd73c28c609622be3a63cfefc99465b5b1cdedf25

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page