Я пытаюсь определить местоположение IP-адресов при подключении к одному из наших серверов с помощью Cartopy + Matplotlib. У меня есть CSV, содержащий метки времени, IP-адреса, лат и долготы, которые я перебираю и создаю новую карту для каждой прошедшей минуты.
Я использовал https://medium.com/udacity/creating-map-animations-with-python-97e24040f17b в качестве приблизительного ориентира.
Я могу генерировать отдельный кадр для каждой минуты, то есть несколько IP-адресов подключаются в течение этой минуты, а затем они отображаются. Они просто не заговорены в нужных местах ...
def make_ips_map(date, data, ax=None, resolution='low'):
if ax is None:
fig = plt.figure(figsize=(19.2, 10.8))
ax = plt.axes(projection=ccrs.Mercator(min_latitude=-65,
max_latitude=70))
ax.background_img(name='BM', resolution=resolution)
ax.set_extent([-170, 179, -65, 70], crs=ccrs.PlateCarree())
players = data[data['Timestamp'] < date]
for ip, ip_data in players.groupby('IPaddress'):
player_counts = ip_data.groupby(['long', 'lat']).count()
# Get lists for longs and lats of each player
index = list(player_counts.index)
longs = [each[0] for each in index]
lats = [each[1] for each in index]
sizes = player_counts['IPaddress'] * 10
ax.scatter(longs, lats, s=sizes,
color='blue', alpha=0.8,
transform=ccrs.PlateCarree())
...
df = pd.read_csv('test_lat_long.csv', names=['Timestamp', 'IPaddress', 'lat', 'long'])
df['Timestamp'] = pd.to_datetime(df['Timestamp'], errors='coerce')
start_date = datetime(2019, 3, 20, 18, 00, 00)
end_date = datetime(2019, 3, 20, 20, 38, 0)
fig = plt.figure(figsize=(19.2, 10.8))
ax = plt.axes(projection=ccrs.Mercator(min_latitude=-65, max_latitude=70))
# Generate an image for each minute between start_date and end_date
total_minutes = range((((end_date - start_date).seconds)//60)%60)
for ii, minutes in enumerate(total_minutes):
date = start_date + timedelta(minutes=minutes)
make_ips_map(date, df, ax=ax, resolution='low')
fig.tight_layout(pad=-0.5)
fig.savefig(f"frames/frame_{ii:04d}.png", dpi=100,
frameon=False, facecolor='black')
ax.clear()
Точки изображены изогнутой линией, начинающейся с 0,0, которая идет вверх и вправо.
Я подозреваю, что это как-то связано с несоответствием между проекцией (Mercator) и преобразованием (PlateCarree), которое использует ax.scatter, но не может это выяснить.