@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]

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()

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()

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!