Skip to content

Fix HeatMap crash on integer numpy weight arrays#2244

Open
gaoflow wants to merge 1 commit into
python-visualization:mainfrom
gaoflow:fix-heatmap-integer-numpy-weights
Open

Fix HeatMap crash on integer numpy weight arrays#2244
gaoflow wants to merge 1 commit into
python-visualization:mainfrom
gaoflow:fix-heatmap-integer-numpy-weights

Conversation

@gaoflow

@gaoflow gaoflow commented Jul 6, 2026

Copy link
Copy Markdown

Problem

HeatMap's docstring documents "a numpy.array of shape (n,2) or (n,3)" as
valid input, but an all-integer array crashes at render time:

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

m = folium.Map()
HeatMap(np.array([[3, 4, 1], [5, 6, 2]])).add_to(m)   # int64 dtype
m.get_root().render()
# TypeError: Object of type int64 is not JSON serializable

The float-weight version renders fine. This is common in real usage, e.g.
HeatMap(df[["lat", "lon", "count"]].values) where the weight column has an
integer dtype (pandas .values yields an int64 array).

Cause

In HeatMap.__init__, validate_location coerces the lat/lon columns to Python
float, but the weight column (line[2:]) is passed through unchanged:

self.data = [
    [*validate_location(line[:2]), *line[2:]] for line in data
]

np.float64 is a subclass of float, so json.dumps (via the template's
|tojson) tolerates float weights; np.int64 is not a subclass of int,
so integer weights raise. The existing test_heatmap_data masks this because
its array contains a 0.5, forcing the whole array to float64.

Fix

Coerce the weight column to float, mirroring the lat/lon normalization. The
NaN guard immediately below still works (float(np.nan) is caught by
np.isnan).

Tests

  • test_heatmap_integer_numpy_weights: an int64 (n,3) array — weights
    normalized to Python float, render contains L.heatLayer, and integer vs
    float arrays produce identical .data.
  • test_heatmap_integer_numpy_no_weight: an int64 (n,2) array renders.

pytest tests/plugins/ passes (the one unrelated test_time_slider_choropleth
failure is a pre-existing missing optional dependency, identical on a clean
checkout). ruff check clean.

HeatMap's docstring documents numpy arrays of shape (n, 2) or (n, 3) as valid
input, but an all-integer array (dtype int64) crashes at render time with
"Object of type int64 is not JSON serializable". validate_location coerces the
lat/lon columns to Python float, while the weight column (line[2:]) was passed
through unchanged. np.float64 is a subclass of float so json.dumps tolerates
float weights, but np.int64 is not a subclass of int, so integer weights fail.
This is common in practice, e.g. HeatMap(df[["lat", "lon", "count"]].values)
where the count column has an integer dtype.

Coerce the weight column to float, mirroring the lat/lon normalization.
@hansthen

hansthen commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Very well documented change. Looks good, I will run the automated tests.

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

Successfully merging this pull request may close these issues.

2 participants