📜  使用Python-3 跟踪鸟类迁徙

📅  最后修改于: 2022-05-13 01:54:51.604000             🧑  作者: Mango

使用Python-3 跟踪鸟类迁徙

一个引人入胜的研究领域使用 GPS 来跟踪动物的运动。现在可以制造一个太阳能充电的小型 GPS 设备,因此您无需更换电池并使用它来跟踪鸟类的飞行模式。
本案例研究的数据来自 LifeWatch INBO 项目。作为该项目的一部分,已经发布了几个数据集。我们将使用一个小型数据集,其中包含三只名为 Eric、Nico 和 Sanne 的海鸥的迁移数据。官方数据集;使用的数据集——CSV”>csv 文件包含八列,包括纬度、经度、海拔和时间戳等变量。在这个案例研究中,我们将首先加载数据,可视化一些简单的飞行轨迹,跟踪飞行速度,了解白天等等。

目标:追踪三只海鸥的运动,即 Eric、Nico 和 Sanne
数据集: official_datasets;使用的数据集 - csv
依赖项: Matplotlib、Pandas、Numpy、Cartopy、Shapely
存储库(Github):源代码
(查看源代码文档的存储库。)
撰写:解释(.pdf)

我们将案例研究分为五个部分:
1. 可视化海鸥的经纬度数据。
2. 可视化海鸥速度的变化。
3. 想象海鸥在旅途中走相同距离所需的时间。
4. 可视化海鸥的日平均速度。
5. 海鸥旅程的制图视图。

PART (1/5):经纬度
在这一部分中,我们将可视化鸟类的位置。我们将分别沿 y 轴和 x 轴绘制纬度和经度,并可视化 csv 文件中存在的位置数据。

Python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
 
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
# storing the indices of the bird Eric
ix = birddata.bird_name == "Eric"
x,y = birddata.longitude[ix], birddata.latitude[ix]
plt.figure(figsize = (7,7))
plt.plot(x,y,"b.")
 
''' To look at all the birds trajectories,
    we plot each bird in the same plot '''
plt.figure(figsize = (7,7))
for bird_name in bird_names:
 
    # storing the indices of the bird Eric
    ix = birddata.bird_name == bird_name 
    x,y = birddata.longitude[ix], birddata.latitude[ix]
    plt.plot(x,y,".", label=bird_name)
plt.xlabel("Longitude")
plt.ylabel("Latitude")
plt.legend(loc="lower right")
plt.show()


Python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
# storing the indices of the bird Eric
ix = birddata.bird_name == "Eric"
speed = birddata.speed_2d[ix]
 
plt.figure(figsize = (8,4))
ind = np.isnan(speed)
plt.hist(speed[~ind], bins = np.linspace(0,30,20), normed=True)
plt.xlabel(" 2D speed (m/s) ")
plt.ylabel(" Frequency ")
plt.show()


Python
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import numpy as np
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
timestamps = []
for k in range(len(birddata)):
    timestamps.append(datetime.datetime.strptime(birddata.date_time.iloc[k][:-3], "%Y-%m-%d %H:%M:%S"))
 
birddata["timestamp"] = pd.Series(timestamps, index = birddata.index)
 
times = birddata.timestamp[birddata.bird_name == "Eric"]
elapsed_time = [time-times[0] for time in times]
 
plt.plot(np.array(elapsed_time)/datetime.timedelta(days=1))
plt.xlabel(" Observation ")
plt.ylabel(" Elapsed time (days) ")
plt.show()


Python
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import numpy as np
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
timestamps = []
for k in range(len(birddata)):
    timestamps.append(datetime.datetime.strptime(birddata.date_time.iloc[k][:-3], "%Y-%m-%d %H:%M:%S"))
birddata["timestamp"] = pd.Series(timestamps, index = birddata.index)
 
data =  birddata[birddata.bird_name == "Eric"]
times = data.timestamp
elapsed_time = [time-times[0] for time in times]
elapsed_days = np.array(elapsed_time)/datetime.timedelta(days=1)
 
next_day = 1
inds = []
daily_mean_speed = []
for (i,t) in enumerate(elapsed_days):
    if t < next_day:
        inds.append(i)
    else:
        daily_mean_speed.append(np.mean(data.speed_2d[inds]))
        next_day += 1
        inds = []
 
plt.figure(figsize = (8,6))
plt.plot(daily_mean_speed, "rs-")
plt.xlabel(" Day ")
plt.ylabel(" Mean Speed (m/s) ");
plt.show()


Python
import pandas as pd
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
# To move forward, we need to specify a
# specific projection that we're interested
# in using.
proj = ccrs.Mercator()
 
plt.figure(figsize=(10,10))
ax = plt.axes(projection=proj)
ax.set_extent((-25.0, 20.0, 52.0, 10.0))
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
for name in bird_names:
    ix = birddata['bird_name'] == name
    x,y = birddata.longitude[ix], birddata.latitude[ix]
    ax.plot(x,y,'.', transform=ccrs.Geodetic(), label=name)
plt.legend(loc="upper left")
plt.show()


plt.figure(figsize = (7,7))
plt.plot(x,y,"b.")

我们使用 matplotlib函数figure() 将图形的大小初始化为 7 x 7 并使用 plot()函数绘制它。函数plot() 中的参数即 x、y 和“b”。指定使用沿 x 轴的经度数据(对于 x),沿 y 的纬度(对于 y)和 b=blue,. = 可视化中的圆圈。

Output : You must have all the dependencies.Install them using "pip install dependency_name"

