Skip to main content

bharat-choropleth

bharat-choropleth creates dependency-free, accessible static SVG choropleths from TopoJSON. It is a Python sibling to the repository’s React, plain-JavaScript, and Flutter renderers, intended for reports, generated web pages, and notebooks that should not need a browser or JavaScript runtime.

It includes no boundaries. Pass a mapping or path to your own TopoJSON and retain the source attribution and licence for any boundary bundle you use. The repository’s prepared bundles are under data/generated and their notices are documented in data/ATTRIBUTION.md.

Install

pip install bharat-choropleth

# Only when you need a Matplotlib axes rather than SVG:
pip install 'bharat-choropleth[matplotlib]'

# Only when you need interactive state-to-district controls in Jupyter:
pip install 'bharat-choropleth[notebook]'

Generate an SVG

from bharat_choropleth import render_svg

values = {
    "in-cs-30-goa": 6,
    "in-cs-24-gujarat": 7,
    "in-cs-27-maharashtra": 41,
}

svg = render_svg(
    "data/generated/current-2019-states/states.topo.json",
    values,
    object_name="states",
    title="Example state metric",
    description="A static map. Regions without a supplied value are marked as no data.",
)
open("states.svg", "w", encoding="utf-8").write(svg)

render_svg returns a complete <svg> element with a title, optional description, per-region accessible labels, an even-odd fill rule, and a lower-to-higher legend. Features with missing, invalid, or non-finite values receive the distinct no-data colour; they are never treated as low values.

Decode once, render repeatedly

from bharat_choropleth import decode_topology, render_svg

states = decode_topology("states.topo.json", object_name="states")
svg = render_svg(states, {"in-cs-30-goa": 6})

The decoder understands TopoJSON’s quantized delta arcs, reversed arc indexes, holes, polygons, and multi-polygons. Every part is retained—an archipelago is rendered as separate islands, never as a fabricated enclosing polygon.

Optional Matplotlib

from bharat_choropleth.matplotlib import render_matplotlib

ax = render_matplotlib("states.topo.json", values, object_name="states")
ax.figure.savefig("states.png", dpi=180, bbox_inches="tight")

The Matplotlib adapter is an extra, so importing bharat_choropleth does not pull in Matplotlib or any other rendering dependency.

Jupyter drill-down

Install the notebook extra for an ipywidgets state selector and lazy district loader, with an optional third level below it. The control updates its inline SVG when a region is selected; it has no browser-map or JavaScript runtime dependency.

from pathlib import Path
from bharat_choropleth.notebook import notebook_drilldown

root = Path.cwd()
states = root / "data/generated/current-2019-states/states.topo.json"
district_dir = root / "data/generated/current-2019-districts/districts"

map_control = notebook_drilldown(
    states,
    {"in-cs-30-goa": 6, "in-cs-31-lakshadweep": 43},
    district_loader=lambda state_id: district_dir / f"{state_id}.topo.json",
    states_object_name="states",
)
map_control.widget  # Display this as the last Jupyter cell expression.

Pass district_values as either a {state_id: {district_id: value}} mapping or a state_id -> {district_id: value} callable to colour the district view.

Add sub_district_loader for a third level — tehsils, taluks, mandals and blocks — and a district selector appears beside the state one. It follows the same contract as the JavaScript, React and Flutter packages: return None for a district with no sub-district level and it stays a leaf, keeping the district view rather than opening an empty one, and is not offered again. Back then steps one level at a time rather than returning straight to the national map.

sub_district_dir = root / "data/generated/current-2019-subdistricts/subdistricts"

def load_sub_districts(district_id):
    path = sub_district_dir / f"{district_id}.topo.json"
    return path if path.exists() else None  # three districts genuinely have none

map_control = notebook_drilldown(
    states,
    {"in-cs-30-goa": 6, "in-cs-31-lakshadweep": 43},
    district_loader=lambda state_id: district_dir / f"{state_id}.topo.json",
    sub_district_loader=load_sub_districts,
    states_object_name="states",
)

sub_district_values takes the same two shapes as district_values, keyed by district id. Omit sub_district_loader and the control stays state-to-district with no district selector shown at all.

API

Item Purpose
load_topology(source) Load a TopoJSON mapping or JSON file path.
decode_topology(source, object_name=...) Decode Polygon/MultiPolygon areas into immutable Feature objects.
ColorScale.fit(values) Fit the shared low-to-high colour ramp to finite values.
render_svg(source, values, ...) Create a complete static, accessible SVG string.
bharat_choropleth.matplotlib.render_matplotlib(...) Optional static Matplotlib renderer.
bharat_choropleth.notebook.notebook_drilldown(...) Optional ipywidgets state-to-district-to-sub-district SVG control.

Develop and package

python -m unittest discover -s tests -v
python -m build
twine check dist/*

Publishing to PyPI is intentionally a separate, identity-bound action:

python -m twine upload --repository testpypi dist/*  # optional first check
python -m twine upload dist/*

Never commit a PyPI token or generated third-party boundary data without first checking its redistribution conditions.

Metadata

Release files for bharat-choropleth 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bharat-choropleth 0.2.0
File Size Uploaded Provenance Actions
bharat_choropleth-0.2.0.tar.gz 18.8 kB Without provenance Details for bharat_choropleth-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bharat-choropleth 0.2.0
File Interpreter ABI Platform Actions
bharat_choropleth-0.2.0-py3-none-any.whl Python 3 none any Details for bharat_choropleth-0.2.0-py3-none-any.whl

Total release size: 35.5 kB

Release files / bharat_choropleth-0.2.0.tar.gz

Download URL bharat_choropleth-0.2.0.tar.gz
Size 18.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d257e701bc036101cde6fd06661c15059212b40b204f92dbcde4c5c9c83ceeec
BLAKE2b-256 checksum
How to use checksums
5e75dc8c0995d6294ffe1efd29cfd66d893eaf19698c12e53f68e4a2b430bdd1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

Release files / bharat_choropleth-0.2.0-py3-none-any.whl

Download URL bharat_choropleth-0.2.0-py3-none-any.whl
Size 16.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c998226a443ab6bc5dd22d91a23f304aae5dc66e331bf7bf6e6ef64fc437e5e4
BLAKE2b-256 checksum
How to use checksums
9a4944c45feef00e5c4bef31cb9c831a4981ec36fd6cc56921371c642159f404
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

Security for bharat-choropleth 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page