简体   繁体   English

Matplotlib Circle补丁没有光滑的边缘

[英]Matplotlib Circle patch does not have smooth edges

I'm trying to display Matplotlib patches using the Circle function on a map plot using cartopy geographical projections. 我正在尝试使用Cartopy地理投影在地图上使用Circle函数显示Matplotlib补丁。 Apparently this is supposed to give a smooth, near scale-free circular patch, however the edges are very polygonal. 显然,这应该是一个平滑的,接近无标度的圆形贴片,但边缘是非常多边形的。 Strangely, CirclePolygon , the polygonal approximation counterpart of Circle , produces a smoother circle, albeit still not as smooth as I would like. 奇怪的是, CirclePolygon ,的多边形逼近对口Circle ,产生平滑的圆形,尽管还没有那样顺利,因为我想。

This is pretty much all the code as it pertains to adding the plot and the patches: 这几乎是所有代码,因为它与添加绘图和补丁有关:

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

Which produces this 产生这个

情节

I've tried looking through the available arguments but none seem to fix it. 我试过查看可用的参数,但似乎没有解决它。 Is there a reason why it comes out like this and is there any way to make it smoother? 它是否有这样的原因出现,是否有任何方法使它更顺畅?

I believe plotting Tissot's Indicatrices is more appropriate in your case. 我相信在您的情况下绘制天梭的Indicatrices更合适。 An Indicatrix represents a ground circle on a map projection. Indicatrix表示地图投影上的地面圆。 In many cases, the Indicatrices are rendered as ellipses as map projections do not always preserve shapes. 在许多情况下,Indicatrices呈现为椭圆形,因为地图投影并不总是保留形状。 The following is the working code that plots all the ground circles of radius = 55 km on the map projection that you desire. 以下是在您想要的地图投影上绘制半径= 55 km的所有地面圆的工作代码。 Read the comments in the code for some useful information. 阅读代码中的注释以获取一些有用的信息。

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

The resulting plot: 由此产生的情节:

在此输入图像描述

Edit 编辑

Since the first version of the code is not optimal. 由于代码的第一个版本不是最佳的。 Code update is offered as follows: 代码更新提供如下:

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

I believe that Cartopy does line projections with an arbitrary fixed accuracy, rather than a dynamic line-split calculation. 我相信Cartopy以任意固定精度进行线投影,而不是动态线分割计算。

See eg : 见例如:

I also think work is ongoing right now to address that. 我还认为现在正在开展工作以解决这个问题。

In the meantime, to solve specific problems you can hack the CRS.threshold property, as explained here : https://github.com/SciTools/cartopy/issues/8 在此期间,要解决特定问题,您可以破解CRS.threshold属性,如下所述: https//github.com/SciTools/cartopy/issues/8
That is, you can make it use finer steps by reprogramming the fixed value. 也就是说,您可以通过重新编程固定值来使用更精细的步骤。
I think this would also fix this circle-drawing problem, though I'm not 100% 我认为这也可以解决这个圆形绘图问题,虽然我不是100%

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM