Back to catalog
Season 41 8 Episodes 28 min 2026

Folium

v0.20 — 2026 Edition. Master Folium v0.20 in this 2026 edition audio course. Learn how to bridge Python's data ecosystem with Leaflet.js to create interactive, powerful web maps.

Geospatial Analysis Interactive Mapping Data Visualization
Folium
Now Playing
Click play to start
0:00
0:00
1
The Folium Bridge
Discover the core abstraction of Folium: bridging Python's data ecosystem with Leaflet.js. Learn how to initialize a Map, set the starting location, and render your first interactive HTML map.
3m 41s
2
Customizing the Canvas
Learn how to transform your map's visual style using tilesets and bounds. We cover xyzservices, custom map tiles, and how to restrict user scrolling.
3m 32s
3
Pinpointing Data
Master the art of dropping pins on your Folium map. We explore Markers, custom Icons, and the crucial difference between Tooltips and Popups.
3m 45s
4
Rich Interactivity in Popups
Take your popups to the next level by embedding rich content. Learn to parse HTML, embed Pandas DataFrames, inject Vega charts, and optimize with lazy loading.
3m 44s
5
Organizing Vectors and Layers
Draw paths and group your data to keep maps clean. We explore PolyLines, FeatureGroups, and how to give users control with LayerControls.
3m 28s
6
Spatial Overlays with GeoJSON
Unlock advanced spatial features by importing GeoJSON into Folium. Learn how to map boundaries and integrate seamlessly with GeoPandas DataFrames.
3m 41s
7
Distributions with Choropleths
Combine geography with statistics using Choropleth maps. Learn how to bind Pandas DataFrames to GeoJSON regions to visualize data distributions.
3m 37s
8
Performance and Plugins
Supercharge your maps with Folium plugins. Discover MarkerClusters for massive point datasets, HeatMaps for density, and Draw tools for map interactions.
3m 23s

Episodes

1

The Folium Bridge

3m 41s

Discover the core abstraction of Folium: bridging Python's data ecosystem with Leaflet.js. Learn how to initialize a Map, set the starting location, and render your first interactive HTML map.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 1 of 8. You have a massive dataset of geographical coordinates, and you need an interactive map to make sense of them. The problem is, building interactive maps usually means stepping out of Python and wrestling with JavaScript libraries. The Folium bridge is the solution to that exact headache. Folium is a Python library that acts as a translator between your data workflows and Leaflet dot js. Leaflet is a highly popular open-source JavaScript library used for building mobile-friendly interactive maps. As a data scientist, you prefer to do the heavy lifting—data manipulation, filtering, and analysis—in Python. Folium allows you to stay in that environment. It takes your Python objects and generates the HTML and JavaScript required to render a Leaflet map. You get the interactivity of a web map without writing a single line of frontend code. Getting started is straightforward. You install the library using standard package managers like pip by running pip install folium. Once installed, the core workflow revolves around creating a base map object. Say you are evaluating potential coordinates for a new retail store location. You have the exact latitude and longitude, and you need to see the surrounding neighborhood. In your script, you import the folium library. You then call the Map function attached to that library. This function requires one critical piece of information to be useful right away: the starting center point. You pass this center point using the location parameter. The location parameter expects a simple list or tuple containing two numbers. The latitude goes first, followed by the longitude. For example, you pass 45.52 for latitude and negative 122.68 for longitude. When you execute this, Folium constructs a map object centered precisely on those coordinates. Now you have a map object existing in memory. How do you actually see it? Folium provides two main paths, depending on your workspace. If you are working inside a Jupyter Notebook, the process is seamless. You simply type the name of your map object on the last line of the cell and run it. The notebook environment recognizes the object's rich HTML representation and automatically renders the interactive Leaflet map directly beneath your code cell. You can immediately pan and zoom to inspect that potential store location. However, you often need to share this map with stakeholders who do not use Jupyter. This is where the second method comes in. You take your map object and call the save method on it. You pass a filename as a string to this method, such as index dot html. Folium takes all the underlying Leaflet logic, the coordinates, and the rendering instructions, and writes them into a standalone HTML file on your hard drive. Anyone can double-click that file and open a fully functional, interactive map in their standard web browser. No Python environment is required to view the final result. Here is the key insight. Folium does not render maps natively in Python; it is simply an engine that generates the web code necessary for a browser to render them. It acts strictly as a bridge to Leaflet, making your Python data instantly web-ready. If you are finding these episodes helpful and want to support the show, you can search for DevStoriesEU on Patreon—every bit helps us keep the lights on. That is all for this one. Thanks for listening, and keep building!
2

