-
Notifications
You must be signed in to change notification settings - Fork 398
Open
Description
Bug summary
I see an issue where drawgreatcircle() produces paths with gaps in with the Mercator projection.
I can see from web searches that others have seen the same issue and suggestions point to gathering the path using computations with other projections.
Code for reproduction
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# setup mercator map projection.
m = Basemap(llcrnrlon=-180.,llcrnrlat=-65.,\
urcrnrlon=180.,urcrnrlat=85.,\
projection='merc',\
lat_0=40.,lon_0=-20.,lat_ts=20.)
m.drawcoastlines()
m.fillcontinents()
# AMS
amslat = np.float64(52.309)
amslon = np.float64(4.764)
# Seattle
sealat = np.float64(47.449)
sealon = np.float64(-122.309)
# Helsinki
hellat = np.float64(60.320)
hellon = np.float64(24.956)
m.drawgreatcircle(amslon,amslat,sealon,sealat,linewidth=2,color='b')
m.drawgreatcircle(sealon,sealat,hellon,hellat,linewidth=2,color='b')
# draw parallels
m.drawparallels(np.arange(-60,65,20))
# draw meridians
m.drawmeridians(np.arange(-180,180,30))
plt.show()
Actual outcome
Expected outcome
Additional information
I don't understand the basemap calculations and how projections enter into it but I can recover the correct output if I change the test for cuts in the source code by making max_dist much larger...
diff -c __init*py.orig **init*py
*** __init__.py.orig Mon Aug 26 08:40:10 2024
--- __init__.py Mon Aug 26 09:28:34 2024
***************
*** 2901,2907 ****
p = _p[0].get_path()
# since we know the difference between any two points, we can use this to find wrap arounds on the plot
! max_dist = 1000*del_s*2
# calculate distances and compare with max allowable distance
dists = np.abs(np.diff(p.vertices[:,0]))
--- 2901,2907 ----
p = _p[0].get_path()
# since we know the difference between any two points, we can use this to find wrap arounds on the plot
! max_dist = 1000*del_s*5
# calculate distances and compare with max allowable distance
dists = np.abs(np.diff(p.vertices[:,0]))
This is what I did to generate the output in the expected result box.
It would be helpful if the defaults did allow great circle paths into high lattitudes.
Operating system
Windows 10
Matplotlib Version
3.8.4
Matplotlib Backend
3.8.4
Python version
3.12.2
Jupyter version
No response
Installation
conda
Metadata
Metadata
Assignees
Labels
No labels
Activity
rcomer commentedon Aug 26, 2024
Hi @glumr it looks like this issue is specifically about basemap, so I’ll transfer it to that repository.
glumr commentedon Aug 26, 2024
Ir seems this has been noted a long time ago: #171
I initially searched in matplotlib/matplotlib issues so did not find the above.
DWesl commentedon Aug 30, 2024
You can create arbitrarily-long great-circle paths on the Mercator projection by making the path arbitrarily close to the pole, so any fixed number will break down in some circumstance. Perhaps the logic should change to take the plot limits into account if the projection can be infinite (Mercator and variants, Lambert Conformal, and Stereographic and variants are the ones that come to mind as relevant for this)?
It might also be possible to make that scale factor a keyword-argument of the function, defaulting to two and only getting used when needed.