Skip to content

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

@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

Activity

deleted a comment from on Aug 26, 2024
deleted a comment from on Aug 26, 2024
deleted a comment from on Aug 26, 2024
rcomer

rcomer commented on Aug 26, 2024

@rcomer
Member

Hi @glumr it looks like this issue is specifically about basemap, so I’ll transfer it to that repository.

glumr

glumr commented on Aug 26, 2024

@glumr
Author

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

DWesl commented on Aug 30, 2024

@DWesl
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

      [Bug]: Basemap drawgreatcircle generating gaps in Mercator projection · Issue #606 · matplotlib/basemap