sktracker.trajectories.Trajectories
is probably the most important class in sktracker
as it represents detected objects and links between them. Trajectories
is a subclass of pandas.DataFrame
which provides convenient methods.
A Trajectories
object consists of several single trajectory. Each row contains an object which has several features (columns) and two integer as index. The first integer is a time stamp t_stamp
and the second one is a label
. Objects from the same label
belong to the same trajectory.
Be aware that t_stamp
are time index and does not represent time in second or minute. Time position (in second or minute) can be stored as object's features in columns (with 't' for example).
All you need to create a Trajectories
object is a pandas.DataFrame
. Note that sktracker
makes an heavy use of pandas.DataFrame
. If you are not familiar with it, take a look at the wonderfull Pandas documentation.
In [1]:
%matplotlib inline
In [2]:
import pandas as pd
import numpy as np
trajs = pd.DataFrame(np.random.random((30, 3)), columns=['x', 'y', 'z'])
trajs['t_stamp'] = np.sort(np.random.choice(range(10), (len(trajs),)))
trajs['label'] = list(range(len(trajs)))
trajs['t'] = trajs['t_stamp'] * 60 # t are in seconds for example
trajs.set_index(['t_stamp', 'label'], inplace=True)
trajs.sort_index(inplace=True)
trajs.head()
Out[2]:
To create Trajectories
, dataframe need to have:
t_stamp
and label
While t_stamp
and label
are required. Columns can contain anything you want/need.
In [ ]:
from sktracker.trajectories import Trajectories
# Create a Trajectories instance
trajs = Trajectories(trajs)
In [4]:
import numpy as np
from sktracker import data
from sktracker.trajectories import Trajectories
trajs = data.with_gaps_df()
trajs = Trajectories(trajs)
trajs.head()
Out[4]:
In [5]:
trajs.show()
Out[5]:
You can change axis to display.
In [6]:
trajs.show(xaxis='t', yaxis='y')
Out[6]:
You can also add a legend.
In [7]:
trajs.show(legend=True)
Out[7]:
You can also build more complex figures.
In [8]:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(15, 3))
ax1 = plt.subplot2grid((1, 3), (0, 0))
ax2 = plt.subplot2grid((1, 3), (0, 1))
ax3 = plt.subplot2grid((1, 3), (0, 2))
trajs.show(xaxis='t', yaxis='x', ax=ax1)
trajs.show(xaxis='t', yaxis='y', ax=ax2)
trajs.show(xaxis='t', yaxis='z', ax=ax3)
Out[8]:
Trajectories.show()
is a nice way to quickly build visualizations. However sktracker.ui
module provides more complex functions and classes in order to visualize your trajectories/dataset. See here for more details.
In [9]:
import numpy as np
from sktracker import data
from sktracker.trajectories import Trajectories
trajs = data.with_gaps_df()
trajs = Trajectories(trajs)
trajs.head()
Out[9]:
In [10]:
trajs.t_stamps
Out[10]:
In [11]:
# Each label corresponds to one segment/trajectory
trajs.labels
Out[11]:
In [12]:
# Get dict if dataframe index of segments (sorted by labels)
trajs.segment_idxs[0]
Out[12]:
In [ ]:
# Iterator over segments
for label, segment in trajs.iter_segments:
print(label, end=' ')
In [14]:
# Get bounds (first and last spots/objects) of each segment
trajs.get_bounds()
Out[14]:
In [15]:
# Get a different colors for each segments
trajs.get_colors()
Out[15]:
Some other methods such as:
get_segments()
get_longest_segments()
get_shortest_segments()
get_t_stamps_correspondences()
See Trajectories
API for more informations.
In [16]:
import numpy as np
from sktracker import data
from sktracker.trajectories import Trajectories
trajs = data.with_gaps_df()
trajs = Trajectories(trajs)
trajs.head()
Out[16]:
Reverse trajectories according to a column (time column makes sense most of the time :-))
In [17]:
reversed_traj = trajs.reverse(time_column='t', inplace=False)
reversed_traj['t'].head()
Out[17]:
Merge two trajectories together taking care to not mix labels.
In [84]:
print("Original trajs labels:", trajs.labels)
merged_trajs = trajs.merge(trajs.copy())
print("Merged trajs new labels:", merged_trajs.labels)
Relabel trajectories from zero. Note that it will also sort labels order.
In [85]:
print("Original trajs labels:", merged_trajs.labels)
relabeled_trajs = merged_trajs.relabel_fromzero()
print("Relabeled trajs labels:", relabeled_trajs.labels)
time_interpolate()
can "fill" holes in your dataset. For example if you have trajs with a missing timepoint, this method will try to "guess" the value of the missing timepoint.
In [20]:
# t = 1 is missing here
missing_trajs = Trajectories(trajs[trajs['t'] != 1])
missing_trajs.head(10)
Out[20]:
The method return a new Trajectories
with interpolated value for missing timepoint. v_*
values are speeds and a_*
values are accelerations.
In [21]:
# t = 1 has been "guessed"
interpolated_trajs = missing_trajs.time_interpolate()
interpolated_trajs.head(10)
Out[21]:
See also:
relabel()
scale()
project()
: project each spots on a line specified by two spots.See Trajectories
API for more informations.
Remove a spot (can be a list of spots)
In [22]:
trajs.head()
Out[22]:
In [23]:
trajs.remove_spots((0, 2), inplace=False).head()
Out[23]:
Remove a segment/trajectory
In [24]:
trajs.labels
Out[24]:
In [25]:
trajs.remove_segments(3).labels
Out[25]:
Merge two segments
In [61]:
print("Size of segment #0 :", len(trajs.get_segments()[0]))
print("Size of segment #3 :", len(trajs.get_segments()[3]))
merged_trajs = trajs.merge_segments((0, 3), inplace=False)
print("Size of segment #0 (merged with #3):", len(merged_trajs.get_segments()[0]))
Cut a segment
In [77]:
print("Size of segment #4:", len(trajs.get_segments()[4]))
cut_trajs = trajs.cut_segments((13, 4), inplace=False)
print("Size of segment #4 :", len(cut_trajs.get_segments()[4]))
print("Size of segment #7 (new segment after cut) :", len(cut_trajs.get_segments()[7]))
Duplicate a segment
In [28]:
dupli_trajs = trajs.duplicate_segments(4)
# Check wether #4 and #7 (duplicated) are the same
np.all(dupli_trajs.get_segments()[4].values == dupli_trajs.get_segments()[7].values)
Out[28]:
Because hard coded trajectories modifications can take long time and be boring, we designed a smart GUI that allows all kind of local trajectory editions such as remove, duplicate, merge and so forth.
For more infos please go here.
In [2]:
from sktracker import data
from sktracker.trajectories import Trajectories
trajs = Trajectories(data.brownian_trajs_df())
Get the differences between each consecutive timepoints for a same trajectory (label).
In [30]:
trajs.get_diff().head(15)
Out[30]:
Get the instantaneous speeds between each consecutive timepoints for a same trajectory (label).
In [31]:
trajs.get_speeds().head(15)
Out[31]:
In [2]:
# Run this cell first.
%load_ext autoreload
%autoreload 2