图_1_Eric's_trajectory
图_2_bird_trajectories

第 (2/5) 部分:2D 速度与频率
在案例研究的第二部分中,我们将可视化名为“Eric”的海鸥的 2D 速度与频率。

Python

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
# storing the indices of the bird Eric
ix = birddata.bird_name == "Eric"
speed = birddata.speed_2d[ix]
 
plt.figure(figsize = (8,4))
ind = np.isnan(speed)
plt.hist(speed[~ind], bins = np.linspace(0,30,20), normed=True)
plt.xlabel(" 2D speed (m/s) ")
plt.ylabel(" Frequency ")
plt.show()
ind = np.isnan(speed)
plt.hist(speed[~ind], bins = np.linspace(0,30,20), normed=True)
plt.xlabel(" 2D speed (m/s) ")
plt.ylabel(" Frequency ")
plt.show()

参数 speed[~ind] 表示我们将仅包括那些 ind != True 的条目,bins=np.linspace(0,30,20) 表示沿 x 轴的 bin 将从 0 到 30 变化,其中 20它们内的垃圾箱,线性间隔。最后,我们分别使用 xlabel() 和 ylabel() 函数绘制沿 x 轴以 m/s 为单位的 2D 速度和沿 y 轴绘制的频率,并使用 plt.show() 绘制数据。

输出 :

figure_3_speed

第 (3/5) 部分:时间和日期
第三部分与日期和时间相关联。我们将可视化 Eric 通过他的旅程覆盖恒定距离所需的时间(以天为单位)。如果他在相同的时间内跑过相同的距离,那么经过时间与观察曲线将是线性的。

Python

import pandas as pd
import matplotlib.pyplot as plt
import datetime
import numpy as np
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
timestamps = []
for k in range(len(birddata)):
    timestamps.append(datetime.datetime.strptime(birddata.date_time.iloc[k][:-3], "%Y-%m-%d %H:%M:%S"))
 
birddata["timestamp"] = pd.Series(timestamps, index = birddata.index)
 
times = birddata.timestamp[birddata.bird_name == "Eric"]
elapsed_time = [time-times[0] for time in times]
 
plt.plot(np.array(elapsed_time)/datetime.timedelta(days=1))
plt.xlabel(" Observation ")
plt.ylabel(" Elapsed time (days) ")
plt.show()
for k in range(len(birddata)):
    timestamps.append(datetime.datetime.strptime(birddata.date_time.iloc[k][:-3], "%Y-%m-%d %H:%M:%S"))

“>>>datetime.datetime.today()”,返回当前日期 (yy-mm-dd) 和时间 (h:m:s)。
“>>>date_str[:-3]”,切片/删除 UTC +00 协调时间戳。
“>>>datetime.datetime.strptime(date_str[:-3], “%Y-%m-%d %H:%M:%S”)” , date_str 中的时间戳字符串转换为 datetime 对象待处理。 “%Y-%m-%d %H:%M:%S”是年-月-日和时-分-秒格式。

输出:

图_4_time_stamp

PART (4/5):日平均速度
我们将在记录的飞行总天数中可视化名为“Eric”的海鸥的每日平均速度。

Python

import pandas as pd
import matplotlib.pyplot as plt
import datetime
import numpy as np
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
timestamps = []
for k in range(len(birddata)):
    timestamps.append(datetime.datetime.strptime(birddata.date_time.iloc[k][:-3], "%Y-%m-%d %H:%M:%S"))
birddata["timestamp"] = pd.Series(timestamps, index = birddata.index)
 
data =  birddata[birddata.bird_name == "Eric"]
times = data.timestamp
elapsed_time = [time-times[0] for time in times]
elapsed_days = np.array(elapsed_time)/datetime.timedelta(days=1)
 
next_day = 1
inds = []
daily_mean_speed = []
for (i,t) in enumerate(elapsed_days):
    if t < next_day:
        inds.append(i)
    else:
        daily_mean_speed.append(np.mean(data.speed_2d[inds]))
        next_day += 1
        inds = []
 
plt.figure(figsize = (8,6))
plt.plot(daily_mean_speed, "rs-")
plt.xlabel(" Day ")
plt.ylabel(" Mean Speed (m/s) ");
plt.show()
enumerate() - is one of the built-in Python functions. It returns an enumerated object. In our case, that object is a list of tuples (immutable lists), each containing a pair of count/index and value.

输出:

图_5_mean.avg.speed_perday

PART (5/5):制图视图
在最后一部分中,我们将在地图上追踪鸟类。

Python

import pandas as pd
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
 
birddata = pd.read_csv("bird_tracking.csv")
bird_names = pd.unique(birddata.bird_name)
 
# To move forward, we need to specify a
# specific projection that we're interested
# in using.
proj = ccrs.Mercator()
 
plt.figure(figsize=(10,10))
ax = plt.axes(projection=proj)
ax.set_extent((-25.0, 20.0, 52.0, 10.0))
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
for name in bird_names:
    ix = birddata['bird_name'] == name
    x,y = birddata.longitude[ix], birddata.latitude[ix]
    ax.plot(x,y,'.', transform=ccrs.Geodetic(), label=name)
plt.legend(loc="upper left")
plt.show()
import cartopy.crs as ccrs
import cartopy.feature as cfeature

这些模块对于映射数据很重要。

ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')

我们添加了地图的显着物理特征。

输出:

figure_6_bird_cartographic

资源 :
1. edX——HarvardX——使用Python进行研究
2. Python函数 doc_I
3. Python函数doc_II