matplotlib / matplotlib/basemap

[Bug]: Basemap drawgreatcircle generating gaps in Mercator projection

Open
#606 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
817
Forks
395
PR merge metrics
No merged PRs in 30d

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

```Python
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](https://github.com/user-attachments/assets/cb6a236e-f4d2-4626-972e-9bfe9a3ab4ab)

### Expected outcome

![Gaps_times5](https://github.com/user-attachments/assets/97d25ddf-6005-4fe1-afa9-ff01db118f9c)

### 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

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in __init__.py around the drawgreatcircle path-cut logic near the max_dist calculation, then run the Python reproduction with the Mercator projection. Investigate why the current distance threshold creates gaps at high latitudes; done means the two great-circle paths render continuously without introducing incorrect wraparound connections.

Written by the indexing model from the issue text.

Assessment

Tech stack
matplotlib, numpy, python
Domain
data-visualization
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.