尝试绘制简单的纬度/经度点时遇到奇怪的问题
Facing weird problem when trying to plot simple lat/ lon points
我有以下数据框(相应的 csv 托管在这里: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
正确绘制以下代码:
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()
但是如果我取一个子集,它不会:
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()
但对另一个子集也是如此。
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()
我很确定我在做一些愚蠢的事情,但我无法弄清楚这种行为的原因。
编辑:
在进一步的实验中,我发现如果我手动设置地图的范围以包括 0
子午线,则之前未显示的子集 :1001
的绘图开始显示(蓝色点在旧金山附近)。
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()
编辑:具有可重现的示例
(对于 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()
编辑
(带有简化的可重现示例)
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()
鉴于 cartopy 似乎存在一些问题,我看到的最好的解决方法是将您的数据分成少于 1000 的块,然后绘制它的所有部分。
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=1001)
test_df['lat'] = 38
fig = plt.figure()
meridian=0
test_ax = fig.add_axes((0, 0.05, 1, 0.3), projection=ccrs.Mercator())
test_ax.plot(test_df['lon'], test_df['lat'], color="red",
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))
meridian=-10
test_ax3 = fig.add_axes((0, 0.55, 1, 0.3), projection=ccrs.Mercator())
# plot first 500
test_ax3.plot(test_df['lon'][:500], test_df['lat'][:500], color="green",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
# plot to cover the gap
test_ax3.plot(test_df['lon'][499:501], test_df['lat'][499:501], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
# plot last 501
test_ax3.plot(test_df['lon'][500:], test_df['lat'][500:], color="yellow",
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_df),meridian))
plt.show()
1001分的情况,我只是拆分成一段500分和一段501分
因为你画的是线,所以我也添加了图来弥补差距,放大时显示为蓝色。
如果您还绘制了点,那么设置间隙填充器而不是重叠两个部分的原因就来了,如下所示:
test_ax3.plot(test_df['lon'][:500], test_df['lat'][:500], color="green",
linewidth=1, alpha=1.0, transform=ccrs.Geodetic(), marker='.')
# plot to cover the gap
test_ax3.plot(test_df['lon'][499:501], test_df['lat'][499:501], color="blue",
linewidth=1, alpha=1.0, transform=ccrs.Geodetic(), marker=None)
# plot last 501
test_ax3.plot(test_df['lon'][500:], test_df['lat'][500:], color="yellow",
linewidth=1, alpha=1.0, transform=ccrs.Geodetic(), marker='.')
通过分离填充物,您可以确保没有重复点,如果您的 alpha 值小于 1.0
。
,这可能是个问题
将此应用于您的原始数据,您可以创建一个函数,以等于您想要的任何大小的块循环遍历数据帧。:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import pandas as pd
PLOT_LIMIT = 1000
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"])
)
print(len(test_df['lon']))
def ax_plot(test_ax, test_df):
# this function will loop over the dataframe in chunks equal to PLOT_LIMIT
len_df = len(test_df)
n=0
for i in range(len_df//PLOT_LIMIT):
test_ax.plot(test_df['lon'][1000*i:1000*(i+1)], test_df['lat'][1000*i:1000*(i+1)], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
if (len_df-((n+1)*PLOT_LIMIT)) != 0:
test_ax.plot(test_df['lon'][(1000*i)-1:(1000*(i+1))+1], test_df['lat'][(1000*i)-1:(1000*(i+1))+1], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic(), marker='None')
n+=1
test_ax.plot(test_df['lon'][1000*n:], test_df['lat'][1000*n:], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax1 = fig.add_axes((0, 0.55, 1, 0.45), projection=ccrs.Mercator(), label="map1")
ax_plot(test_ax1, test_df)
test_ax1.coastlines()
test_ax1.gridlines(draw_labels=True)
test_ax1.set_title("Path shows", y=1.5)
# Including 0 meridian in extent shows the path
test_ax2 = fig.add_axes((0, 0.1, 1, 0.45), projection=ccrs.Mercator(), label="map2")
ax_plot(test_ax2, test_df)
test_ax2.set_extent([-130, -30, 30, 40], crs=ccrs.Geodetic())
test_ax2.coastlines()
test_ax2.gridlines(draw_labels=True)
test_ax2.set_title("Path shows (blue dot near San Francisco)", y=1.1)
plt.show()
如您所见,您现在应该可以灵活地设置地图上的视图 window。我没有检查像穿越反子午线这样的边缘情况,但在所展示的情况下它是有效的。
我找到了另一种解决方法。如果在使用 plot
函数之前转换点(而不是传递 transform
参数),它会起作用。
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()
我有以下数据框(相应的 csv 托管在这里: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
正确绘制以下代码:
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()
但是如果我取一个子集,它不会:
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()
但对另一个子集也是如此。
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()
我很确定我在做一些愚蠢的事情,但我无法弄清楚这种行为的原因。
编辑:
在进一步的实验中,我发现如果我手动设置地图的范围以包括 0
子午线,则之前未显示的子集 :1001
的绘图开始显示(蓝色点在旧金山附近)。
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()
编辑:具有可重现的示例
(对于 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()
编辑
(带有简化的可重现示例)
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()
鉴于 cartopy 似乎存在一些问题,我看到的最好的解决方法是将您的数据分成少于 1000 的块,然后绘制它的所有部分。
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=1001)
test_df['lat'] = 38
fig = plt.figure()
meridian=0
test_ax = fig.add_axes((0, 0.05, 1, 0.3), projection=ccrs.Mercator())
test_ax.plot(test_df['lon'], test_df['lat'], color="red",
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))
meridian=-10
test_ax3 = fig.add_axes((0, 0.55, 1, 0.3), projection=ccrs.Mercator())
# plot first 500
test_ax3.plot(test_df['lon'][:500], test_df['lat'][:500], color="green",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
# plot to cover the gap
test_ax3.plot(test_df['lon'][499:501], test_df['lat'][499:501], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
# plot last 501
test_ax3.plot(test_df['lon'][500:], test_df['lat'][500:], color="yellow",
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_df),meridian))
plt.show()
1001分的情况,我只是拆分成一段500分和一段501分
因为你画的是线,所以我也添加了图来弥补差距,放大时显示为蓝色。
如果您还绘制了点,那么设置间隙填充器而不是重叠两个部分的原因就来了,如下所示:
test_ax3.plot(test_df['lon'][:500], test_df['lat'][:500], color="green",
linewidth=1, alpha=1.0, transform=ccrs.Geodetic(), marker='.')
# plot to cover the gap
test_ax3.plot(test_df['lon'][499:501], test_df['lat'][499:501], color="blue",
linewidth=1, alpha=1.0, transform=ccrs.Geodetic(), marker=None)
# plot last 501
test_ax3.plot(test_df['lon'][500:], test_df['lat'][500:], color="yellow",
linewidth=1, alpha=1.0, transform=ccrs.Geodetic(), marker='.')
通过分离填充物,您可以确保没有重复点,如果您的 alpha 值小于 1.0
。
将此应用于您的原始数据,您可以创建一个函数,以等于您想要的任何大小的块循环遍历数据帧。:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import pandas as pd
PLOT_LIMIT = 1000
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"])
)
print(len(test_df['lon']))
def ax_plot(test_ax, test_df):
# this function will loop over the dataframe in chunks equal to PLOT_LIMIT
len_df = len(test_df)
n=0
for i in range(len_df//PLOT_LIMIT):
test_ax.plot(test_df['lon'][1000*i:1000*(i+1)], test_df['lat'][1000*i:1000*(i+1)], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
if (len_df-((n+1)*PLOT_LIMIT)) != 0:
test_ax.plot(test_df['lon'][(1000*i)-1:(1000*(i+1))+1], test_df['lat'][(1000*i)-1:(1000*(i+1))+1], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic(), marker='None')
n+=1
test_ax.plot(test_df['lon'][1000*n:], test_df['lat'][1000*n:], color="blue",
linewidth=4, alpha=1.0, transform=ccrs.Geodetic())
test_ax1 = fig.add_axes((0, 0.55, 1, 0.45), projection=ccrs.Mercator(), label="map1")
ax_plot(test_ax1, test_df)
test_ax1.coastlines()
test_ax1.gridlines(draw_labels=True)
test_ax1.set_title("Path shows", y=1.5)
# Including 0 meridian in extent shows the path
test_ax2 = fig.add_axes((0, 0.1, 1, 0.45), projection=ccrs.Mercator(), label="map2")
ax_plot(test_ax2, test_df)
test_ax2.set_extent([-130, -30, 30, 40], crs=ccrs.Geodetic())
test_ax2.coastlines()
test_ax2.gridlines(draw_labels=True)
test_ax2.set_title("Path shows (blue dot near San Francisco)", y=1.1)
plt.show()
如您所见,您现在应该可以灵活地设置地图上的视图 window。我没有检查像穿越反子午线这样的边缘情况,但在所展示的情况下它是有效的。
我找到了另一种解决方法。如果在使用 plot
函数之前转换点(而不是传递 transform
参数),它会起作用。
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()