You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG]: fitbounds="locations" thinks the world is flat and goes through longitude zero when dealing with positive and negative longitudes #7844
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
import plotly.graph_objects as go
for lon in [-179, 179]:
# Coordinates for the points
lats = [43.1155, 32.7157]
lons = [131.8855, lon]
fig = go.Figure(go.Scattergeo(
lat=lats,
lon=lons,
mode='markers+text',
textposition='top center',
marker=dict(size=10, color='red')
))
fig.update_layout(
title=f'eastern most longitude is {lon}',
geo=dict(
fitbounds="locations",
visible=True,
projection_type='equirectangular'
)
)
fig.show()
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
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 map traces, but those are separate from the geo traces.
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
Activity
[-][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[/+]camdecoster commentedon Mar 18, 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.
rl-utility-man commentedon Mar 20, 2026
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:
thanks to Eli Lebow for suggesting this clean solution!
emilykl commentedon Mar 25, 2026
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.
SharadhNaidu commentedon Jun 8, 2026
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.
rl-utility-man commentedon Jun 9, 2026
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
Fix geo fitbounds to pick compact range across the antimeridian
camdecoster commentedon 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.