Matplotlib Circle贴片没有光滑的边缘

时间:2019-01-15 04:06:14

标签: python matplotlib cartopy

我正在尝试使用Circle函数在使用Cartopy地理投影的地图上显示Matplotlib补丁。显然,这应该会提供一个平滑的,接近无比例的圆形补丁,但是边缘非常多边形。奇怪的是,CirclePolygon(与Circle近似的多边形)产生了一个 smoother 圆,尽管它仍然不如我所希望的那样平滑。

这几乎是所有与添加绘图和补丁有关的代码:

fig = plt.figure(figsize=(8,6))
img_extent = [340, 348, -35.5, -31]
ax = fig.add_subplot(1, 1, 1, projection = ccrs.Mollweide(), extent = img_extent)
patch_coords = [[342.5833, -34.5639],[343.4042, -34.3353],[343.8500, -33.8728],
                 [344.4917, -33.7636],[344.9250, -33.3108],[345.1333, -32.6811],
                   [344.9233, -32.1583]]
for pair in patch_coords:
    ax.add_patch(mpatches.Circle(xy = pair, radius = 0.5, 
                   color = 'r', alpha = 0.3, rasterized = None, 
                      transform = ccrs.Geodetic()))
ax.scatter(ra1, dec1, transform = ccrs.Geodetic(), rasterized = True, s = 1, 
             marker = ".", c = 'g', label = 'z < 0.025')
ax.scatter(ra2, dec2, transform = ccrs.Geodetic(), rasterized = True, s = 2, 
             marker = ".", c = 'b', label = '0.25 < z < 0.034')
ax.scatter(ra3, dec3, transform = ccrs.Geodetic(), rasterized = True, s = 0.75, 
             marker = ".", c = 'grey', label = '0.034 < z < 0.05')

哪个生产这个

Plot

我尝试浏览可用的参数,但似乎没有一个可以解决。有这样一个原因的原因吗?有什么办法可以使它更平滑?

2 个答案:

答案 0 :(得分:2)

我认为绘制Tissot的Indicicatrics在您的情况下更合适。 Indicatrix代表地图投影上的地面圆。在许多情况下,由于地图投影并不总是保留形状,因此将Indicatrices渲染为椭圆形。以下是在您想要的地图投影上绘制半径= 55 km的所有地面圆的工作代码。阅读代码中的注释以获取一些有用的信息。

import matplotlib.pyplot as plt
# import matplotlib.patches as mpatches
import cartopy.crs as ccrs
import numpy as np

fig = plt.figure(figsize=(12,8))

img_extent = [340, 348, -35.5, -31]
ax = fig.add_subplot(1, 1, 1, projection = ccrs.Mollweide(), extent = img_extent)

patch_coords = [[342.5833, -34.5639],[343.4042, -34.3353],[343.8500, -33.8728],
                 [344.4917, -33.7636],[344.9250, -33.3108],[345.1333, -32.6811],
                   [344.9233, -32.1583]]

for ix,pair in enumerate(patch_coords):
    # plot tissot indicatrix at each location 
    # n_samples = number of points forming indicatrix' perimeter
    # rad_km = 55 km. is about the angular distance 0.5 degree
    ax.tissot(rad_km=55, lons=np.array(patch_coords)[:,0][ix], \
              lats=np.array(patch_coords)[:,1][ix], n_samples=36, \
             facecolor='red', edgecolor='black', linewidth=0.15, alpha = 0.3)

gl = ax.gridlines(draw_labels=False, linewidth=1, color='blue', alpha=0.3, linestyle='--')
plt.show()

结果图:

enter image description here

修改

由于代码的第一个版本不是最佳的。 代码更新如下:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
fig = plt.figure(figsize=(12,8))

img_extent = [340, 348, -35.5, -31]
ax = fig.add_subplot(1, 1, 1, projection = ccrs.Mollweide(), extent = img_extent)

patch_coords = [[342.5833, -34.5639],[343.4042, -34.3353],[343.8500, -33.8728],
                 [344.4917, -33.7636],[344.9250, -33.3108],[345.1333, -32.6811],
                   [344.9233, -32.1583]]

for pair in patch_coords:
    # plot tissot indicatrix at each location 
    # n_samples = number of points forming indicatrix' perimeter
    # rad_km = 55 km. is about the angular distance 0.5 degree at equator
    ax.tissot(rad_km=55, lons=pair[0], lats=pair[1], n_samples=36, \
             facecolor='red', edgecolor='black', linewidth=0.15, alpha = 0.3)

gl = ax.gridlines(draw_labels=False, linewidth=1, color='blue', alpha=0.3, linestyle='--')
plt.show()

答案 1 :(得分:2)

我相信Cartopy可以以任意固定的精度而不是动态的线分割计算来进行线投影。

例如参见:

我也认为目前正在努力解决该问题。

同时,要解决特定问题,您可以破解CRS.threshold属性, 如此处所述:https://github.com/SciTools/cartopy/issues/8
也就是说,可以通过重新编程固定值来使其使用更精细的步骤。
我认为这也可以解决这个画圆的问题,尽管我不是100%