Skip to content

[Bug]: Basemap drawgreatcircle generating gaps in Mercator projection #606

Open
@glumr

Description

@glumr

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

Gaps_times2

Expected outcome

Gaps_times5

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions