Skip to content

Commit c4fdd8c

Browse files
committed
[feat] add Plot class
1 parent 87d409c commit c4fdd8c

File tree

9 files changed

+154
-4
lines changed

9 files changed

+154
-4
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,16 @@
4242
fa.saved("output.xlsx", delimiter='\t', keys=["xHead", "yHead", "imageNumber", "id"], ids=None, indexes=None, format="excel") # Saved a list of features for all the frames and all the objects in an excel file.
4343
fa.saved("output.txt", delimiter='\t', keys=None, ids=None, indexes=None, format="excel") # Saved all thefeatures for all the frames and all the objects in an csv file.
4444
```
45-
Two format are supported: csv and excel.
45+
Two format are supported: csv and excel.
46+
47+
### Plot metrics
48+
```
49+
import fastanalysis as fa
50+
import matplotlib.pyplot as plt
51+
52+
tracking = fa.Load("tracking.txt")
53+
plotObj = fa.Plot(tracking)
54+
plotObj.velocityDistribution(ids=[0, 1], key="Body", pooled=False, subplots=True) # Plot velocity distribution for objects 1 and 0 in 2 subplots
55+
plotObj.velocityDistribution(ids=[0, 1], key="Body", pooled=False, subplots=False) # Plot velocity distribution for objects 1 and 0 in 1 plot
56+
plotObj.velocityDistribution(ids=[0, 1], key="Body", pooled=True) # Plot velocity distribution for objects 1 and 0 pooled in 1 distribution
57+
```

docs/source/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@
4444
# The theme to use for HTML and HTML Help pages. See the documentation for
4545
# a list of builtin themes.
4646
#
47-
html_theme = 'alabaster'
47+
html_theme = 'p-main_theme'
48+
import os
49+
from PSphinxTheme import utils
50+
51+
p, html_theme, needs_sphinx = utils.set_psphinxtheme(html_theme)
52+
html_theme_path = p
4853

4954
# Add any paths that contain custom static files (such as style sheets) here,
5055
# relative to this directory. They are copied after the builtin static files,

docs/source/fastanalysis.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ Submodules
77
fastanalysis module
88
-----------------------------
99

10-
.. automodule:: fastanalysis.load
10+
.. autoclass:: fastanalysis.load.Load
11+
:members:
12+
:undoc-members:
13+
:show-inheritance:
14+
15+
.. autoclass:: fastanalysis.plot.Plot
1116
:members:
1217
:undoc-members:
1318
:show-inheritance:

docs/source/index.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
Welcome to FastAnalysis's documentation!
77
========================================
88

9+
Introduction
10+
########################################
11+
FastAnalysis is a python module to load, export and analyse the output files of FastTrack software.
12+
13+
Installation
14+
########################################
15+
.. code-block::
16+
17+
git clone https://github.com/FastTrackOrg/FastAnalysis.git
18+
cd FastAnalysis
19+
pip install -U .
20+
921
.. toctree::
1022
:maxdepth: 2
1123
:caption: Contents:

fastanalysis/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from .load import Load
2+
from .plot import Plot

fastanalysis/plot.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import pandas
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
import seaborn as sns
5+
6+
class Plot:
7+
"""Base class for plotting"""
8+
9+
def __init__(self, loadObject):
10+
"""Constructor for the plot object.
11+
12+
:param loadObject: A Load object containing the data.
13+
:type index: Load
14+
"""
15+
self.data = loadObject.getDataframe()
16+
17+
def velocityDistribution(self, ids, indexes=None, key="Body", pooled=True, subplots=False):
18+
"""Plot the velocity distribution.
19+
20+
:param ids: Ids of objects.
21+
:type ids: list
22+
:param indexes: Sub part of data based on indexes [min:max[ to select. Default: all the indexes.
23+
:type ids: list
24+
:param key: Head, Body or Tail. default: Body
25+
:type key: str
26+
:param pooled: Concatenate the objects distributions.
27+
:type pooled: bool
28+
:param subplots: Plot the distribution on separate subplots.
29+
:type pooled: bool
30+
:return: Matplotlib axe and raw data.
31+
:rtype: (ax, list)
32+
"""
33+
if not indexes:
34+
indexes = (0, len(self.data.imageNumber.values))
35+
if pooled:
36+
subplots = False
37+
tmpData = self.data[(self.data.id == ids[0])&(self.data.imageNumber.isin(range(indexes[0], indexes[1])))]
38+
pooledData = (np.sqrt(np.diff(tmpData["x"+key].values)**2 + np.diff(tmpData["y"+key].values)**2)) / np.diff(tmpData.imageNumber.values)
39+
for i in ids[1::]:
40+
tmpData = self.data[(self.data.id == i)&(self.data.imageNumber.isin(range(indexes[0], indexes[1])))]
41+
pooledData = np.concatenate((pooledData, (np.sqrt(np.diff(tmpData["x"+key].values)**2 + np.diff(tmpData["y"+key].values)**2)) / np.diff(tmpData.imageNumber.values)))
42+
outputData = [pooledData]
43+
else:
44+
data = []
45+
for i in ids:
46+
tmpData = self.data[(self.data.id == i)&(self.data.imageNumber.isin(range(indexes[0], indexes[1])))]
47+
data.append((np.sqrt(np.diff(tmpData["x"+key].values)**2 + np.diff(tmpData["y"+key].values)**2)) / np.diff(tmpData.imageNumber.values))
48+
outputData = data
49+
50+
if subplots:
51+
fig, axs = plt.subplots(len(ids), 1, sharey=True)
52+
for i, j in enumerate(outputData):
53+
sns.distplot(j, ax=axs[i], label=ids[i])
54+
axs[i].legend()
55+
axs[-1].set_xlabel("Velocity")
56+
else:
57+
fig, axs = plt.subplots()
58+
for i, j in enumerate(outputData):
59+
sns.distplot(j, ax=axs, label=ids[i])
60+
axs.legend()
61+
axs.set_xlabel("Velocity")
62+
63+
return (axs, outputData)

fastanalysis/tests/test_plot.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
import pandas
3+
import numpy as np
4+
5+
import load
6+
import plot
7+
8+
9+
def test_velocity_dist_default_key():
10+
"""Test velocity distribution."""
11+
tracking = load.Load("tests/tracking.txt")
12+
plotObj = plot.Plot(tracking)
13+
velocityTest = plotObj.velocityDistribution(ids=[0, 1])
14+
refData = tracking.getObjects(0)
15+
a = (np.sqrt(np.diff(refData.xBody.values)**2 + np.diff(refData.yBody.values)**2)) / np.diff(refData.imageNumber.values)
16+
refData = tracking.getObjects(1)
17+
b = (np.sqrt(np.diff(refData.xBody.values)**2 + np.diff(refData.yBody.values)**2)) / np.diff(refData.imageNumber.values)
18+
pooled = np.concatenate((a, b))
19+
np.testing.assert_array_equal(pooled, velocityTest[1][0])
20+
21+
velocityTest = plotObj.velocityDistribution(ids=[0, 1], pooled=False)
22+
np.testing.assert_array_equal(a, velocityTest[1][0])
23+
np.testing.assert_array_equal(b, velocityTest[1][1])
24+
25+
refData = tracking.getObjectsInFrames(0, indexes=list(range(0, 100)))
26+
a = (np.sqrt(np.diff(refData.xBody.values)**2 + np.diff(refData.yBody.values)**2)) / np.diff(refData.imageNumber.values)
27+
velocityTest = plotObj.velocityDistribution(ids=[0], pooled=True, indexes=(0, 100))
28+
np.testing.assert_array_equal(a, velocityTest[1][0])
29+
30+
def test_velocity_dist_head():
31+
"""Test velocity distribution."""
32+
tracking = load.Load("tests/tracking.txt")
33+
plotObj = plot.Plot(tracking)
34+
velocityTest = plotObj.velocityDistribution(ids=[0, 1], key="Head")
35+
refData = tracking.getObjects(0)
36+
a = (np.sqrt(np.diff(refData.xHead.values)**2 + np.diff(refData.yHead.values)**2)) / np.diff(refData.imageNumber.values)
37+
refData = tracking.getObjects(1)
38+
b = (np.sqrt(np.diff(refData.xHead.values)**2 + np.diff(refData.yHead.values)**2)) / np.diff(refData.imageNumber.values)
39+
pooled = np.concatenate((a, b))
40+
np.testing.assert_array_equal(pooled, velocityTest[1][0])
41+
42+
velocityTest = plotObj.velocityDistribution(ids=[0, 1], pooled=False, key="Head")
43+
np.testing.assert_array_equal(a, velocityTest[1][0])
44+
np.testing.assert_array_equal(b, velocityTest[1][1])
45+
46+
refData = tracking.getObjectsInFrames(0, indexes=list(range(0, 100)))
47+
a = (np.sqrt(np.diff(refData.xHead.values)**2 + np.diff(refData.yHead.values)**2)) / np.diff(refData.imageNumber.values)
48+
velocityTest = plotObj.velocityDistribution(ids=[0], pooled=True, indexes=(0, 100), key="Head")
49+
np.testing.assert_array_equal(a, velocityTest[1][0])

requirements/conda.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
pandas
22
xlrd
33
openpyxl
4+
matplotlib
5+
seaborn
6+
numpy

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
description="A python library to open the tracking data from FastTrack the tracking software",
99
url="https://github.com/FastTrackOrg/FastAnalysis",
1010
packages=['fastanalysis'],
11-
install_requires=['pandas', 'numpy', 'matplotlib', 'xlrd', 'openpyxl'],
11+
install_requires=['pandas', 'numpy', 'matplotlib', 'xlrd', 'openpyxl', 'seaborn'],
1212
license='MIT',
1313
python_requires='>=3.6',
1414
zip_safe=False

0 commit comments

Comments
 (0)