Как увеличить масштаб до определенной широты в файле cartopy.crs.Orthographic?

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

орто-60

Способ 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()
 

img2

Способ 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()
 

орто_н_круг