plotly/plotly.js · warning
Something went wrong during<this.id>fitbounds computations.
Error message
Something went wrong during<this.id>fitbounds computations.
What it means
When fitting the geo projection to the data bounds (layout.geo.fitbounds or fitbounds: 'geo'), plotly.js computes a scale factor from projection bounds; if that factor is not finite (division by zero from degenerate bounds), it warns 'Something went wrong during<id>fitbounds computations.' and skips the scale adjustment, leaving the projection at its previous state.
Source
Thrown at src/plots/geo/geo.js:328
// scaleExtent uses fitScale so min/maxscale are relative to the
// user-facing projection.scale (where 1 == fits lon/lat ranges).
// https://d3js.org/d3-zoom#zoom_scaleExtent
projection.scaleExtent = () => {
const { minscale } = projLayout;
const maxscale = projLayout.maxscale ?? Infinity;
// swap if user supplied min > max so d3 receives a valid range
return [s * Math.min(minscale, maxscale), s * Math.max(minscale, maxscale)];
};
if (geoLayout.fitbounds) {
var b2 = projection.getBounds(makeRangeBox(axLon.range, axLat.range));
var k2 = Math.min((b[1][0] - b[0][0]) / (b2[1][0] - b2[0][0]), (b[1][1] - b[0][1]) / (b2[1][1] - b2[0][1]));
if (isFinite(k2)) {
projection.scale(k2 * s);
} else {
Lib.warn('Something went wrong during' + this.id + 'fitbounds computations.');
}
} else {
// adjust projection to user setting
projection.scale(projLayout.scale * s);
}
// px coordinates of view mid-point,
// useful to update `geo.center` after interactions
var midPt = (this.midPt = [(b[0][0] + b[1][0]) / 2, (b[0][1] + b[1][1]) / 2]);
projection.translate([t[0] + (midPt[0] - t[0]), t[1] + (midPt[1] - t[1])]).clipExtent(b);
// the 'albers usa' projection does not expose a 'center' method
// so here's this hack to make it respond to 'geoLayout.center'
if (geoLayout._isAlbersUsa) {
var centerPx = projection([center.lon, center.lat]);
// If center isn't within the Albers USA bounds (clipped to the USA),
// `projection(...)` returns null so skip the recenteringView on GitHub (pinned to 1d090e0b5f)
Solutions
- Check that the geo data actually spans a non-degenerate lon/lat extent before enabling fitbounds.
- Remove explicit range settings on axLon/axLat that collapse the bounds, and let fitbounds compute from full data.
- Fall back to manual projection.scale/center configuration instead of fitbounds for degenerate datasets.
- Validate/repair locations and coordinates (drop nulls, fix invalid ISO codes) so ranges are finite.
Example fix
// before
layout = {geo: {fitbounds: 'locations'}, /* data reduced to a single point */}
// after
// ensure >= 2 distinct points, or set manually:
layout = {geo: {projection: {scale: 3}, center: {lon: 10, lat: 50}}}; Defensive patterns
Strategy: fallback
Validate before calling
function hasNonDegenerateBounds(lon, lat) {
const lonSet = new Set(lon.filter(Number.isFinite));
const latSet = new Set(lat.filter(Number.isFinite));
return lonSet.size > 1 && latSet.size > 1;
}
const layout = hasNonDegenerateBounds(lons, lats) ? {geo: {fitbounds: 'locations'}} : {geo: {projection: {scale: 2}}}; Type guard
const fitboundsSafe = (lons, lats) => lons.every(Number.isFinite) && lats.every(Number.isFinite) && new Set(lons).size > 1 && new Set(lats).size > 1;
Try / catch
try {
Plotly.newPlot(gd, data, {geo: {fitbounds: 'locations'}});
} catch (e) {
if (/fitbounds/.test(e.message)) {
Plotly.newPlot(gd, data, {geo: {projection: {scale: 2}, center: {lon: 0, lat: 0}}});
} else { throw e; }
} Prevention
- Verify data spans a real geographic extent before enabling fitbounds.
- Filter out null/invalid coordinates and unmatched locations.
- Avoid combining fitbounds with manually collapsed axis ranges.
- Provide a manual projection.scale/center fallback for degenerate datasets.
When it happens
Trigger: Enabling fitbounds on a geo subplot whose computed lon/lat ranges are degenerate (all points identical, empty data after filtering, or ranges producing zero-width/zero-height projection bounds so the scale ratio divides by zero).
Common situations: Fitting bounds to a single-point dataset; data filtered down to nothing; choropleth/geo traces with all locations invalid; fitbounds combined with manually set range that collapses to one point.
AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02).
Data as JSON: /api/errors/519054ed6dbc115c.
Report an issue: GitHub.