#python #maps #zooming #cartopy #orthographic
Вопрос:
Я не уверен, возможно ли это, но я, по сути, пытаюсь изолировать широту Северного полярного круга (60N) на орфографической карте И сохранить эллипсоид, чтобы увеличенное изображение не было прямоугольником/квадратом.
Вот что у меня есть:
fig = plt.figure(figsize=[20, 10])
ax1 = plt.subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))
for ax in [ax1]:
ax.coastlines(zorder=2)
ax.stock_img()
ax.gridlines()
Это дает вид на северный полюс, который я хочу, но я бы хотел, чтобы он остановился на 60N.
Комментарии:
1. К вашему сведению, если вы нажмете
accept
на мой ответ, вы получите 3 балла.2. Что, если я хочу, чтобы все было по кругу?
3. Пожалуйста, задайте это как новый вопрос. Обратитесь к этому как к смежной теме. Больше людей увидят, и вы быстрее получите ответы.
4. Возможно, я не сформулировал это четко, но сохранение круговой проекции было включено в исходный вопрос, и я беспокоюсь, что, если я снова задам тот же вопрос, меня за это оштрафуют.
Ответ №1:
Чтобы получить масштаб и квадратный экстент орфографической карты, вам нужно построить несколько контрольных точек (например, с помощью .scatter) или указать правильные extent
координаты в проекции (сложнее). Вот код, который нужно попробовать.
import cartopy
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
fig = plt.figure(figsize=[8, 8])
lonlatproj = ccrs.PlateCarree()
my_projn = ccrs.Orthographic(central_longitude=0,central_latitude=90)
ax1 = plt.subplot(1, 1, 1, projection=my_projn)
# set `lowlat` as lower limits of latitude to plot some points
# these points will determine the plot extents of the map
lowlat = 60 2.8 # and get 60
lons, lats = [-180,-90,0,90], [lowlat,lowlat,lowlat,lowlat]
# plot invisible points to get map extents
ax1.scatter(lons, lats, s=0, color='r', transform=lonlatproj)
#ax1.stock_img() #uncomment to get it plotted
ax1.coastlines(lw=0.5, zorder=2)
ax1.gridlines(lw=2, ec='black', draw_labels=True)
Способ 2: Путем указания правильного экстента в координатах проекции
import cartopy
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
fig = plt.figure(figsize=[8, 8])
lonlatproj = ccrs.PlateCarree()
my_projn = ccrs.Orthographic(central_longitude=0,central_latitude=90)
ax1 = plt.subplot(1, 1, 1, projection=my_projn)
# These 2 lines of code grab extents in projection coordinates
_, y_min = my_projn.transform_point(0, 60, lonlatproj) #(0.0, -3189068.5)
x_max, _ = my_projn.transform_point(90, 60, lonlatproj) #(3189068.5, 0)
# prep extents of the axis to plot map
pad = 25000
xmin,xmax,ymin,ymax = y_min-pad, x_max pad, y_min-pad, x_max pad
# set extents with prepped values
ax1.set_extent([xmin,xmax,ymin,ymax], crs=my_projn) # data/projection coordinates
ax1.stock_img()
ax1.coastlines(lw=0.5, zorder=2)
# plot other layers of data here using proper values of zorder
# finally, plot gridlines
ax1.gridlines(draw_labels=True, x_inline=False, y_inline=True,
color='k', linestyle='dashed', linewidth=0.5)
plt.show()
Способ 3 Постройте карту с круговой границей
Выполняемый код:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import numpy as np
r_limit = 3214068.5 #from: ax.get_ylim() of above plot
# some settings
lonlatproj = ccrs.PlateCarree()
my_projn = ccrs.Orthographic(central_longitude=0, central_latitude=90)
fig = plt.figure(figsize=[8, 8])
ax = plt.subplot(1, 1, 1, projection=my_projn)
# add bluemarble image
ax.stock_img()
# add coastlines
ax.coastlines(lw=0.5, color="black", zorder=20)
# draw graticule (of meridian and parallel lines)
gls = ax.gridlines(draw_labels=True, crs=ccrs.PlateCarree(), lw=3, color="gold",
y_inline=True, xlocs=range(-180,180,30), ylocs=range(-80,91,10))
# add extra padding to the plot extents
r_extent = r_limit*1.0001
ax.set_xlim(-r_extent, r_extent)
ax.set_ylim(-r_extent, r_extent)
# Prep circular boundary
circle_path = mpath.Path.unit_circle()
circle_path = mpath.Path(circle_path.vertices.copy() * r_limit,
circle_path.codes.copy())
#set circle boundary
ax.set_boundary(circle_path)
#hide frame
ax.set_frame_on(False) #hide the rectangle frame
plt.show()