Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improvement: better leafmap formatters #2852

Merged
merged 3 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/api/plotting.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ selection, consider using [`mo.ui.altair_chart`](#marimo.ui.altair_chart).
.. autofunction:: marimo.mpl.interactive
```

## Leafmap support

marimo supports rendering [Leafmap](https://leafmap.org/) maps using the `folium` and `plotly` backends.

## Other plotting libraries

You can use all the popular plotting libraries with marimo. Such as:
Expand Down
60 changes: 44 additions & 16 deletions marimo/_output/formatters/leafmap_formatters.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# Copyright 2024 Marimo. All rights reserved.
from __future__ import annotations

from typing import Any, cast

from marimo._messaging.mimetypes import KnownMimeType
from marimo._output.builder import h
from marimo._output.formatters.formatter_factory import FormatterFactory
from marimo._output.formatters.utils import src_or_src_doc
from marimo._output.md import md
from marimo._output.utils import flatten_string


Expand All @@ -16,18 +15,21 @@ def package_name() -> str:
return "leafmap"

def register(self) -> None:
import leafmap # type: ignore[import-not-found]
# Different backends
# plotly is handled by PlotlyFormatter
import leafmap.foliumap as leafmap_folium # type: ignore[import-untyped]
import leafmap.leafmap as leafmap # type: ignore[import-untyped]

from marimo._output import formatting

@formatting.formatter(leafmap.folium.Map)
@formatting.formatter(leafmap_folium.Map)
def _show_folium_map(
fmap: leafmap.folium.Map,
fmap: leafmap_folium.Map,
) -> tuple[KnownMimeType, str]:
# leafmap.folium.Map has a _repr_html_, which we have
# another custom formatter for, but this wraps the map in an
# additional iframe which can cause weird layout issues
html_content = cast(Any, fmap).to_html()
html_content = fmap.to_html()
return (
"text/html",
flatten_string(
Expand All @@ -44,20 +46,46 @@ def _show_folium_map(
def _show_map(
lmap: leafmap.Map,
) -> tuple[KnownMimeType, str]:
# 540px is the pixel height that makes the map fit in the
# notebook without scrolling
height = lmap.layout.height or "540px"
width = lmap.layout.width or "100%"
html_content = lmap.to_html(width=width, height=height)
del lmap
return (
"text/html",
(
md(
"""
leafmap.Map objects are not supported in marimo.
Please change the backend to `folium` or `plotly`.

```python
import leafmap.foliumap as leafmap
# or
import leafmap.plotlymap as leafmap
```
"""
)
.callout()
.text,
)

# Kepler is an optional dependency
# so we don't want this to fail if it's not installed
try:
import leafmap.kepler as leafmap_kepler # type: ignore[import-untyped]

@formatting.formatter(leafmap_kepler.Map)
def _show_kepler_map(
kmap: leafmap_kepler.Map,
) -> tuple[KnownMimeType, str]:
contents = kmap.to_html() or ""
return (
"text/html",
flatten_string(
h.iframe(
**src_or_src_doc(html_content),
**src_or_src_doc(contents),
onload="__resizeIframe(this)",
style="min-height: 540px",
width="100%",
)
)
),
)
),
)

except (ImportError, ModuleNotFoundError):
pass
1 change: 1 addition & 0 deletions marimo/_output/formatters/plotly_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def register(self) -> None:
from marimo._output import formatting

@formatting.formatter(plotly.graph_objects.Figure)
@formatting.formatter(plotly.graph_objects.FigureWidget)
def _show_plotly_figure(
fig: plotly.graph_objects.Figure,
) -> tuple[KnownMimeType, str]:
Expand Down
86 changes: 86 additions & 0 deletions marimo/_smoke_tests/third_party/leafmap/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import marimo

__generated_with = "0.9.17"
app = marimo.App(width="medium")


@app.cell
def __():
import marimo as mo
return (mo,)


@app.cell
def __():
import leafmap as default_leamap
import leafmap.leafmap as leafmap
import leafmap.foliumap as leafmap_folium
import leafmap.plotlymap as leafmap_plotly
return default_leamap, leafmap, leafmap_folium, leafmap_plotly


@app.cell
def __():
import keplergl
import leafmap.kepler as leafmap_kepler
return keplergl, leafmap_kepler


@app.cell
def __(default_leamap):
default_leamap.Map
return


@app.cell
def __(leafmap):
data = leafmap.examples.datasets.countries_geojson
return (data,)


@app.cell
def __(data, leafmap):
_m = leafmap.Map()
_m.add_data(
data,
column="POP_EST",
scheme="Quantiles",
cmap="Blues",
legend_title="Population",
)
_m
return


@app.cell
def __(leafmap_plotly):
_m = leafmap_plotly.Map(center=(40, -100), zoom=3, height=500)
_m
return


@app.cell
def __(data, leafmap_folium):
_m = leafmap_folium.Map()
_m.add_data(
data,
column="POP_EST",
scheme="Quantiles",
cmap="Blues",
legend_title="Population",
)
_m
return


@app.cell
def __(leafmap_kepler):
_m = leafmap_kepler.Map(
center=[40, -100], zoom=2, height=600, widescreen=False
)
_m
return


if __name__ == "__main__":
app.run()
Loading