Customizing the Canvas

3m 32s

Learn how to transform your map's visual style using tilesets and bounds. We cover xyzservices, custom map tiles, and how to restrict user scrolling.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 2 of 8. You build a beautiful interactive map of a national park, but the moment the user clicks and drags, they slide off the coast and get lost in an endless gray ocean. You need the right background imagery, and you need to lock the camera exactly where your data is. This is all about Customizing the Canvas. When you initialize a Folium map, it defaults to standard OpenStreetMap tiles. Those are the square image tiles stitched together by the browser to form the map background. Standard street maps are not always the right choice. You change this using the tiles parameter when creating your map. If you want a faded, minimalist background so your data stands out, you can pass a simple string name like cartodb positron. But for a national park, you likely want terrain or satellite imagery. This is where Folium integrates with a package called xyzservices. You do not have to hunt down third-party map server links. Folium bundles hundreds of pre-configured providers. You simply access the providers dictionary from the folium map module and pick the one you need. You might choose an Esri topographical map or a specific satellite feed. You pass that provider object directly to the tiles parameter, and Folium handles the server requests behind the scenes. Sometimes, your organization has a private map server, or you need a highly specialized overlay that is not in the built-in list. In that case, you can pass a custom URL string to the tiles parameter. Map servers use a standardized URL structure containing placeholders for the zoom level, usually represented by Z, along with the X and Y coordinates of the map tile. You provide that URL template directly. There is one strict requirement here. When using a custom URL, Folium forces you to include a second parameter called attr, which stands for attribution. You must provide a string crediting the data source. Without the attribution parameter, Folium will refuse to render the custom tiles. Now, your map has the perfect topographical background. But you still have the panning problem. Users can scroll far away from the national park. You prevent this by setting viewport limits. When you create the map object, you define a bounding box using four specific parameters: minimum latitude, maximum latitude, minimum longitude, and maximum longitude. You pass the coordinate boundaries of your park to these parameters. Here is the key insight. Just defining those four coordinates does not stop the user from panning. To actively lock the viewport, you must also set the max bounds parameter to true. When you enable this, Folium instructs the underlying mapping engine to snap the camera back into place if the user tries to drag the view outside your specified rectangle. They are free to zoom in and out to explore the trails, but the map physically blocks them from wandering off into the ocean. Setting hard boundaries keeps your audience focused on the relevant geography, and matching those boundaries with the correct terrain tiles gives your data the exact context it deserves. That is all for this one. Thanks for listening, and keep building!
3

Pinpointing Data

3m 45s

Master the art of dropping pins on your Folium map. We explore Markers, custom Icons, and the crucial difference between Tooltips and Popups.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 3 of 8. A map is really just a static picture until you start dropping pins on it to highlight specific locations. But those pins do not all have to look like the exact same default blue teardrop. Pinpointing data effectively means giving your users visual cues and interactive context right at the coordinate level. To place a point of interest on your map, you use the folium dot Marker class. The only absolute requirement for creating a marker is the location parameter. You pass it a sequence of two numbers, with the latitude first, followed by the longitude. Once you create this marker object in your code, you attach it to your base map using the add to method. That gives you a standard pin sitting exactly at those coordinates. But a bare pin only tells the user that something exists there. It needs to communicate what that something is. Folium gives you two primary ways to attach text to a marker, and developers constantly mix them up. The distinction is simple. A tooltip is text on hover. A popup is a label on click. Think of a map showing different ski resorts across a mountain range. You want the tooltip to hold the name of the resort, like Aspen or Snowbird. This allows the user to quickly scan the map by moving their cursor from pin to pin, instantly seeing names appear and disappear. The popup is reserved for secondary information that requires intent to read. When the user actively clicks the Aspen pin, the popup reveals details like a vertical drop of three thousand feet or the current weather conditions. You use the tooltip for rapid identification, and the popup for deeper context. You configure both by passing text to the tooltip and popup parameters when creating your marker. Now, looking at fifty identical blue pins is a bad user experience. You can visually differentiate them using the folium dot Icon class. When you create your marker, you can pass a custom Icon object to its icon parameter. This lets you alter the color of the pin itself and the graphic displayed inside it. For the color parameter, Folium accepts several standard string names like red, green, purple, or orange. Going back to our ski resorts, you could visually categorize them by marking beginner-friendly resorts in green, and expert-only resorts in red. To change the symbol inside the pin, you use the icon parameter within the Icon class. By default, Folium uses Bootstrap glyphicons. You can pass names like cloud or info dash sign to get those specific graphics inside your marker. If the default library does not have the exact symbol you need, you can switch to Font-Awesome icons. You do this by setting the prefix parameter in your Icon object to the string f a. Once you change the prefix, you can pass any standard Font-Awesome name to the icon parameter. This opens up a massive library of symbols, allowing you to place a snowflake graphic on your winter resorts instead of a generic shape. Here is the key insight. The markers on your map carry the actual narrative of your spatial data. Combining distinct colors, recognizable symbols, and the right split between hover text and click actions turns a simple grid of coordinates into a highly readable interface. Thanks for listening. Take care, everyone.
4

