I have following dataframe (corresponding csv is hosted here: http://www.sharecsv.com/s/3795d862c1973efa311d8a770e978215/t.csv)
lat lon
count 6159.000000 6159.000000
mean 37.764859 -122.355491
std 0.028214 0.038874
min 37.742200 -122.482783
25% 37.746317 -122.360133
50% 37.746417 -122.333717
75% 37.785825 -122.331300
max 37.818133 -122.331167
Following code plots correctly:
test_ax = plt.axes(projection=ccrs.Mercator())
test_ax.plot(test_df['lon'], test_df['lat'], color="blue", linewidth=4, alpha=1.0,
transform=ccrs.Geodetic())
plt.show()
But if I take one subset, it doesn't:
test_ax = plt.axes(projection=ccrs.Mercator())
test_ax.plot(test_df['lon'][:1001], test_df['lat'][:1001], color="blue", linewidth=4, alpha=1.0,
transform=ccrs.Geodetic())
plt.show()
But does so with another subset.
test_ax = plt.axes(projection=ccrs.Mercator())
test_ax.plot(test_df['lon'][:3501], test_df['lat'][:3501], color="blue", linewidth=4, alpha=1.0,
transform=ccrs.Geodetic())
plt.show()
I am pretty sure I am doing something stupid, but I am just unable to figure the reason for this behaviour.
Edit:
On further experimentation I found that if I set the extent of map manually to include 0
meridian, the plot for the subset :1001
, which wasn't showing earlier starts showing (the blue dot near San Francisco).
test_ax = plt.axes(projection=ccrs.Mercator())
test_ax.plot(test_df['lon'][:1001], test_df['lat'][:1001], color="blue", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax.coastlines()
test_ax.set_extent([-130, 0, 30, 40], crs=ccrs.Geodetic())
test_ax.gridlines(draw_labels=True)
plt.show()
Edit: with reproducible example
(For jupyter notebook)
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import pandas as pd
df_csv_url = 'http://www.sharecsv.com/dl/76dd767525a37180ca54cd1d9314b9dc/t1.csv'
test_df = pd.read_csv(df_csv_url)
figure_params = { 'width': 9.6, 'height': 5.4 }
fig = plt.figure(
figsize=(figure_params["width"], figure_params["height"])
)
test_ax = fig.add_axes((0, 0.5, 0.5, 0.5), projection=ccrs.Mercator(), label="map1")
test_ax.plot(test_df['lon'], test_df['lat'], color="blue", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax.coastlines()
test_ax.gridlines(draw_labels=True)
test_ax.set_title("Path doesn\'t show", y=1.5)
# Including 0 meridian in extent shows the path
test_ax1 = fig.add_axes((0, 0, 0.5, 0.5), projection=ccrs.Mercator(), label="map2")
test_ax1.plot(test_df['lon'], test_df['lat'], color="blue", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax1.set_extent([-130, 0, 30, 40], crs=ccrs.Geodetic())
test_ax1.coastlines()
test_ax1.gridlines(draw_labels=True)
test_ax1.set_title("Path shows (blue dot near San Francisco)", y=1.1)
plt.show()
Edit
(with simplified reproducible example)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
test_df = pd.DataFrame()
test_df['lon'] = np.linspace(-120, -60, num=1000)
test_df['lat'] = 38
test_df1 = pd.DataFrame()
test_df1['lon'] = np.linspace(-120, -60, num=1001)
test_df1['lat'] = 38
fig = plt.figure()
meridian=0
test_ax = fig.add_axes((0, 0, 1, 0.6), projection=ccrs.Mercator())
test_ax.plot(test_df['lon'], test_df['lat'], color="blue", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax.coastlines()
test_ax.set_extent((-125, meridian, 36, 38))
gl = test_ax.gridlines(draw_labels=True)
gl.xlabels_top = False
gl.ylabels_left = False
test_ax.set_title('Path with {} points, eastern edge={}'.format(len(test_df),meridian))
test_ax1 = fig.add_axes((0, 0.7, 1, 0.6), projection=ccrs.Mercator())
test_ax1.plot(test_df1['lon'], test_df1['lat'], color="red", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax1.coastlines()
test_ax1.set_extent((-125, meridian, 36, 38))
gl1 = test_ax1.gridlines(draw_labels=True)
gl1.xlabels_top = False
gl1.ylabels_left = False
test_ax1.set_title('Path with {} points, eastern edge={}'.format(len(test_df1),meridian))
meridian=-10
test_ax2 = fig.add_axes((0, 1.4, 1, 0.6), projection=ccrs.Mercator())
test_ax2.plot(test_df['lon'], test_df['lat'], color="black", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax2.coastlines()
test_ax2.set_extent((-125, -10, 36, 38))
gl2 = test_ax2.gridlines(draw_labels=True)
gl2.xlabels_top = False
gl2.ylabels_left = False
test_ax2.set_title('Path with {} points, eastern edge={}'.format(len(test_df),meridian))
test_ax3 = fig.add_axes((0, 2.1, 1, 0.6), projection=ccrs.Mercator())
test_ax3.plot(test_df1['lon'], test_df1['lat'], color="green", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax3.coastlines()
test_ax3.set_extent((-125, -10, 36, 38))
gl3 = test_ax3.gridlines(draw_labels=True)
gl3.xlabels_top = False
gl3.ylabels_left = False
test_ax3.set_title('Path with {} points, eastern edge={}'.format(len(test_df1),meridian))
plt.show()
I have been able to find another workaround. If the points are transformed prior to using the plot
function (instead of passing the transform
parameter), it works.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
test_df = pd.DataFrame()
test_df['lon'] = np.linspace(-120, -60, num=1000)
test_df['lat'] = 38
test_df1 = pd.DataFrame()
test_df1['lon'] = np.linspace(-120, -60, num=1001)
test_df1['lat'] = 38
fig = plt.figure()
meridian=0
test_ax = fig.add_axes((0, 0, 1, 0.6), projection=ccrs.Mercator())
test_ax.plot(test_df['lon'], test_df['lat'], color="blue", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax.coastlines()
test_ax.set_extent((-125, meridian, 36, 38))
gl = test_ax.gridlines(draw_labels=True)
gl.xlabels_top = False
gl.ylabels_left = False
test_ax.set_title('Path with {} points, eastern edge={}'.format(len(test_df),meridian))
test_ax1 = fig.add_axes((0, 0.7, 1, 0.6), projection=ccrs.Mercator())
test_ax1.plot(test_df1['lon'], test_df1['lat'], color="red", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax1.coastlines()
test_ax1.set_extent((-125, meridian, 36, 38))
gl1 = test_ax1.gridlines(draw_labels=True)
gl1.xlabels_top = False
gl1.ylabels_left = False
test_ax1.set_title('Path with {} points, eastern edge={}'.format(len(test_df1),meridian))
meridian=-10
test_ax2 = fig.add_axes((0, 1.4, 1, 0.6), projection=ccrs.Mercator())
test_ax2.plot(test_df['lon'], test_df['lat'], color="black", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax2.coastlines()
test_ax2.set_extent((-125, -10, 36, 38))
gl2 = test_ax2.gridlines(draw_labels=True)
gl2.xlabels_top = False
gl2.ylabels_left = False
test_ax2.set_title('Path with {} points, eastern edge={}'.format(len(test_df),meridian))
test_ax3 = fig.add_axes((0, 2.1, 1, 0.6), projection=ccrs.Mercator())
test_ax3.plot(test_df1['lon'], test_df1['lat'], color="green", linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax3.coastlines()
test_ax3.set_extent((-125, -10, 36, 38))
gl3 = test_ax3.gridlines(draw_labels=True)
gl3.xlabels_top = False
gl3.ylabels_left = False
test_ax3.set_title('Path with {} points, eastern edge={}'.format(len(test_df1),meridian))
test_ax4 = fig.add_axes((0, 2.8, 1, 0.6), projection=ccrs.Mercator())
# Instead of transforming within the plot function, transform and then plot
transformed_points = ccrs.Mercator().transform_points(ccrs.Geodetic(), test_df1['lon'].values, test_df1['lat'].values)
test_ax4.plot([p[0] for p in transformed_points], [p[1] for p in transformed_points], color="green", linewidth=4, alpha=1.0)
test_ax4.coastlines()
test_ax4.set_extent((-125, -10, 36, 38))
gl3 = test_ax4.gridlines(draw_labels=True)
gl3.xlabels_top = False
gl3.ylabels_left = False
test_ax4.set_title('Path with {} prior transformed points, eastern edge={}'.format(len(test_df1),meridian))
plt.show()