Предположим, что я ехал по заданному маршруту с 3g модемом и GPS на своем ноутбуке, в то время как мой компьютер дома записывает задержку пинга. Я связал пинг с широтой / долготой GPS, и теперь я хотел бы визуализировать эти данные.
У меня есть около 80 000 точек данных в день, и я хотел бы показать стоимость за несколько месяцев. Меня особенно интересует отображение областей, в которых время пинга постоянно истекает (т. Е. Пинг == 1000).
Точечный график
Моя первая попытка была с точечной диаграммой, с одной точкой на ввод данных. Я увеличил размер точки в 5 раз, если это был тайм-аут, поэтому было очевидно, где находятся эти области. Я также снизил альфа до 0,1, чтобы грубо увидеть наложенные точки.
# Colour
c = pings
# Size
s = [2 if ping < 1000 else 10 for ping in pings]
# Scatter plot
plt.scatter(longs, lats, s=s, marker='o', c=c, cmap=cm.jet, edgecolors='none', alpha=0.1)
Очевидная проблема с этим состоит в том, что он отображает один маркер для каждой точки данных, что является очень плохим способом отображения больших объемов данных. Если я дважды проезжал одну и ту же область, данные первого прохода просто отображаются поверх второго прохода.
Интерполяция по четной сетке
Затем я попытался использовать numpy и scipy для интерполяции по четной сетке.
# Convert python list to np arrays
x = np.array(longs, dtype=float)
y = np.array(lats, dtype=float)
z = np.array(pings, dtype=float)
# Make even grid (200 rows/cols)
xi = np.linspace(min(longs), max(longs), 200)
yi = np.linspace(min(lats), max(lats), 200)
# Interpolate data points to grid
zi = griddata((x, y), z, (xi[None,:], yi[:,None]), method='linear', fill_value=0)
# Plot contour map
plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k')
plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet)
С этот пример
Это выглядит интересно (много цветов и форм), но оно экстраполирует слишком далеко вокруг областей, которые я не исследовал. Вы не можете видеть маршруты, которые я прошел, только красные / синие пятна.
Если я проехал большую кривую, он будет интерполироваться для области между (см. Ниже):
интерполировать по неровной сетке
Затем я попытался использовать meshgrid (xi, yi = np.meshgrid(lats, longs)
) вместо фиксированной сетки, но мне сказали, что мой массив слишком большой.
Есть ли простой способ создать сетку из моих точек?
Мои требования:
- Обработка больших наборов данных (80 000 x 60 = ~ 5 м точек)
- Отображение дублированных данных для каждой точки путем усреднения (я полагаю, что интерполяция сделает это) или путем принятия минимального значения для каждой точки.
- Не экстраполировать слишком далеко от точек данных
Я доволен точечной диаграммой (вверху), но мне нужен какой-то способ усреднения данных перед их отображением.
(извинения за изворотливые рисунки MSPaint, я не могу загрузить фактические данные)
Решение:
# Get sum
hsum, long_range, lat_range = np.histogram2d(longs, lats, bins=(res_long,res_lat), range=((a,b),(c,d)), weights=pings)
# Get count
hcount, ignore1, ignore2 = np.histogram2d(longs, lats, bins=(res_long,res_lat), range=((a,b),(c,d)))
# Get average
h = hsum/hcount
x, y = np.where(h)
average = h[x, y]
# Make scatter plot
scatterplot = ax.scatter(long_range[x], lat_range[y], s=3, c=average, linewidths=0, cmap="jet", vmin=0, vmax=1000)