Skip to content

Supplying a gradient to plugins.HeatMap with floats for keys leads to an exception at render time #2143

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

Closed
atwilso opened this issue May 10, 2025 · 2 comments

Comments

@atwilso
Copy link

atwilso commented May 10, 2025

Describe the bug

Supplying a dict (float -> str) for the gradient argument of folium.plugins.HeatMap() leads to an error at render time.

To Reproduce

This is the code snippet from the documentation page for HeatMap plus a gradient argument. The gradient is taken from the docstring for HeatMap.

import folium
from folium.plugins import HeatMap
import numpy as np

data = (
    np.random.normal(size=(100, 3)) * np.array([[1, 1, 1]]) + np.array([[48, 5, 1]])
).tolist()

m = folium.Map([48.0, 5.0], zoom_start=6)

gradient = {.4: "blue", .6: "cyan", .7: "lime", .8: "yellow", 1: "red"}

HeatMap(data, gradient=gradient).add_to(m)

m

** Expected behavior **

This code snippet should produce a heatmap similar to the one on the documentation page.

What happens instead is that folium.utilities.camelize() throws an error while trying to process the dict keys. This is being called from folium.template.tojavascript(). camelize() assumes that its keys will be strings; this is not necessarily the case.

** Environment **

  • Firefox 128.10.0esr
  • Jupyter Lab 4.4.1
  • Folium 0.19.5
  • Python 3.12
  • Branca 0.8.1

Possible solutions

There's an easy workaround: have the gradient argument look like this:

gradient = {".4": "blue", ".6": "cyan", ".7": "lime", ".8": "yellow", "1": "red"}

The path of least resistance is just to codify this in the documentation for HeatMap, but that would probably break consistency with HeatMapWithTime -- see below. The path of second-least resistance would be to have HeatMap convert the keys to strings. Another possibility would be to have camelize() check to see what kind of argument it's being passed, then call str() on floats and ints, process strings as it usually does, and complain if it sees anything else.

Note: I haven't tested this with HeatMapWithTime. I suspect that this bug will not show up there because it embeds the gradient in the template as-is with {% if this.gradient %}gradient: {{ this.gradient }}{% endif %}.
By comparison, HeatMap pulls it in as part of the options array, processed with {{ this.options|tojavascript }}.

@hansthen
Copy link
Collaborator

hansthen commented May 11, 2025

@atwilso I cannot reproduce the error using Folium 0.19.5. This looks like a duplicate of #2098, which was resolved a few months ago. Can you verify your version?

@atwilso
Copy link
Author

atwilso commented May 12, 2025

Aha! Yes, this is definitely a duplicate of #2098.

Regarding versions, I checked just to make sure:

import folium
import branca
import sys

print(f"Folium version: {folium.__version__}")
print(f"Branca version: {branca.__version__}")
print(f"Python version: {sys.version_info}")
Folium version: 0.19.5
Branca version: 0.8.1
Python version: sys.version_info(major=3, minor=12, micro=0, releaselevel='final', serial=0)

It looks like this commit didn't make it into 0.19.5. The version of camelize() in utilities.py in the release archive (https://github.com/python-visualization/folium/archive/refs/tags/v0.19.5.tar.gz) doesn't look for types. Also, that release was created on 27 February 2025 and the two commits that resolve the issue (1869ae8 and 6644d59) went in on 1 Mar and 12 Mar, respectively.

It sounds like my path forward is to stringify my keys for now and trust that all shall be well when 0.19.6 comes out. I'll close the issue. Thanks for getting back to me!

@atwilso atwilso closed this as completed May 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants