如何使用 cartopy 和 matplotlib 绘制天梭?
How to plot a tissot with cartopy and matplotlib?
为了绘制天空图我刚从Basemap切换到cartopy,我更喜欢它
.
(主要原因是底图在某些计算机上出现段错误,我无法修复)。
我唯一遇到的困难是获得一个天梭圆(用于显示我们 telescope 的视锥)
这是一些绘制随机星星的示例代码(我使用真实的星表):
import matplotlib.pyplot as plt
from cartopy import crs
import numpy as np
# create some random stars:
n_stars = 100
azimuth = np.random.uniform(0, 360, n_stars)
altitude = np.random.uniform(75, 90, n_stars)
brightness = np.random.normal(8, 2, n_stars)
fig = plt.figure()
ax = fig.add_subplot(1,1,1, projection=crs.NorthPolarStereo())
ax.background_patch.set_facecolor('black')
ax.set_extent([-180, 180, 75, 90], crs.PlateCarree())
plot = ax.scatter(
azimuth,
altitude,
c=brightness,
s=0.5*(-brightness + brightness.max())**2,
transform=crs.PlateCarree(),
cmap='gray_r',
)
plt.show()
如何向该图像添加具有一定半径(以度为单位)的天梭圆?
https://en.wikipedia.org/wiki/Tissot%27s_indicatrix
我一直想返回并添加 GeographicLib 中的两个函数,这两个函数提供正向和逆向测地线计算,这只是通过在给定的适当方位角处采样来计算测地圆的简单问题 lat/lon/radius. las,我还没有这样做,但是在 pyproj 中有一个相当原始(但有效)的包装器来实现该功能。
然后要实现天梭指示器,代码可能类似于:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
from pyproj import Geod
import shapely.geometry as sgeom
def circle(geod, lon, lat, radius, n_samples=360):
"""
Return the coordinates of a geodetic circle of a given
radius about a lon/lat point.
Radius is in meters in the geodetic's coordinate system.
"""
lons, lats, back_azim = geod.fwd(np.repeat(lon, n_samples),
np.repeat(lat, n_samples),
np.linspace(360, 0, n_samples),
np.repeat(radius, n_samples),
radians=False,
)
return lons, lats
def main():
ax = plt.axes(projection=ccrs.Robinson())
ax.coastlines()
geod = Geod(ellps='WGS84')
radius_km = 500
n_samples = 80
geoms = []
for lat in np.linspace(-80, 80, 10):
for lon in np.linspace(-180, 180, 7, endpoint=False):
lons, lats = circle(geod, lon, lat, radius_km * 1e3, n_samples)
geoms.append(sgeom.Polygon(zip(lons, lats)))
ax.add_geometries(geoms, ccrs.Geodetic(), facecolor='blue', alpha=0.7)
plt.show()
if __name__ == '__main__':
main()
为了绘制天空图我刚从Basemap切换到cartopy,我更喜欢它 .
(主要原因是底图在某些计算机上出现段错误,我无法修复)。
我唯一遇到的困难是获得一个天梭圆(用于显示我们 telescope 的视锥)
这是一些绘制随机星星的示例代码(我使用真实的星表):
import matplotlib.pyplot as plt
from cartopy import crs
import numpy as np
# create some random stars:
n_stars = 100
azimuth = np.random.uniform(0, 360, n_stars)
altitude = np.random.uniform(75, 90, n_stars)
brightness = np.random.normal(8, 2, n_stars)
fig = plt.figure()
ax = fig.add_subplot(1,1,1, projection=crs.NorthPolarStereo())
ax.background_patch.set_facecolor('black')
ax.set_extent([-180, 180, 75, 90], crs.PlateCarree())
plot = ax.scatter(
azimuth,
altitude,
c=brightness,
s=0.5*(-brightness + brightness.max())**2,
transform=crs.PlateCarree(),
cmap='gray_r',
)
plt.show()
如何向该图像添加具有一定半径(以度为单位)的天梭圆? https://en.wikipedia.org/wiki/Tissot%27s_indicatrix
我一直想返回并添加 GeographicLib 中的两个函数,这两个函数提供正向和逆向测地线计算,这只是通过在给定的适当方位角处采样来计算测地圆的简单问题 lat/lon/radius. las,我还没有这样做,但是在 pyproj 中有一个相当原始(但有效)的包装器来实现该功能。
然后要实现天梭指示器,代码可能类似于:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
from pyproj import Geod
import shapely.geometry as sgeom
def circle(geod, lon, lat, radius, n_samples=360):
"""
Return the coordinates of a geodetic circle of a given
radius about a lon/lat point.
Radius is in meters in the geodetic's coordinate system.
"""
lons, lats, back_azim = geod.fwd(np.repeat(lon, n_samples),
np.repeat(lat, n_samples),
np.linspace(360, 0, n_samples),
np.repeat(radius, n_samples),
radians=False,
)
return lons, lats
def main():
ax = plt.axes(projection=ccrs.Robinson())
ax.coastlines()
geod = Geod(ellps='WGS84')
radius_km = 500
n_samples = 80
geoms = []
for lat in np.linspace(-80, 80, 10):
for lon in np.linspace(-180, 180, 7, endpoint=False):
lons, lats = circle(geod, lon, lat, radius_km * 1e3, n_samples)
geoms.append(sgeom.Polygon(zip(lons, lats)))
ax.add_geometries(geoms, ccrs.Geodetic(), facecolor='blue', alpha=0.7)
plt.show()
if __name__ == '__main__':
main()