In this Folium tutorial, we build a complete set of interactive maps that run in Colab or any local Python setup. We explore multiple basemap styles, design rich markers with HTML popups, and visualize spatial density using heatmaps. We also create region-level choropleth maps from GeoJSON, scale to thousands of points using marker clustering, and animate time-based movement with a timestamped layer. Finally, we combine real-world USGS earthquake data with layered magnitude buckets, density heatmaps, legends, and fullscreen controls to produce a practical, dashboard-like global monitor. Copy CodeCopiedUse a different Browser import folium from folium import plugins from folium.plugins import HeatMap, MarkerCluster, TimestampedGeoJson, MiniMap, Draw, Fullscreen import pandas as pd import numpy as np import json import requests from datetime import datetime, timedelta import branca.colormap as cm print(f”Folium version: {folium.__version__}”) print(“All imports successful!n”) We import all required libraries, such as Folium, Pandas, NumPy, Requests, and Folium plugins to prepare our geospatial environment. We initialize the mapping workflow by confirming the Folium version and ensuring that all dependencies load successfully. This setup establishes the technical foundation for building interactive maps, processing data, and integrating external geospatial sources. Copy CodeCopiedUse a different Browser def create_multi_tile_map(): “””Create a map with multiple tile layers””” m = folium.Map( location=[40.7128, -74.0060], zoom_start=12, tiles=’OpenStreetMap’ ) folium.TileLayer(‘cartodbpositron’, name=’CartoDB Positron’).add_to(m) folium.TileLayer(‘cartodbdark_matter’, name=’CartoDB Dark Matter’).add_to(m) folium.TileLayer( tiles=’https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}.png’, attr=’Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL’, name=’Terrain’ ).add_to(m) folium.TileLayer( tiles=’https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}.png’, attr=’Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL’, name=’Toner’ ).add_to(m) folium.TileLayer( tiles=’https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg’, attr=’Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL’, name=’Watercolor’ ).add_to(m) folium.LayerControl().add_to(m) return m We create a multi-layer base map and configure multiple tile providers to enable different visual styles. We add terrain, dark mode, toner, and watercolor layers so we can switch perspectives based on the analytical requirements. By including a layer control panel, we can dynamically toggle map styles and explore spatial data more effectively. Copy CodeCopiedUse a different Browser def create_advanced_markers_map(): “””Create map with custom markers and HTML popups””” landmarks = [ {‘name’: ‘Statue of Liberty’, ‘lat’: 40.6892, ‘lon’: -74.0445, ‘type’: ‘monument’, ‘visitors’: 4500000}, {‘name’: ‘Empire State Building’, ‘lat’: 40.7484, ‘lon’: -73.9857, ‘type’: ‘building’, ‘visitors’: 4000000}, {‘name’: ‘Central Park’, ‘lat’: 40.7829, ‘lon’: -73.9654, ‘type’: ‘park’, ‘visitors’: 42000000}, {‘name’: ‘Brooklyn Bridge’, ‘lat’: 40.7061, ‘lon’: -73.9969, ‘type’: ‘bridge’, ‘visitors’: 4000000}, {‘name’: ‘Times Square’, ‘lat’: 40.7580, ‘lon’: -73.9855, ‘type’: ‘plaza’, ‘visitors’: 50000000} ] m = folium.Map(location=[40.7128, -74.0060], zoom_start=12) icon_colors = { ‘monument’: ‘red’, ‘building’: ‘blue’, ‘park’: ‘green’, ‘bridge’: ‘orange’, ‘plaza’: ‘purple’ } icon_symbols = { ‘monument’: ‘star’, ‘building’: ‘home’, ‘park’: ‘tree’, ‘bridge’: ‘road’, ‘plaza’: ‘shopping-cart’ } for landmark in landmarks: html = f””” <div style="”font-family:" arial; width: 200px;”> <h4 style="”color:" {icon_colors[landmark[‘type’]]};”>{landmark[‘name’]}</h4> <hr style="”margin:" 5px 0;”> <p><b>Type:</b> {landmark[‘type’].title()}</p> <p><b>Annual Visitors:</b> {landmark[‘visitors’]:,}</p> <img src="”https://via.placeholder.com/180×100?text={landmark[‘name’].replace(‘" ‘, ‘+’)}” style="”width:" 100%; border-radius: 5px;”> </div> “”” iframe = folium.IFrame(html, width=220, height=250) popup = folium.Popup(iframe, max_width=220) folium.Marker( location=[landmark[‘lat’], landmark[‘lon’]], popup=popup, tooltip=landmark[‘name’], icon=folium.Icon( color=icon_colors[landmark[‘type’]], icon=icon_symbols[landmark[‘type’]], prefix=’fa’ ) ).add_to(m) folium.CircleMarker( location=[40.7128, -74.0060], radius=20, popup=’NYC Center’, color=’#3186cc’, fill=True, fillColor=’#3186cc’, fillOpacity=0.2 ).add_to(m) return m We build a map with advanced markers and rich HTML popups to represent real-world landmarks. We customize marker icons, colors, and symbols by location type to enhance visual clarity and semantic meaning. By embedding structured HTML content inside popups, we present detailed contextual information directly within the interactive map. Copy CodeCopiedUse a different Browser def create_heatmap(): “””Create a heatmap showing data density””” np.random.seed(42) n_incidents = 1000 crime_data = [] hotspots = [ [40.7580, -73.9855], [40.7484, -73.9857], [40.7128, -74.0060], ] for _ in range(n_incidents): hotspot = hotspots[np.random.choice(len(hotspots))] lat = hotspot[0] + np.random.normal(0, 0.02) lon = hotspot[1] + np.random.normal(0, 0.02) intensity = np.random.uniform(0.3, 1.0) crime_data.append([lat, lon, intensity]) m = folium.Map(location=[40.7128, -74.0060], zoom_start=12) HeatMap( crime_data, min_opacity=0.2, max_zoom=18, max_val=1.0, radius=15, blur=25, gradient={ 0.0: ‘blue’, 0.3: ‘lime’, 0.5: ‘yellow’, 0.7: ‘orange’, 1.0: ‘red’ } ).add_to(m) title_html = ”’ <div style="”position:" fixed; top: 10px; left: 50px; width: 300px; height: 60px; background-color: white; border:2px solid grey; z-index:9999; font-size:16px; padding: 10px”> <h4 style="”margin:" 0;”>NYC Crime Density Heatmap</h4> <p style="”margin:" 5px 0 0; font-size: 12px;”>Simulated incident data</p> </div> ”’ m.get_root().html.add_child(folium.Element(title_html)) return m We generate synthetic spatial data and use a heatmap to visualize density patterns across geographic locations. We simulate clustered coordinates and apply gradient-based intensity visualization to reveal spatial concentration trends. By overlaying this density layer on the map, we gain insight into how events distribute across regions. Copy CodeCopiedUse a different Browser def create_choropleth_map(): “””Create a choropleth map showing data across regions””” us_states_url = ‘https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/us-states.json’ try: us_states = requests.get(us_states_url).json() except: print(“Warning: Could not fetch GeoJSON data. Using offline sample.”) return None state_data = { ‘Alabama’: 5.1, ‘Alaska’: 6.3, ‘Arizona’: 4.7, ‘Arkansas’: 3.8, ‘California’: 5.3, ‘Colorado’: 3.9, ‘Connecticut’: 4.3, ‘Delaware’: 4.1, ‘Florida’: 3.6, ‘Georgia’: 4.0, ‘Hawaii’: 2.8, ‘Idaho’: 2.9, ‘Illinois’: 5.0, ‘Indiana’: 3.5, ‘Iowa’: 3.1, ‘Kansas’: 3.3, ‘Kentucky’: 4.3, ‘Louisiana’: 4.6, ‘Maine’: 3.2, ‘Maryland’: 4.0, ‘Massachusetts’: 3.6, ‘Michigan’: 4.3, ‘Minnesota’: 3.2, ‘Mississippi’: 5.2, ‘Missouri’: 3.7, ‘Montana’: 3.5, ‘Nebraska’: 2.9, ‘Nevada’: 4.8, ‘New Hampshire’: 2.7, ‘New Jersey’: 4.2, ‘New Mexico’: 5.0, ‘New York’: 4.5, ‘North Carolina’: 4.0, ‘North Dakota’: 2.6, ‘Ohio’: 4.2, ‘Oklahoma’: 3.4, ‘Oregon’: 4.2, ‘Pennsylvania’: 4.4, ‘Rhode Island’: 4.0, ‘South Carolina’: 3.5, ‘South Dakota’: 2.9, ‘Tennessee’: 3.6, ‘Texas’: 4.0, ‘Utah’: 2.8, ‘Vermont’: 2.8, ‘Virginia’: 3.3, ‘Washington’: 4.6, ‘West Virginia’: 5.1, ‘Wisconsin’: 3.4, ‘Wyoming’: 3.6 } df = pd.DataFrame(list(state_data.items()), columns=[‘State’, ‘Unemployment’]) m = folium.Map(location=[37.8, -96], zoom_start=4) folium.Choropleth( geo_data=us_states, name=’choropleth’, data=df, columns=[‘State’, ‘Unemployment’], key_on=’feature.properties.name’, fill_color=’YlOrRd’, fill_opacity=0.7, line_opacity=0.5, legend_name=’Unemployment Rate (%)’ ).add_to(m) style_function = lambda x: {‘fillColor’: ‘#ffffff’, ‘color’:’#000000′, ‘fillOpacity’: 0.1, ‘weight’: 0.1} highlight_function = lambda x: {‘fillColor’: ‘#000000’, ‘color’:’#000000′, ‘fillOpacity’: 0.50, ‘weight’: 0.1} NIL = folium.features.GeoJson( us_states, style_function=style_function, control=False, highlight_function=highlight_function, tooltip=folium.features.GeoJsonTooltip( fields=[‘name’], aliases=[‘State:’], style=(“background-color: white; color: #333333; font-family: arial; font-size: 12px; padding: 10px;”) ) ) m.add_child(NIL) m.keep_in_front(NIL) folium.LayerControl().add_to(m) return m We create a choropleth map by combining GeoJSON boundary data with structured numerical attributes. We map unemployment rates to geographic regions and use color gradients to visually represent statistical differences. By enabling hover interactions and tooltips, we can explore region-specific data directly within the map interface. Copy CodeCopiedUse a different Browser def create_marker_cluster_map(): “””Create a map