问题
I'm playing around with cartopy trying to understand how it works. The first thing I tried was very similar to the example in the docs under the 'Adding Data to the Map' section.
I'm trying to draw a straight line from Adelaide, Australia to Liverpool, UK on my Robinson projection. This is my code:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.Robinson())
ax.coastlines()
ax.stock_img()
ad_lat, ad_lon = -34.93, 138.60
liv_lat, liv_lon = 53.41, -2.99
plt.plot([ad_lon, liv_lon], [ad_lat, liv_lat],
color='blue', linewidth=1, marker='o', markersize=3,
)
plt.show()
However this produces a single marker in the middle of the map. The docs say that by default, if you don't specify a transform property to plt.plot, it uses the one for the axes (Robinson in this case). When I explicitly add 'transform=ccrs.Robinson()' the same thing happens. However, it does let me use 'ccrs.Geodetic()' for a curved line, or ccrs.PlateCarree() for a slightly wonky straight line.
I can't find anything in the docs about the transform property being limited to some projections but not others, so I don't understand why this is happening. Can anyone shed some light on this?
回答1:
The transform argument is tied to the data you are plotting. You are specifying the start and end points of the line in lat/lon, and therefore the only sensible transforms are Geodetic and PlateCarree.
When you set transform=ccrs.Robinson()
Cartopy is assuming the coordinates you provided are already in the Robinson projection, which they are not. The Robinson projection extents in native coordinates are very large comapared to geographic coordinates (order ~1e7 perhaps) so both the points you selected are very near the centre of the projection, which is why you just see a dot.
If you want the line to be straight when drawn on the Robinson projection you will have to plot it in projection coordinates. This is straightforward using Cartopy's transforms system as in the modified example below. For more guidance on how Cartopy's transform/projection keywords work see https://scitools.org.uk/cartopy/docs/v0.16/tutorials/understanding_transform.html.
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.Robinson())
ax.coastlines()
ax.stock_img()
ad_lat, ad_lon = -34.93, 138.60
liv_lat, liv_lon = 53.41, -2.99
# New bit: transform the given lat/lon points into the Robinson projection
geodetic = ccrs.Geodetic()
robinson = ccrs.Robinson()
ad_lon_t, ad_lat_t = robinson.transform_point(ad_lon, ad_lat, geodetic)
liv_lon_t, liv_lat_t = robinson.transform_point(liv_lon, liv_lat, geodetic)
plt.plot([ad_lon_t, liv_lon_t], [ad_lat_t, liv_lat_t],
color='blue', linewidth=1, marker='o', markersize=3,
# Be explicit about which transform you want:
transform=robinson)
plt.show()
来源:https://stackoverflow.com/questions/52827226/plotting-a-straight-line-in-cartopy-robinson-projection