Straight line across the pole with Cartographic stereographic projection

I use cartography to create a map of the Arctic with a stereographic projection, and then draw a line (to show the position of the cross section) on top. If I use the following code, then the line does not go in a straight line along the pole, but instead goes along the line of latitude.

import cartopy.crs as ccrs import matplotlib.pyplot as plt x=[180,0] y=[50,50] ax = plt.axes(projection=ccrs.NorthPolarStereo()) ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree()) ax.plot(x,y,transform=ccrs.PlateCarree()) plt.gca().stock_img() plt.gca().coastlines() plt.show() 

To get around this, I need to change x and y to:

 x=[180,180,0,0] y=[50,90,90,50] 

so there are two data points at the North Pole. Is there a better solution for this?

Edit : image attached What is desired

Thanks,

Tim

+4
source share
2 answers

@ajdawson answer is correct. Using a geodetic transformation in this case will do the trick.

To understand the reason why the line was not what you expected it to look, we need to understand what the PlateCarree transform is.

First, let's notice that all lines drawn in the form transform=<projection> , using Cartopy, must go through the same geographical points, regardless of the projection on which the line is drawn.

 import cartopy.crs as ccrs import matplotlib.pyplot as plt def main(): x=[180, 180, 0, 0] y=[50, 90, 90, 50] # plot2 - North Polar Stereographic ax = plt.subplot(211, projection=ccrs.NorthPolarStereo()) ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree()) ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2) ax.stock_img() ax.coastlines() # plot2 - PlateCarree ax = plt.subplot(212, projection=ccrs.PlateCarree(central_longitude=45)) ax.set_extent([0, 360, -45, 90], crs=ccrs.PlateCarree()) ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2) ax.stock_img() ax.coastlines() plt.show() if __name__ == '__main__': main() 

output image - north polar stereo next to PlateCarree

So, back to drawing the original coordinates (which were in the coordinates of the PlateCarree) on the PlateCarree map:

 import cartopy.crs as ccrs import matplotlib.pyplot as plt def main(): x=[180, 0] y=[50, 50] ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=45)) ax.set_extent([0, 360, -45, 90], crs=ccrs.PlateCarree()) ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2) ax.stock_img() ax.coastlines() plt.tight_layout() plt.show() if __name__ == '__main__': main() 

PlateCarree line

You will find that the line goes through the same geographical points as your bad line in the original question.

This should satisfy you with the fact that Cartopy behaves rationally and is not a mistake, but does not answer the question of how you are going to draw the line you need.

@ajdawson already said that in your case we draw a line:

 plt.plot([180, 0], [50, 50] , transform=ccrs.Geodetic()) 

will lead to the desired result.

This is because the geodetic coordinate system draws the line of the shortest distance on the globe between two points. However, there will be a latitude which, at the intersection passing through the north pole, does not provide the shortest distance:

 import cartopy.crs as ccrs import matplotlib.pyplot as plt def main(): ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=45)) ax.set_global() ax.plot([180, 0], [20, 20], transform=ccrs.Geodetic(), color='red', lw=2, label='Latitude = 20') ax.plot([180, 0], [0, 0], transform=ccrs.Geodetic(), color='blue', lw=2, label='Latitude = 0') ax.plot([180, 0], [-20, -20], transform=ccrs.Geodetic(), color='yellow', lw=2, label='Latitude = -20') ax.outline_patch.set_zorder(2) plt.legend(loc=8, bbox_to_anchor=(0.65, -0.2), shadow=True, fancybox=True) ax.stock_img() ax.coastlines() plt.tight_layout() plt.show() if __name__ == '__main__': main() 

Non-north pole crossing geodetic lines

As a rule, if you want to draw a geodesic line that always crosses the North Pole, then the North Pole should be one of the coordinates of the line.

 plt.plot([180, 0, 0], [-45, 90, -45] , transform=ccrs.Geodetic()) 

Finally, just to throw it into the mix, if you need a vertical line in the north polar stereographic projection that crosses the North Pole, it’s worth remembering that there is a Cartesian coordinate system (in which it’s worth remembering that the numbers are not latitude and longitude), so just do :

 ax = plt.axes(projection=ccrs.NorthPolarStereo()) plt.axvline() 

There will also be a trick! (but less portable than the geodetic approach)

Wow, my answer dragged on. I hope you are still with me and this will make the whole PlateCarree clearer!

+7
source

I think you need to use geodetic conversion when building this section, and not in the Carree plate:

 <!-- language: lang-py --> import cartopy.crs as ccrs import matplotlib.pyplot as plt x=[180,0] y=[50,50] ax = plt.axes(projection=ccrs.NorthPolarStereo()) ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree()) ax.plot(x,y,transform=ccrs.Geodetic()) ax.stock_img() ax.coastlines() plt.show() 

The result is as follows:

section over North Pole

I think this is the right way to handle this anyway!

Andrew

+2
source

All Articles