Repository navigation
[BUG]: fitbounds="locations" thinks the world is flat and goes through longitude zero when dealing with positive and negative longitudes #7844
Description
Activity
- changed the title
[-][BUG]: fitbounds="locations" thinks the world is flat and goes through longitude zero when dealing with positive and negative values[/-][+][BUG]: fitbounds="locations" thinks the world is flat and goes through longitude zero when dealing with positive and negative longitudes[/+]on Mar 16, 2026 Thanks for the report! We're going to look into this a bit and follow up. There's some other work being done in this area.
much appreciated! because the map is effectively cylindrical, the best area to omit is where the greatest gap is between any two longitudes. the pseudocode for the correct bounds is roughly:
largest_gap = sorted_longitudes[0]-sorted_longitudes[-1] largest_left_edge_index = -1 for i in range(len(sorted_longitudes)-1): if sorted_longitudes[i+1]-sorted_longitudes[i] > largest_gap: #capture the index of the left edge of the largest gap; #the right edge of the largest gap is largest_left_edge_index+1 largest_left_edge_index= i largest_gap = sorted_longitudes[i+1]-sorted_longitudes[i] #largest left_edge tells us where the right most coordinate to keep is latitude_range = [sorted_longitudes[largest_left_edge_index+1], sorted_longitudes[largest_left_edge_index]]thanks to Eli Lebow for suggesting this clean solution!
Hi @rl-utility-man , thanks for looking into this. We have some work ongoing for a related issue in the
maptraces, but those are separate from thegeotraces.This does seem like a bug and we would welcome a PR.
hey, mind if i take a shot at this one? had a look and the issue is in geo.js updateProjection , the lon range for fitbounds comes straight from 'getAutoRange', so it's a naive min/max and any pair of points across +/-180 drags the range through lon 0.
@rl-utility-man's largest-gap idea works nicely , sort the lons, find the biggest gap (including the wrap from last back to first), and use the complement as the range. tight antimeridian clusters go from '~358°' down to a few degrees, and normal spread-out data is left alone
one thing i wanted to check before writing it up: do you want this applied whenever it's more compact, or only when points genuinely straddle the antimeridian? the pure largest-gap version will also re-center a few cases that look fine today, so it depends how aggressive you want it. happy to go whichever way.
Feel free to submit a PR. I'm far more experienced in Python than JS.
As for whether to e.g. show London or Tokyo when the map has only points at say 91 degrees east and 91 degrees west, remember that we can document this behavior and ways to override the default -- so I think I lean toward a simple to code, simple to document default that bakes in no preference between the Atlantic and the Pacific. Then we can document the default and how users can customize the behavior. But I defer to Plotly engineers
- added a commit that references this issue
on Jun 16, 2026 Given that this is a bug in plotly.js, I'm going to transfer the issue. See @SharadhNaidu's PR for JS examples of how to reproduce the bug.
Description
The Scatter_geo fitbounds='locations' parameter is supposed to show just the relevant part of the world. When the points are on both sides of longitude +/-180, it includes longitude zero on the map even if a map that shows longitude 180 would be far more compact. The two maps below are trivially different; when the eastern most coordinate is 179, the map is compact and fitbounds works as expected. When the eastern most coordinate is -179, the map includes a large amount of unnecessary, blank geography.
Specifying longitude and latitude ranges manually is a workaround.
Let me know if this would be a good PR for someone new to the codebase
Screenshots/Video
Steps to reproduce
Run this code