Matplotlib Circle patch не имеет ровных краев - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь отобразить патчи Matplotlib, используя функцию Circle на графике карты, используя картографические географические проекции. Очевидно, что это должно дать гладкое, почти безмасштабное круглое пятно, однако края очень многоугольные. Странно, но CirclePolygon, аналог многоугольной аппроксимации Circle, создает более гладкий круг , хотя все еще не так гладко, как хотелось бы.

Это почти весь код, связанный с добавлением графика и патчей:

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 голосов
/ 15 января 2019

Я полагаю, что Картопи делает линейные проекции с произвольной фиксированной точностью, а не динамическим вычислением разбиения линий.

Смотри, например, :

Я также думаю, что сейчас продолжается работа по решению этой проблемы.

А пока для решения конкретных проблем вы можете взломать свойство CRS.threshold, как объяснено здесь: https://github.com/SciTools/cartopy/issues/8
То есть вы можете сделать его более точным, перепрограммировав фиксированное значение.
Я думаю, что это также решило бы проблему рисования кругов, хотя я не на 100%

0 голосов
/ 15 января 2019

Я считаю, что построение индикатрис Тиссо более уместно в вашем случае. Индикаторная матрица представляет земной круг на проекции карты. Во многих случаях индикатрисы отображаются в виде эллипсов, поскольку проекции карты не всегда сохраняют фигуры. Ниже приведен рабочий код, который отображает все земные круги радиусом = 55 км на требуемой вами проекции карты. Прочитайте комментарии в коде для некоторой полезной информации.

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...