Rich Interactivity in Popups

3m 44s

Take your popups to the next level by embedding rich content. Learn to parse HTML, embed Pandas DataFrames, inject Vega charts, and optimize with lazy loading.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 4 of 8. You click a marker on a map expecting a detailed breakdown, but instead, you get a cramped, unreadable block of plain text. You might think map pins are only built for short labels. But you can actually embed an entire interactive data table or a mini-chart right inside that pin. This is what we cover today: Rich Interactivity in Popups. By default, Folium popups take a simple string of text. But they are built to handle much more. Consider a real estate map. When a user clicks a house pin, an address is not enough. You want to display a photo of the property and a clean, formatted table of housing stats. You achieve this by treating the popup as an isolated web page. First, you can pass raw HTML strings directly to the popup. By setting the parse html argument to true, you instruct Folium to render the string as structural web elements rather than displaying the literal angle brackets on the screen. This allows you to include image tags, headers, and standard web formatting directly inside the marker. For more advanced layouts, you use a specific component from Folium's underlying framework called the Branca IFrame. An IFrame creates an isolated, scrollable window within the popup. This is crucial when embedding complex structures because it prevents the popup's internal styling or large images from leaking out and breaking your main map layout. You create your HTML string, pass it to the IFrame object, set a fixed width and height, and then pass that IFrame directly into your Popup. This workflow pairs perfectly with data analysis libraries. You do not need to manually construct HTML tables to display metrics. If you have a Pandas DataFrame containing the property statistics, you just call the standard Pandas to html method. You take that generated HTML string, feed it into your IFrame, and your map pin now contains a fully formatted, accurate data table. You can push this further using the Folium Vega and VegaLite classes. These classes allow you to embed interactive visualizations. Instead of passing HTML, you pass a JSON specification of a chart to the Vega class, and assign that directly to the popup. Now, clicking the house pin displays a dynamic line chart of historical property values alongside the data table. Here is the key insight. Loading all this rich content creates a massive performance bottleneck. If your real estate map has five thousand house pins, and every popup contains a data table, an image link, and a Vega chart, the browser will try to render all five thousand hidden structures the moment the map loads. The page will instantly freeze. To solve this, the Popup object accepts a parameter called lazy. By setting lazy to true, Folium does not inject the popup content into the webpage initially. The map renders the markers, but the heavy HTML, IFrames, and charts are entirely ignored. The browser only fetches and renders the content at the exact moment the user clicks a specific pin. This defers the computational cost, meaning a map with thousands of heavy, interactive popups will load just as fast as a map with standard text labels. The true power of a web map is not where you place the pins, but how much context you can pack inside them without degrading the user experience. Thanks for listening. Take care, everyone.
5

Organizing Vectors and Layers

3m 28s

Draw paths and group your data to keep maps clean. We explore PolyLines, FeatureGroups, and how to give users control with LayerControls.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 5 of 8. You plot fifty delivery routes and a dozen warehouses on a single map. The result is a chaotic web of intersecting lines that no one can read. You need a way to let users filter the noise. That is where organizing vectors and layers comes in. First, you need to draw the paths. To represent connected coordinates on a map, you use the Folium PolyLine class. A PolyLine takes a sequence of latitude and longitude pairs and draws straight segments between them. If you have the GPS traces from a delivery truck, you simply pass that list of coordinates to the PolyLine object. You can configure visual properties like color, weight, and opacity. This allows you to draw a thick blue line for a primary shipping lane and a thin gray line for a local delivery route. If you attach a PolyLine directly to your base map, it is permanently visible. For a complex logistics map, this is a mistake. Here is the key insight. Instead of attaching shapes directly to the map object, you should put them inside a FeatureGroup. A FeatureGroup is a logical container. It groups related elements together so they can be managed as a single unit. In our logistics scenario, you start by creating two separate FeatureGroups. You name the first one Delivery Routes and the second one Warehouse Locations. Then, as you generate your map elements, you change their destination. When you create a PolyLine for a truck path, you add it to the Delivery Routes group. When you create a standard marker for a building, you add it to the Warehouse Locations group. Once all your individual elements are sorted into their respective containers, you add both FeatureGroups to the main map object. At this stage, the generated map looks identical to one where everything was dumped directly onto the base layer. The visual output has not changed, but the underlying data structure has. This structure is what enables user interaction. To expose this structure to the user, you instantiate a Folium LayerControl and add it to the map. The LayerControl scans the map object, finds all the FeatureGroups you attached, and automatically builds an interactive menu in the top corner of the screen. Your FeatureGroups become toggleable overlays. The user will see a checkbox for Delivery Routes and another checkbox for Warehouse Locations. If the screen is too cluttered, they can uncheck the routes to inspect just the facilities. The LayerControl separates your map data into two categories: base layers and overlays. Base layers are the underlying map tiles, like a street view or a satellite view. These are presented with radio buttons, because only one base map can be active at a time. Overlays are the vectors and markers you added via FeatureGroups. These use checkboxes, allowing multiple sets of data to stack on top of each other. The single most important rule of map interactivity is that the user interface can only manipulate what your data structure defines. If you attach every line and marker to the root map, your layer control menu will be empty and the user controls nothing. That is your lot for this one. Catch you next time!
6

