Альтернативным вариантом является использование gmplot
.По сути, это оболочка Python для API JavaScript Карт Google, которая позволяет генерировать .html
файлы, которые отображают ваши графики на фоне карты.
Здесь я использую ее для построения случайного обхода спутника.фоновое изображение (этот тип карты не поддерживается по умолчанию, но довольно просто заставить его работать):
from gmplot import GoogleMapPlotter
from random import random
# We subclass this just to change the map type
class CustomGoogleMapPlotter(GoogleMapPlotter):
def __init__(self, center_lat, center_lng, zoom, apikey='',
map_type='satellite'):
super().__init__(center_lat, center_lng, zoom, apikey)
self.map_type = map_type
assert(self.map_type in ['roadmap', 'satellite', 'hybrid', 'terrain'])
def write_map(self, f):
f.write('\t\tvar centerlatlng = new google.maps.LatLng(%f, %f);\n' %
(self.center[0], self.center[1]))
f.write('\t\tvar myOptions = {\n')
f.write('\t\t\tzoom: %d,\n' % (self.zoom))
f.write('\t\t\tcenter: centerlatlng,\n')
# This is the only line we change
f.write('\t\t\tmapTypeId: \'{}\'\n'.format(self.map_type))
f.write('\t\t};\n')
f.write(
'\t\tvar map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);\n')
f.write('\n')
initial_zoom = 16
num_pts = 40
lats = [37.428]
lons = [-122.145]
for pt in range(num_pts):
lats.append(lats[-1] + (random() - 0.5)/100)
lons.append(lons[-1] + random()/100)
gmap = CustomGoogleMapPlotter(lats[0], lons[0], initial_zoom,
map_type='satellite')
gmap.plot(lats, lons, 'cornflowerblue', edge_width=10)
gmap.draw("mymap.html")
Вы можете открыть получившийся файл .html
в браузере и взаимодействовать так же, как с GoogleКарты.К сожалению, это означает, что вы не получите красивое графическое окно matplotlib
или что-либо еще, поэтому для создания файла изображения вам нужно либо сделать снимок экрана самостоятельно, либо взломать что-то, чтобы отобразить HTML для вас.
Еще одна вещь, которую нужно иметь в виду, это то, что вам, вероятно, понадобится ключ API Карт Google , в противном случае вы получите уродливую затемненную карту с водяным знаком, как я:
![Random walk map](https://i.stack.imgur.com/SB7P1.jpg)
Кроме того, поскольку вы хотите изобразить значения в виде цветов, вам нужно будет вручную преобразовать их в цветные строки и использовать метод gmap.scatter()
.Если вы заинтересованы в этом подходе, дайте мне знать, чтобы я мог попытаться придумать некоторый код для этого.
Обновление
Вот версия, которая поддерживает значения кодирования в виде цветов в разбросесюжет над спутниковыми снимками.Для достижения эффекта я использую карты цветов matplotlib
.Вы можете изменить цветовую карту, если хотите, см. Список опций здесь .Я также включил некоторый код для чтения ключа API из файла apikey.txt
, который позволяет каждому исследователю использовать свой собственный индивидуальный ключ без изменения кода (если такой файл не найден, по умолчанию не используется ключ API, как обычно).
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
from matplotlib.cm import ScalarMappable
from gmplot import GoogleMapPlotter
from random import random
class CustomGoogleMapPlotter(GoogleMapPlotter):
def __init__(self, center_lat, center_lng, zoom, apikey='',
map_type='satellite'):
if apikey == '':
try:
with open('apikey.txt', 'r') as apifile:
apikey = apifile.readline()
except FileNotFoundError:
pass
super().__init__(center_lat, center_lng, zoom, apikey)
self.map_type = map_type
assert(self.map_type in ['roadmap', 'satellite', 'hybrid', 'terrain'])
def write_map(self, f):
f.write('\t\tvar centerlatlng = new google.maps.LatLng(%f, %f);\n' %
(self.center[0], self.center[1]))
f.write('\t\tvar myOptions = {\n')
f.write('\t\t\tzoom: %d,\n' % (self.zoom))
f.write('\t\t\tcenter: centerlatlng,\n')
# Change this line to allow different map types
f.write('\t\t\tmapTypeId: \'{}\'\n'.format(self.map_type))
f.write('\t\t};\n')
f.write(
'\t\tvar map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);\n')
f.write('\n')
def color_scatter(self, lats, lngs, values=None, colormap='coolwarm',
size=None, marker=False, s=None, **kwargs):
def rgb2hex(rgb):
""" Convert RGBA or RGB to #RRGGBB """
rgb = list(rgb[0:3]) # remove alpha if present
rgb = [int(c * 255) for c in rgb]
hexcolor = '#%02x%02x%02x' % tuple(rgb)
return hexcolor
if values is None:
colors = [None for _ in lats]
else:
cmap = plt.get_cmap(colormap)
norm = Normalize(vmin=min(values), vmax=max(values))
scalar_map = ScalarMappable(norm=norm, cmap=cmap)
colors = [rgb2hex(scalar_map.to_rgba(value)) for value in values]
for lat, lon, c in zip(lats, lngs, colors):
self.scatter(lats=[lat], lngs=[lon], c=c, size=size, marker=marker,
s=s, **kwargs)
initial_zoom = 12
num_pts = 40
lats = [37.428]
lons = [-122.145]
values = [random() * 20]
for pt in range(num_pts):
lats.append(lats[-1] + (random() - 0.5)/100)
lons.append(lons[-1] + random()/100)
values.append(values[-1] + random())
gmap = CustomGoogleMapPlotter(lats[0], lons[0], initial_zoom,
map_type='satellite')
gmap.color_scatter(lats, lons, values, colormap='coolwarm')
gmap.draw("mymap.html")
В качестве примера я использую ряд монотонно увеличивающихся значений, которые красиво отображаются от оттенка синего до красного в цветовой карте coolwarm
:
![New map example with colors](https://i.stack.imgur.com/fjzDw.png)