Make beautiful maps with Leaflet.js & Python
—
Helper functions, color maps, JavaScript integration utilities, and styling tools for advanced customization and programmatic map control.
Tools for embedding custom JavaScript code and creating dynamic interactive behaviors.
class JsCode:
"""
Wrapper for embedding JavaScript code in map elements.
Parameters:
- js_code: str, JavaScript code to embed
Returns:
JsCode instance that can be used in place of strings for dynamic behavior
"""
def __init__(self, js_code): ...Color mapping functionality for data-driven visualizations and styling.
class ColorMap:
"""
Base class for color mapping functionality.
Parameters:
- colors: list, color values (hex, rgb, or named colors)
- index: list, data values corresponding to colors (optional)
- vmin: float, minimum data value (default 0)
- vmax: float, maximum data value (default 1)
- caption: str, colormap legend title
Returns:
ColorMap instance
"""
def __init__(
self,
colors,
index=None,
vmin=0,
vmax=1,
caption=''
): ...
def to_step(self, n=6, data=None, method='linear', quantiles=None): ...
def to_linear(self): ...
class LinearColormap:
"""
Linear interpolation between color stops for continuous data visualization.
Parameters:
- colors: list, color values for interpolation
- index: list, data values at color stops (optional)
- vmin: float, minimum data value (default 0)
- vmax: float, maximum data value (default 1)
- caption: str, colormap legend title
Returns:
LinearColormap instance
"""
def __init__(
self,
colors,
index=None,
vmin=0,
vmax=1,
caption=''
): ...
def scale(self, vmin, vmax): ...
def to_step(self, n=6, data=None, method='linear', quantiles=None): ...
class StepColormap:
"""
Discrete color steps for categorical or binned data visualization.
Parameters:
- colors: list, discrete color values
- index: list, bin edges or category values
- vmin: float, minimum data value (default 0)
- vmax: float, maximum data value (default 1)
- caption: str, colormap legend title
Returns:
StepColormap instance
"""
def __init__(
self,
colors,
index=None,
vmin=0,
vmax=1,
caption=''
): ...
def scale(self, vmin, vmax): ...
def to_linear(self): ...Foundation classes for creating custom HTML elements and containers (imported from branca).
class Element:
"""
Base class for all HTML elements in folium maps.
Parameters:
- template: Template, Jinja2 template for rendering
Returns:
Element instance
"""
def __init__(self, template=None): ...
def render(self, **kwargs): ...
def add_child(self, child, name=None, index=None): ...
def add_to(self, parent): ...
class Figure:
"""
Top-level container for complete HTML documents and maps.
Parameters:
- width: str or int, figure width (default '100%')
- height: str or int, figure height (default '100%')
- left: str, left margin (default '0%')
- top: str, top margin (default '0%')
- position: str, CSS positioning (default 'relative')
- title: str, HTML document title
Returns:
Figure instance
"""
def __init__(
self,
width='100%',
height='100%',
left='0%',
top='0%',
position='relative',
title=None
): ...
def save(self, outfile): ...
def show_in_browser(self): ...
class Html:
"""
HTML content element for embedding raw HTML.
Parameters:
- data: str, HTML content
- script: bool, treat as script tag (default False)
Returns:
Html instance
"""
def __init__(self, data, script=False): ...
class Div:
"""
HTML div container element.
Parameters:
- text: str, text content for the div
- script: bool, treat as script tag (default False)
Returns:
Div instance
"""
def __init__(self, text='', script=False): ...
class IFrame:
"""
HTML iframe element for embedding external content.
Parameters:
- html: str, HTML content to embed
- width: str or int, iframe width (default '100%')
- height: str or int, iframe height (default '100%')
Returns:
IFrame instance
"""
def __init__(
self,
html='',
width='100%',
height='100%'
): ...Components for including external CSS and JavaScript resources.
class CssLink:
"""
Link to external CSS stylesheet.
Parameters:
- href: str, CSS file URL
- download: bool, mark for download (default False)
Returns:
CssLink instance
"""
def __init__(self, href, download=False): ...
class JavascriptLink:
"""
Link to external JavaScript file.
Parameters:
- src: str, JavaScript file URL
- download: bool, mark for download (default False)
Returns:
JavascriptLink instance
"""
def __init__(self, src, download=False): ...
class Link:
"""
Generic HTML link element.
Parameters:
- href: str, link URL
- download: bool, mark for download (default False)
Returns:
Link instance
"""
def __init__(self, href, download=False): ...Base classes for complex interactive map elements.
class MacroElement:
"""
Base class for complex map elements that generate HTML, CSS, and JavaScript.
Returns:
MacroElement instance
"""
def __init__(self): ...
def render(self, **kwargs): ...
def add_child(self, child, name=None, index=None): ...
def add_to(self, parent): ...import folium
from folium.utilities import JsCode
m = folium.Map(location=[45.52, -122.67], zoom_start=12)
# Custom JavaScript for dynamic marker behavior
marker_js = JsCode("""
function(e) {
var marker = e.target;
var popup = marker.getPopup();
var currentTime = new Date().toLocaleTimeString();
popup.setContent('Clicked at: ' + currentTime);
marker.openPopup();
}
""")
# Add marker with custom click behavior
marker = folium.Marker([45.52, -122.67], popup='Click me!')
# Note: In practice, custom JavaScript events are added via the _template system
# This is a simplified example of the JsCode usage pattern
marker.add_to(m)
m.save('custom_js.html')import folium
from folium import LinearColormap, StepColormap
import pandas as pd
import numpy as np
# Sample data
data = pd.DataFrame({
'location': [[45.51, -122.68], [45.52, -122.67], [45.53, -122.66]],
'temperature': [15.2, 18.7, 22.1],
'category': ['cold', 'moderate', 'warm']
})
m = folium.Map(location=[45.52, -122.67], zoom_start=13)
# Create linear colormap for temperature
temp_colormap = LinearColormap(
colors=['blue', 'cyan', 'yellow', 'red'],
vmin=data['temperature'].min(),
vmax=data['temperature'].max(),
caption='Temperature (°C)'
)
temp_colormap.add_to(m)
# Add temperature-colored circles
for idx, row in data.iterrows():
color = temp_colormap(row['temperature'])
folium.CircleMarker(
location=row['location'],
radius=15,
popup=f"Temperature: {row['temperature']}°C",
color=color,
fill=True,
fillColor=color,
fillOpacity=0.7
).add_to(m)
# Create step colormap for categories
category_colors = ['blue', 'orange', 'red']
category_colormap = StepColormap(
colors=category_colors,
index=['cold', 'moderate', 'warm'],
caption='Temperature Category'
)
category_colormap.add_to(m)
m.save('colormap_example.html')import folium
from branca.element import Template, MacroElement
# Create custom element class
class CustomLegend(MacroElement):
"""Custom legend element with dynamic content."""
_template = Template("""
{% macro script(this, kwargs) %}
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend');
div.innerHTML = `
<h4>{{ this.title }}</h4>
{% for item in this.items %}
<i style="background:{{ item.color }}"></i> {{ item.label }}<br>
{% endfor %}
`;
return div;
};
legend.addTo({{ this._parent.get_name() }});
{% endmacro %}
""")
def __init__(self, title, items):
super().__init__()
self._name = 'CustomLegend'
self.title = title
self.items = items
# Use custom legend
m = folium.Map(location=[45.52, -122.67], zoom_start=12)
# Add some colored markers
colors = ['red', 'blue', 'green']
labels = ['High', 'Medium', 'Low']
locations = [[45.51, -122.68], [45.52, -122.67], [45.53, -122.66]]
for color, label, location in zip(colors, labels, locations):
folium.Marker(
location,
popup=f'Category: {label}',
icon=folium.Icon(color=color)
).add_to(m)
# Add custom legend
legend_items = [
{'color': 'red', 'label': 'High Priority'},
{'color': 'blue', 'label': 'Medium Priority'},
{'color': 'green', 'label': 'Low Priority'}
]
custom_legend = CustomLegend('Priority Levels', legend_items)
custom_legend.add_to(m)
m.save('custom_legend.html')import folium
from folium import LinearColormap
import pandas as pd
import numpy as np
# Generate sample data
np.random.seed(42)
n_points = 50
data = pd.DataFrame({
'lat': np.random.normal(45.52, 0.02, n_points),
'lon': np.random.normal(-122.67, 0.02, n_points),
'value': np.random.exponential(10, n_points),
'category': np.random.choice(['A', 'B', 'C'], n_points)
})
m = folium.Map(location=[45.52, -122.67], zoom_start=12)
# Create value-based colormap
value_colormap = LinearColormap(
colors=['green', 'yellow', 'orange', 'red'],
vmin=data['value'].min(),
vmax=data['value'].max(),
caption='Data Value'
)
# Category colors
category_colors = {'A': 'circle', 'B': 'square', 'C': 'triangle'}
# Add points with dynamic styling
for idx, row in data.iterrows():
# Color based on value
color = value_colormap(row['value'])
# Size based on value (normalized)
size = 5 + (row['value'] / data['value'].max()) * 15
folium.CircleMarker(
location=[row['lat'], row['lon']],
radius=size,
popup=f"Value: {row['value']:.2f}<br>Category: {row['category']}",
color='black',
weight=1,
fillColor=color,
fillOpacity=0.7,
tooltip=f"Category {row['category']}"
).add_to(m)
# Add colormap to map
value_colormap.add_to(m)
m.save('dynamic_styling.html')import folium
from branca.element import Figure
# Create figure container
fig = Figure(width='100%', height='600px')
# Create two maps
map1 = folium.Map(location=[45.52, -122.67], zoom_start=11)
map2 = folium.Map(location=[40.7128, -74.0060], zoom_start=11)
# Add content to maps
folium.Marker([45.52, -122.67], popup='Portland, OR').add_to(map1)
folium.Marker([40.7128, -74.0060], popup='New York, NY').add_to(map2)
# Add maps to figure with custom positioning
map1_html = map1._repr_html_()
map2_html = map2._repr_html_()
# Create side-by-side layout
combined_html = f"""
<div style="display: flex; width: 100%; height: 100%;">
<div style="width: 50%; height: 100%;">
{map1_html}
</div>
<div style="width: 50%; height: 100%;">
{map2_html}
</div>
</div>
"""
# Add to figure
fig.html.add_child(folium.Html(combined_html))
# Save combined figure
fig.save('dual_maps.html')import folium
from folium import LinearColormap
import pandas as pd
import numpy as np
# Large dataset simulation
n_points = 1000
data = pd.DataFrame({
'lat': np.random.normal(45.52, 0.1, n_points),
'lon': np.random.normal(-122.67, 0.1, n_points),
'value': np.random.exponential(5, n_points)
})
# Preprocess data for optimal performance
# Bin similar values to reduce color calculations
data['value_binned'] = pd.cut(data['value'], bins=10, labels=False)
m = folium.Map(location=[45.52, -122.67], zoom_start=10)
# Create colormap with discrete steps
colors = ['darkgreen', 'green', 'lightgreen', 'yellow', 'orange',
'darkorange', 'red', 'darkred', 'purple', 'darkviolet']
colormap = LinearColormap(colors=colors, vmin=0, vmax=9, caption='Value Bins')
# Add optimized markers
for bin_value in range(10):
bin_data = data[data['value_binned'] == bin_value]
if len(bin_data) == 0:
continue
color = colors[bin_value]
# Create feature group for each bin
group = folium.FeatureGroup(name=f'Bin {bin_value}')
for idx, row in bin_data.iterrows():
folium.CircleMarker(
location=[row['lat'], row['lon']],
radius=5,
color=color,
fillColor=color,
fillOpacity=0.6,
popup=f"Value: {row['value']:.2f}",
weight=1
).add_to(group)
group.add_to(m)
# Add controls
folium.LayerControl(collapsed=False).add_to(m)
colormap.add_to(m)
m.save('optimized_large_dataset.html')Install with Tessl CLI
npx tessl i tessl/pypi-folium