Question

Hi I'm trying to map a graph of ip addresses onto a world map using the greatcircle function in Basemap (part of matplot lib) but every time I connect two points that span across the Pacific Ocean (i.e. Somewhere in the USA west coast and australia) there is a horizontal line that shows up in my plot.

I know it's because of this problem:

Note Cannot handle situations in which the great circle intersects the edge of the map projection domain, and then re-enters the domain. (http://matplotlib.org/basemap/api/basemap_api.html#mpl_toolkits.basemap.Basemap.drawgreatcircle)

Just wondering if anyone knew how to fix it or knew of another package which didnt' have this problem. Thanks!

Was it helpful?

Solution

To solve this in Basemap for specific cases you can check the differences of the x vertices in the resulting path. From there, we can cut the bad path into two sections. I have thrown together my own example of doing this with basemap:

from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt


m = Basemap(projection='cyl', lon_0=0, resolution='c')

m.fillcontinents(color='coral',lake_color='aqua')
m.drawmapboundary(fill_color='aqua')

places = {'Mexico City': (19.05, -99.366667),
          'London': (51.507222, -0.1275),
          'Sydney': (-33.859972, 151.211111),
          'Cape Town': (-33.925278, 18.423889),
          'Delhi': (28.61, 77.23),
          }

network = [
           ('London', 'Delhi'),
           ('Mexico City', 'Sydney'),
           ]


for source, target in network:
    lat1, lon1 = places[source]
    lat2, lon2 = places[target]
    line, = m.drawgreatcircle(lon1, lat1, lon2, lat2, lw=3)

    p = line.get_path()
    # find the index which crosses the dateline (the delta is large)
    cut_point = np.where(np.abs(np.diff(p.vertices[:, 0])) > 200)[0]
    if cut_point:
        cut_point = cut_point[0]

        # create new vertices with a nan inbetween and set those as the path's vertices
        new_verts = np.concatenate(
                                   [p.vertices[:cut_point, :], 
                                    [[np.nan, np.nan]], 
                                    p.vertices[cut_point+1:, :]]
                                   )
        p.codes = None
        p.vertices = new_verts


plt.show()

The result:

example output

This is not a general solution, and will only work when you have latitudes and longitudes. Solving the general problem is much, much harder and is the focus of cartopy (http://scitools.org.uk/cartopy/docs/latest/). I will post an example of doing this the exact same plot in cartopy in the next couple of days.

HTH

OTHER TIPS

Another package which doesn't have this problem: cartopy (as yet, unannounced). The example found here is relevant.

HTH

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top