Spatial Overlays with GeoJSON

3m 41s

Unlock advanced spatial features by importing GeoJSON into Folium. Learn how to map boundaries and integrate seamlessly with GeoPandas DataFrames.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 6 of 8. Plotting a thousand individual markers on a map is straightforward. But what happens when you need to draw the exact, jagged borders of all fifty United States, or the winding administrative boundaries of an entire city? Plotting every single vertex manually is not an option. Spatial Overlays with GeoJSON are how you solve this. GeoJSON is the industry standard format for representing complex geographical features. While a standard marker represents a single coordinate, GeoJSON handles lines, polygons, and multi-polygons. When you are dealing with real-world borders, you are dealing with arrays containing thousands of latitude and longitude pairs defining a single shape. Folium uses the GeoJson class to take this dense boundary data and render it as a visual overlay on your base map. Let us use the scenario of mapping the borders of city districts. You have the spatial data for twenty districts, and you need to see their outlines on a street map. Some districts are simple polygons, while others might include islands or disconnected zones, requiring multi-polygons. Folium gives you several ways to ingest this complex data. You can pass a string containing a URL that points directly to a GeoJSON file hosted online. You can pass a local file path. You can even pass a parsed Python dictionary if you have already loaded the data into memory. Here is the key insight. Folium does not just read static text files. It natively integrates with the broader Python data science ecosystem. The GeoJson class will accept any Python object that implements the standard geo-interface property. This is a common protocol in Python spatial libraries that allows different tools to share geographic data structures seamlessly. Because of this standard, you do not need to manually extract JSON strings if you are already using modern analytical tools. You can pass a GeoPandas GeoDataFrame directly into Folium. To do this, you first load your district boundaries into a GeoDataFrame using GeoPandas. Next, you generate your standard base map centered on the city. Then, you call the GeoJson class and simply hand it your GeoDataFrame as the primary argument. Finally, you add that newly created GeoJson object to your base map. Folium reads the geo-interface of the dataframe, extracts the geometric shapes for all twenty city districts, and draws the exact borders over the map tiles. You completely bypass raw file manipulation and go straight from a data structure to a visualization. Keep in mind, this specific overlay process is strictly about displaying spatial boundaries. It is not about joining statistical data to those boundaries to color them based on population or income. That is a different concept altogether. The GeoJson class is purely about defining the physical shapes and getting them onto the map. The power of the Folium GeoJSON layer is not just that it can draw complex, multi-part geographic borders, but that it serves as a direct bridge between analytical objects like a GeoDataFrame and your final interactive map, requiring absolutely zero manual coordinate wrangling. That is all for this one. Thanks for listening, and keep building!
7

Distributions with Choropleths

3m 37s

