Skip to content

Commit a926577

Browse files
committed
fix create_hexbin_map truncating aggregated values to integers
The aggregated "color" column was cast to Int64, so any non-integer result of agg_func (e.g. the mean of a column with values between 0 and 1) got truncated and np.min/np.mean/np.max all produced the same map. The cast came in with the narwhals port; before that the column went through pd.to_numeric and kept its float values. Drop the cast. Closes #4632
1 parent 05579b0 commit a926577

3 files changed

Lines changed: 27 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## Unreleased
66

7+
### Fixed
8+
- Fix `create_hexbin_map` truncating aggregated values to integers, which made `agg_func` results such as the mean of a float column come out wrong [[#4632](https://github.com/plotly/plotly.py/issues/4632)], with thanks to @Belagum for the contribution!
79

810
## [7.1.0] - 2026-09-15
911

plotly/figure_factory/_hexbin_map.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,7 @@ def create_hexbin_map(
437437
)
438438
)
439439

440-
agg_data_frame = nw.concat(agg_data_frame_list, how="vertical").with_columns(
441-
color=nw.col("color").cast(nw.Int64)
442-
)
440+
agg_data_frame = nw.concat(agg_data_frame_list, how="vertical")
443441

444442
if range_color is None:
445443
range_color = [

tests/test_optional/test_figure_factory/test_figure_factory.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,30 @@ def test_aggregation(self):
12751275

12761276
assert fig3.data[0].z.sum() == 1000
12771277

1278+
def test_aggregation_keeps_float_values(self):
1279+
lat = [0, 1, 1, 2, 4, 5, 1, 2, 4, 5, 2, 3, 2, 1, 5, 3, 5]
1280+
lon = [1, 2, 3, 3, 0, 4, 5, 0, 5, 3, 1, 5, 4, 0, 1, 2, 5]
1281+
1282+
fig = ff.create_hexbin_map(
1283+
lat=lat,
1284+
lon=lon,
1285+
nx_hexagon=1,
1286+
color=0.5 * np.ones(len(lat)),
1287+
agg_func=np.mean,
1288+
)
1289+
assert np.array_equal(fig.data[0].z, 0.5 * np.ones(5))
1290+
1291+
color = np.linspace(0.1, 0.9, len(lat))
1292+
fig_min = ff.create_hexbin_map(
1293+
lat=lat, lon=lon, nx_hexagon=1, color=color, agg_func=np.min
1294+
)
1295+
fig_max = ff.create_hexbin_map(
1296+
lat=lat, lon=lon, nx_hexagon=1, color=color, agg_func=np.max
1297+
)
1298+
z_min, z_max = fig_min.data[0].z, fig_max.data[0].z
1299+
assert np.all(z_min >= 0.1) and np.all(z_max <= 0.9)
1300+
assert np.all(z_min <= z_max) and np.any(z_min < z_max)
1301+
12781302
def test_build_dataframe(self):
12791303
np.random.seed(0)
12801304
N = 10000

0 commit comments

Comments
 (0)