Фон
Я работаю с набором из 8000 географических точек, содержащихся в CSV-файле. С одной стороны я создаю визуализацию диаграмм Вороного, построенных по этим точкам - это делается с помощью библиотеки D3. С другой стороны, я вычисляю эти диаграммы Вороного в Python, используя Scipy.
Моя логика работы проста — я работаю со своими данными на стороне Python, делаю тепловые карты, анализирую и так далее, а затем визуализирую эффекты с помощью D3. Но сегодня я случайно обнаружил, что диаграммы Вороного, сделанные Scipy и D3, отличаются. Я заметил это после использования geojson.io для построения GeoJsons of Voronois, сделанных на Python, просто чтобы посмотреть, смогу ли я все там визуализировать.
Как я уже сказал, Вороные были разные - у некоторых из них были другие углы, а у некоторых даже были дополнительные вершины.
Вопрос:
Почему это происходит? Почему диаграммы Вороного, рассчитанные этими двумя библиотеками (D3 и Scipy), различаются?
Дополнительное описание
Как это делается на стороне D3: на примере Криса Зеттера http://chriszetter.com/blog/2014/06/15/building-a-voronoi-map-with-d3-and-leaflet/ Я перевожу широту и долготу в пользовательскую проекцию, чтобы визуализировать ее на карте mapbox.
var voronoi = d3.geom.voronoi()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.clipExtent([[N_W.x , N_W.y],[S_E.x, S_E.y]])
Я создаю Voronoi на основе точек, которые видны в пределах границы карты + некоторые отступы (filteredPoints)
filteredPoints = points.filter(function(d) {
var latlng = new L.LatLng(d.latitude, d.longitude);
if (!drawLimit.contains(latlng)) { return false };
// this translates points from coordinates to pixels
var point = map.latLngToLayerPoint(latlng);
key = point.toString();
if (existing.has(key)) { return false };
existing.add(key);
d.x = point.x;
d.y = point.y;
return true;
});
voronoi(filteredPoints).forEach(function(d) { d.point.cell = d});
Как это делается на стороне Python: я использую scipy.spatial.Voronoi.
from scipy.spatial import Voronoi
def create_voronois():
points = numpy.array(points_list)
vor = Voronoi(points)
Где «points_list» — это список моих 8000 географических точек.
РЕДАКТИРОВАТЬ:
Скриншот из моей визуализации - черные рамки сделаны Voronois с помощью D3, белые сделаны scipy.spatial.Voronoi. Как мы видим, scipy ошибается. Кто-нибудь сравнивал эти 2 библиотеки раньше?
Код для запуска. Он печатает GeoJson с плохо рассчитанным Вороным.
import numpy
from scipy.spatial import Voronoi
from geojson import FeatureCollection, Feature, Polygon
points = [
[22.7433333333000, 53.4869444444000],
[23.2530555556000, 53.5683333333000],
[23.1066666667000, 53.7200000000000],
[22.8452777778000, 53.7758333333000],
[23.0952777778000, 53.4413888889000],
[23.4152777778000, 53.5233333333000],
[22.9175000000000, 53.5322222222000],
[22.7197222222000 ,53.7322222222000],
[22.9586111111000, 53.4594444444000],
[23.3425000000000, 53.6541666667000],
[23.0900000000000, 53.5777777778000],
[23.2283333333000, 53.4713888889000],
[23.3488888889000, 53.5072222222000],
[23.3647222222000 ,53.6447222222000]]
def create_voronois(points_list):
points = numpy.array(points_list)
vor = Voronoi(points)
point_voronoi_list = []
feature_list = []
for region in range(len(vor.regions) - 1):
vertice_list = []
for x in vor.regions[region]:
vertice = vor.vertices[x]
vertice = (vertice[1], vertice[0])
vertice_list.append(vertice)
polygon = Polygon([vertice_list])
feature = Feature(geometry=polygon, properties={})
feature_list.append(feature)
feature_collection = FeatureCollection(feature_list)
print feature_collection
create_voronois(points)