# AnyMap
[](https://mybinder.org/v2/gh/opengeos/anymap/HEAD)
[](https://colab.research.google.com/github/opengeos/anymap/blob/main)
[](https://pypi.python.org/pypi/anymap)
[](https://anaconda.org/conda-forge/anymap)
[](https://github.com/conda-forge/anymap-feedstock)
[](https://pepy.tech/project/anymap)
[](https://anaconda.org/conda-forge/anymap)
[](https://opensource.org/licenses/MIT)
<!-- [](https://hub.docker.com/r/opengeos/anymap/tags) -->
**A Python package for creating interactive maps with anywidget and JavaScript mapping libraries**
- GitHub repo: <https://github.com/opengeos/anymap>
- Documentation: <https://anymap.dev>
- PyPI: <https://pypi.org/project/anymap>
- Conda-forge: <https://anaconda.org/conda-forge/anymap>
- Free software: MIT License
## Features
- πΊοΈ **Interactive Maps**: Create beautiful, interactive maps in Jupyter notebooks
- π **Bidirectional Communication**: Full Python β JavaScript communication
- π± **Multi-cell Support**: Render maps in multiple notebook cells without conflicts
- π― **MapLibre Integration**: Built-in support for MapLibre GL JS
- π οΈ **Extensible**: Easy to add support for other mapping libraries
- π **Familiar API**: Similar to ipyleaflet for easy migration
## Installation
```bash
pip install anymap
```
```bash
conda install -c conda-forge anymap
```
## Quick Start
```python
from anymap import MapLibreMap
# Create a basic map
m = MapLibreMap(
center=[-122.4194, 37.7749], # San Francisco
zoom=12,
height="600px"
)
m
```
## Basic Usage
### Creating Maps
```python
from anymap import MapLibreMap
# Create a map with custom settings
m = MapLibreMap(
center=[-74.0060, 40.7128], # New York City
zoom=13,
height="500px",
bearing=45, # Map rotation
pitch=60 # 3D tilt
)
```
### Adding Markers
```python
# Add a marker with popup
m.add_marker(
lat=40.7128,
lng=-74.0060,
popup="<h3>New York City</h3><p>The Big Apple</p>"
)
```
### Working with GeoJSON
```python
# Add GeoJSON data
geojson_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-74.0060, 40.7128]
},
"properties": {"name": "NYC"}
}
]
}
m.add_geojson_layer(
layer_id="cities",
geojson_data=geojson_data,
layer_type="circle",
paint={
"circle-radius": 8,
"circle-color": "#ff0000"
}
)
```
### Event Handling
```python
def handle_click(event):
lat, lng = event['lngLat']
print(f"Clicked at: {lat:.4f}, {lng:.4f}")
m.on_map_event('click', handle_click)
```
### Dynamic Updates
```python
# Change map properties
m.set_center(-0.1278, 51.5074) # London
m.set_zoom(14)
# Animate to a location
m.fly_to(2.3522, 48.8566, zoom=15) # Paris
```
## Multi-Cell Rendering
AnyMap is designed to work seamlessly across multiple notebook cells:
```python
# Cell 1
m = MapLibreMap(center=[0, 0], zoom=2)
m
# Cell 2 - Same map instance
m.add_marker(0, 0, popup="Origin")
# Cell 3 - Display again
m
```
## Advanced Features
### Layer Management
```python
# Add and remove layers
m.add_source("my-source", {
"type": "geojson",
"data": geojson_data
})
m.add_layer("my-layer", {
"id": "my-layer",
"type": "circle",
"source": "my-source",
"paint": {"circle-radius": 5}
})
# Remove layers
m.remove_layer("my-layer")
m.remove_source("my-source")
```
### Custom JavaScript Methods
```python
# Call any MapLibre GL JS method
m.call_js_method('easeTo', {
'center': [lng, lat],
'zoom': 14,
'duration': 2000
})
```
## Examples
Check out the example notebooks in the `examples/` directory:
- `basic_usage.ipynb` - Basic map creation and interaction
- `advanced_features.ipynb` - Advanced layer management and styling
- `multi_cell_test.ipynb` - Multi-cell rendering tests
## Development
To set up for development:
```bash
git clone https://github.com/opengeos/anymap.git
cd anymap
pip install -e .
```
Run tests:
```bash
python -m unittest tests.test_anymap -v
```
## Roadmap
- β
MapLibre GL JS backend
- β
Mapbox GL JS backend
- β
Leaflet backend
- β
OpenLayers backend
- β
DeckGL backend
- β
KeplerGL backend
- π² Cesium backend
- π² Potree backend
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License - see the LICENSE file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "anymap",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "anymap",
"author": null,
"author_email": "Qiusheng Wu <giswqs@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/5b/93/6366d17dd1dce36315e24e7a110ea970782722969c37c702c83f24ea2580/anymap-0.5.0.tar.gz",
"platform": null,
"description": "# AnyMap\n\n[](https://mybinder.org/v2/gh/opengeos/anymap/HEAD)\n[](https://colab.research.google.com/github/opengeos/anymap/blob/main)\n[](https://pypi.python.org/pypi/anymap)\n[](https://anaconda.org/conda-forge/anymap)\n[](https://github.com/conda-forge/anymap-feedstock)\n[](https://pepy.tech/project/anymap)\n[](https://anaconda.org/conda-forge/anymap)\n[](https://opensource.org/licenses/MIT)\n\n<!-- [](https://hub.docker.com/r/opengeos/anymap/tags) -->\n\n**A Python package for creating interactive maps with anywidget and JavaScript mapping libraries**\n\n- GitHub repo: <https://github.com/opengeos/anymap>\n- Documentation: <https://anymap.dev>\n- PyPI: <https://pypi.org/project/anymap>\n- Conda-forge: <https://anaconda.org/conda-forge/anymap>\n- Free software: MIT License\n\n## Features\n\n- \ud83d\uddfa\ufe0f **Interactive Maps**: Create beautiful, interactive maps in Jupyter notebooks\n- \ud83d\udd04 **Bidirectional Communication**: Full Python \u2194 JavaScript communication\n- \ud83d\udcf1 **Multi-cell Support**: Render maps in multiple notebook cells without conflicts\n- \ud83c\udfaf **MapLibre Integration**: Built-in support for MapLibre GL JS\n- \ud83d\udee0\ufe0f **Extensible**: Easy to add support for other mapping libraries\n- \ud83d\ude80 **Familiar API**: Similar to ipyleaflet for easy migration\n\n## Installation\n\n```bash\npip install anymap\n```\n\n```bash\nconda install -c conda-forge anymap\n```\n\n## Quick Start\n\n```python\nfrom anymap import MapLibreMap\n\n# Create a basic map\nm = MapLibreMap(\n center=[-122.4194, 37.7749], # San Francisco\n zoom=12,\n height=\"600px\"\n)\nm\n```\n\n## Basic Usage\n\n### Creating Maps\n\n```python\nfrom anymap import MapLibreMap\n\n# Create a map with custom settings\nm = MapLibreMap(\n center=[-74.0060, 40.7128], # New York City\n zoom=13,\n height=\"500px\",\n bearing=45, # Map rotation\n pitch=60 # 3D tilt\n)\n```\n\n### Adding Markers\n\n```python\n# Add a marker with popup\nm.add_marker(\n lat=40.7128,\n lng=-74.0060,\n popup=\"<h3>New York City</h3><p>The Big Apple</p>\"\n)\n```\n\n### Working with GeoJSON\n\n```python\n# Add GeoJSON data\ngeojson_data = {\n \"type\": \"FeatureCollection\",\n \"features\": [\n {\n \"type\": \"Feature\",\n \"geometry\": {\n \"type\": \"Point\",\n \"coordinates\": [-74.0060, 40.7128]\n },\n \"properties\": {\"name\": \"NYC\"}\n }\n ]\n}\n\nm.add_geojson_layer(\n layer_id=\"cities\",\n geojson_data=geojson_data,\n layer_type=\"circle\",\n paint={\n \"circle-radius\": 8,\n \"circle-color\": \"#ff0000\"\n }\n)\n```\n\n### Event Handling\n\n```python\ndef handle_click(event):\n lat, lng = event['lngLat']\n print(f\"Clicked at: {lat:.4f}, {lng:.4f}\")\n\nm.on_map_event('click', handle_click)\n```\n\n### Dynamic Updates\n\n```python\n# Change map properties\nm.set_center(-0.1278, 51.5074) # London\nm.set_zoom(14)\n\n# Animate to a location\nm.fly_to(2.3522, 48.8566, zoom=15) # Paris\n```\n\n## Multi-Cell Rendering\n\nAnyMap is designed to work seamlessly across multiple notebook cells:\n\n```python\n# Cell 1\nm = MapLibreMap(center=[0, 0], zoom=2)\nm\n\n# Cell 2 - Same map instance\nm.add_marker(0, 0, popup=\"Origin\")\n\n# Cell 3 - Display again\nm\n```\n\n## Advanced Features\n\n### Layer Management\n\n```python\n# Add and remove layers\nm.add_source(\"my-source\", {\n \"type\": \"geojson\",\n \"data\": geojson_data\n})\n\nm.add_layer(\"my-layer\", {\n \"id\": \"my-layer\",\n \"type\": \"circle\",\n \"source\": \"my-source\",\n \"paint\": {\"circle-radius\": 5}\n})\n\n# Remove layers\nm.remove_layer(\"my-layer\")\nm.remove_source(\"my-source\")\n```\n\n### Custom JavaScript Methods\n\n```python\n# Call any MapLibre GL JS method\nm.call_js_method('easeTo', {\n 'center': [lng, lat],\n 'zoom': 14,\n 'duration': 2000\n})\n```\n\n## Examples\n\nCheck out the example notebooks in the `examples/` directory:\n\n- `basic_usage.ipynb` - Basic map creation and interaction\n- `advanced_features.ipynb` - Advanced layer management and styling\n- `multi_cell_test.ipynb` - Multi-cell rendering tests\n\n## Development\n\nTo set up for development:\n\n```bash\ngit clone https://github.com/opengeos/anymap.git\ncd anymap\npip install -e .\n```\n\nRun tests:\n\n```bash\npython -m unittest tests.test_anymap -v\n```\n\n## Roadmap\n\n- \u2705 MapLibre GL JS backend\n- \u2705 Mapbox GL JS backend\n- \u2705 Leaflet backend\n- \u2705 OpenLayers backend\n- \u2705 DeckGL backend\n- \u2705 KeplerGL backend\n- \ud83d\udd32 Cesium backend\n- \ud83d\udd32 Potree backend\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "A Python package for creating interactive maps with anywidget and JavaScript mapping libraries",
"version": "0.5.0",
"project_urls": {
"Homepage": "https://github.com/opengeos/anymap"
},
"split_keywords": [
"anymap"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "087ebe7512e60ff7a23cee2770a4887135f9b65d5c341a35134acace6d70a282",
"md5": "3b70574144f373c53a60d38440c180eb",
"sha256": "528aa242d6b2774f4949e2c833504a77df090ec9644b99fffb75570fc6ff5cdf"
},
"downloads": -1,
"filename": "anymap-0.5.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "3b70574144f373c53a60d38440c180eb",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.9",
"size": 146633,
"upload_time": "2025-08-18T22:10:28",
"upload_time_iso_8601": "2025-08-18T22:10:28.483865Z",
"url": "https://files.pythonhosted.org/packages/08/7e/be7512e60ff7a23cee2770a4887135f9b65d5c341a35134acace6d70a282/anymap-0.5.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5b936366d17dd1dce36315e24e7a110ea970782722969c37c702c83f24ea2580",
"md5": "4de0945184f4ce444b2129776082d5e8",
"sha256": "c2e7fd28842871c07e12f8979ba3428315401d7916a9ddc3653e497abf0ae32a"
},
"downloads": -1,
"filename": "anymap-0.5.0.tar.gz",
"has_sig": false,
"md5_digest": "4de0945184f4ce444b2129776082d5e8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 125365,
"upload_time": "2025-08-18T22:10:29",
"upload_time_iso_8601": "2025-08-18T22:10:29.717836Z",
"url": "https://files.pythonhosted.org/packages/5b/93/6366d17dd1dce36315e24e7a110ea970782722969c37c702c83f24ea2580/anymap-0.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-18 22:10:29",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "opengeos",
"github_project": "anymap",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "anywidget",
"specs": [
[
">=",
"0.9.0"
]
]
},
{
"name": "geopandas",
"specs": []
},
{
"name": "ipyvuetify",
"specs": []
},
{
"name": "ipywidgets",
"specs": [
[
">=",
"8.0.0"
]
]
},
{
"name": "numpy",
"specs": []
},
{
"name": "pandas",
"specs": []
},
{
"name": "psutil",
"specs": []
},
{
"name": "pystac-client",
"specs": []
},
{
"name": "requests",
"specs": []
},
{
"name": "traitlets",
"specs": [
[
">=",
"5.0.0"
]
]
},
{
"name": "xyzservices",
"specs": []
}
],
"lcname": "anymap"
}