Combine geography with statistics using Choropleth maps. Learn how to bind Pandas DataFrames to GeoJSON regions to visualize data distributions.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 7 of 8. The most recognizable map in data science colors geographic regions based on a statistical value. Getting the geographic borders to match your spreadsheet data usually requires a messy merge operation in a separate spatial library. In Folium, the Choropleth class handles the geometry, the data binding, and the color scaling in a single step. A choropleth binds numerical data to geographical boundaries. You provide the shapes, you provide the numbers, and the map colors the shapes based on those numbers. Consider the classic example of mapping the unemployment rate across US states. To build this, you instantiate the Choropleth class and pass it four critical pieces of information. First is the geographic data. You pass a GeoJSON file containing the polygon boundaries for the US states to the geo data parameter. Second is the statistical data. You pass your Pandas DataFrame containing the unemployment statistics to the data parameter. Third, you tell Folium which parts of your DataFrame matter. You provide a list of exactly two column names to the columns parameter. The first column holds the region identifier, like the state abbreviation. The second column holds the numerical value you want to visualize, which is the unemployment rate. Here is the key insight. The DataFrame and the geographic shapes are completely separate objects. You must explicitly tell Folium how to link them together using the key on parameter. This parameter takes a string representing the precise path within the GeoJSON file where the matching identifier lives. If your GeoJSON defines a state using a feature property called id, your key on parameter will be the string feature dot id. This path must perfectly match the identifier in the first column of your DataFrame. When they match, the statistical data binds to the geometry. Once the data binds, the map applies colors. The fill color parameter accepts standard palettes like YlGn for a yellow-to-green gradient. By default, Folium takes the minimum and maximum values in your dataset and cuts the color scale into equal mathematical slices. If your unemployment data is heavily skewed, this linear slicing might lump most states into a single color band, rendering the map useless. To control this, pass a list of specific numerical thresholds to the bins parameter. This forces the color scale to shift exactly where your data naturally breaks, giving you full control over the visual distribution. Real-world datasets often have gaps. If a state in your GeoJSON boundary file lacks a matching row in your DataFrame, Folium will still draw the border but leave the inside uncolored. You manage these empty regions with the nan fill color parameter. Setting this to a neutral shade like gray ensures missing data is explicitly marked without distracting from the rest of the map. The alignment between the DataFrame key and the GeoJSON property path is the single point of failure for most choropleths. Get the key on parameter right, and the map builds itself. If you find these technical deep dives helpful, you can support the show by searching for DevStoriesEU on Patreon. That is all for this one. Thanks for listening, and keep building!
8

Performance and Plugins

3m 23s

Supercharge your maps with Folium plugins. Discover MarkerClusters for massive point datasets, HeatMaps for density, and Draw tools for map interactions.

Download
Hi, this is Alex from DEV STORIES DOT EU. Folium, episode 8 of 8. Plotting one hundred points on a web map is easy. Plot ten thousand points, and your browser will completely freeze. The document object model simply cannot handle that many individual graphical elements at once. The solution to this bottleneck is Performance and Plugins. You have a dataset of one hundred thousand taxi pickup locations across a city. If you loop through that list and add standard markers directly to your base map, the page will crash before it even finishes loading. This is where the MarkerCluster plugin comes in. Instead of attaching points straight to the map, you create a dedicated cluster object. You loop through your dataset, add every single pickup location to this cluster object, and then attach the entire cluster to the map at the very end. When the map loads fully zoomed out, the browser does not attempt to draw one hundred thousand pins. It draws a few large circles with numbers inside them, representing the total count of locations in that broad area. As you zoom in, those massive clusters dynamically break apart into smaller, localized clusters. If you click on a numbered circle, the map automatically computes the boundaries and zooms into that specific region. It handles the spatial math in the background, ensuring the browser only renders individual markers when you are close enough to actually see them. Sometimes, exact point locations are not what you actually need to communicate. You want to see density. The HeatMap plugin takes that same massive list of taxi coordinates and renders a smooth color gradient instead of thousands of overlapping pins. You pass your raw list of latitude and longitude pairs directly into the heatmap function, and attach it to the map. The plugin calculates the spatial concentration of your data. High density pickup zones glow intensely, while sparse areas fade out. It is computationally much cheaper for the browser to render this single overlay than discrete vector shapes, and it instantly reveals hotspots without turning the screen into a chaotic mess of icons. Up to this point, the maps have been strictly read-only. The Draw plugin changes that behavior entirely. It adds an interactive toolbar directly to the user interface. You enable the plugin in your Python script, and when the user opens the resulting file, they can click tools to sketch custom polygons, draw lines, or drop their own markers over your taxi data. Here is the key insight. These drawn shapes are not just dead pixels on a screen. They generate valid spatial data. A user can draw a boundary fence around a specific neighborhood with high taxi demand and export that exact shape as a GeoJSON file directly from the toolbar. This transforms your visualization from a static report into an active selection and annotation tool. Folium plugins bridge the gap between straightforward Python scripts and heavy-duty front-end web mapping, giving you advanced browser performance without forcing you to write JavaScript. I encourage you to explore the official documentation, try these tools hands-on, or visit devstories dot eu to suggest topics you want to hear about in a future series. That is all for this one. Thanks for listening, and keep building!