Список повторной выборки точек широты

Приведенный ниже код считывает данные о местонахождении действующих ASOS (метеорологических станций) по всему миру. Я хотел бы использовать этот список в будущем как список точек для построения данных, но многие станции расположены слишком близко друг к другу, чтобы их можно было просматривать в масштабе страны или даже штата. Я бы хотел уменьшить плотность станций, нанесенных на карту. Ниже приведен код, отображающий все станции в США / южной Канаде:

import re

fh = open('../498/stations.txt', 'r')
lines = fh.readlines()

data = []
for line in lines:
    comment_match = re.search('^!', line)
    blank_match = re.search('^\s*$', line)
    header_match = re.search('\d{2}-\w{3}-\d{2}|CD\s+STATION', line)
    if comment_match or blank_match or header_match:
        None
    else:
        ICAO = line[20:24].strip()
        if len(ICAO) == 4:
            CD = line[0:3].strip()
            if len(CD) == 0:
                CD = None
            STATION = line[3:20].strip()
            LATLON = line[39:54]
            if LATLON[5] == 'S':
                LAT = float("{0:.2f}".format(-(float(LATLON[0:2])+float(LATLON[3:5])/60.)))
            if LATLON[5] == 'N':
                LAT = float("{0:.2f}".format((float(LATLON[0:2])+float(LATLON[3:5])/60.)))
            if LATLON[14] == 'W':
                LON = float("{0:.2f}".format(-(float(LATLON[8:11])+float(LATLON[12:14])/60.)))
            if LATLON[14] == 'E':
                LON = float("{0:.2f}".format((float(LATLON[8:11])+float(LATLON[12:14])/60.)))
            ELEV = int(line[54:59].strip())
            C = line[81:-1]
            stn_dict = {'name':STATION, 'id':ICAO, 'state':CD, 'country':C, 'lat':LAT, 'lon':LON, 'elev':ELEV}
            data.append(stn_dict)

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt

extent = [-130,-60,20,60]

fig = plt.figure(figsize=(15,12))
ax = fig.add_subplot(111,projection=ccrs.Miller())
ax.coastlines(resolution='50m')
ax.add_feature(cfeature.STATES.with_scale('50m'))
ax.set_extent(extent,crs=ccrs.Miller())

for stndict in data:
    if stndict['lon'] > extent[0] and stndict['lon'] < extent[1] and stndict['lat'] > extent[2] and stndict['lat'] < extent[3]:
        plt.plot(stndict['lon'], stndict['lat'], color='blue', marker='o',
         transform=ccrs.PlateCarree())

Вот результат выполнения кода. Вы можете увидеть, что множество графиков расположены поверх одного. другой в этом масштабе карты. В идеале я хотел бы иметь возможность изменять расстояние между нанесенными точками, например, 100 км.

Есть ли библиотеки, которые упростили бы эту задачу?


person Karl Schneider    schedule 13.06.2019    source источник
comment
Matplotlib Basemap имеет hexbin график, который показывает плотность встречаемости точек.   -  person swatchai    schedule 14.06.2019


Ответы (1)


MetPy имеет функцию _ 1_, который может делать то, что вы хотите. Эта функция принимает местоположения ваших станций в виде массива (количество точек) x размеров (например, 2 или 3) вместе с радиусом, минимальным расстоянием до ближайшей точки в результате. Результатом является логический массив, который можно использовать в качестве маски для выбора точек интереса. Вы используете это как:

from metpy.calc import reduce_point_density
import numpy as np
point_locs = np.array([(10, 50), (11, 49), (35, 40)])
mask = reduce_point_density(point_locs, 4.)
keep_points = point_locs[mask]

Вы также можете при желании передать массив значений приоритета, который позволяет контролировать, какие точки предпочтительно выбираются для сохранения. Более крупный пример использования reduce_point_density находится здесь.

person DopplerShift    schedule 14.06.2019