Search code examples
pythoncartopycyclone

Cartopy connects endpoints in cyclone tracks plots


when I plot (lat,lon) pairs on the globe using cartopy to get cyclone tracks, the points through the border of the map (180 degrees) get connected so I end with a long line over the whole globe. How can I sort that out and get nice tracks?

enter image description here

colormap = "RdYlBu_r"

pole_lon = -180
pole_lat = 90

fig = plt.figure(figsize=(20, 20))

ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_global()


ax.add_feature(cartopy.feature.OCEAN, color='white', zorder=0)
ax.add_feature(cartopy.feature.LAND, color='lightgray',zorder=0,
               linewidth=0.5, edgecolor='black')

ax.gridlines(draw_labels=True, linewidth=0.5, color='gray',
                 xlocs=range(-180,180,15), ylocs=range(-90,90,15))

ax.coastlines(resolution='50m', linewidth=0.3, color='black')
ax.set_title('', fontsize=10, fontweight='bold')

crs = ccrs.RotatedPole(pole_longitude=pole_lon, pole_latitude=pole_lat)
ax.set_extent([-180, 180, -90, 90 ], crs=ccrs.PlateCarree())

g=df.groupby('label')['xlat', 'xlon', 'date']

for i in range(len(c_l)):
    g_tmp=g.get_group(c_l[i]).sort_values(by = 'date', ascending=True)
    lat = g_tmp[['xlat', 'date']]
    lon = g_tmp[['xlon', 'date']]
    ax.plot(lon, lat, '-', transform=crs)
        
#ax.plot(-180, 0, '-', transform=crs)

I tried sorting the data because that was the only thing that Google suggested before, but sorting by date doesn't help and thus I think it is because of the plotting routine.


Solution

  • You can use ccrs.Geodetic() as the transformation, note that this will also cause the lines the follow the curvature of earth, and therefore no longer will show a straight line in between two coordinate pairs.

    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    import cartopy.feature as cfeature
    
    fig, ax = plt.subplots(
        figsize=(8, 4), dpi=100, facecolor="w",
        subplot_kw=dict(projection=ccrs.PlateCarree()), 
    )
    ax.set_global()
    
    ax.add_feature(
        cfeature.LAND, facecolor='lightgray', zorder=0, 
        linewidth=0.5, edgecolor='k',
    )
    
    ax.plot(
        [100, -100], [ 50, 20], '-', lw=3,
        transform=ccrs.Geodetic(), label="Geodetic()",
    )
    
    ax.plot(
        [100, -100], [-50,-20], '-', lw=3,
        transform=ccrs.PlateCarree(), label="PlateCarree()",
    )
    ax.legend(loc="upper center", framealpha=1, ncol=2)
    

    enter image description here