Create Timeline Plot of Platforms in a STOQS Database

Walk through activities of the database and summarize platform time in water

Executing this Notebook requires a personal STOQS server. Follow the steps to build your own development system — this will take a few hours and depends on a good connection to the Internet. Once your server is up log into it (after a cd ~/Vagrants/stoqsvm) and activate your virtual environment with the usual commands:

vagrant ssh -- -X
cd /vagrant/dev/stoqsgit
source venv-stoqs/bin/activate

Connect to your Institution's STOQS database server using read-only credentials. (Note: firewalls typically limit unprivileged access to such resources.)

cd stoqs
ln -s mbari_campaigns.py campaigns.py
export DATABASE_URL=postgis://everyone:guest@kraken.shore.mbari.org:5433/stoqs

Launch Jupyter Notebook on your system with:

cd contrib/notebooks
../../manage.py shell_plus --notebook

navigate to this file and open it. You will then be able to execute the cells and experiment with this notebook.


For the CCE campaign add up the hours and collect in a dictionary all the platform start and end times using Matplotlib mdate format:

In [1]:
from collections import defaultdict
from datetime import timedelta
import matplotlib.dates as mdates

db = 'stoqs_cce2015'

plat_start_ends = defaultdict(list)
plat_depl_dur = {}
print('Platform Name     # Deployments   Hours')
print('-------------     -------------   -----')
for plat in Platform.objects.using(db).all():
    time_diff_sum = timedelta(0)
    for act in Activity.objects.using(db).filter(platform=plat):
        time_diff = act.enddate - act.startdate
        time_diff_sum += time_diff
        plat_start_ends[plat].append((mdates.date2num(act.startdate), 
                                      mdates.date2num(act.enddate)))

    plat_depl_dur[plat] = (len(plat_start_ends[plat]), 
                           time_diff_sum.total_seconds() / 3600)
    print(f'{plat.name:20s} {plat_depl_dur[plat][0]:10d} {plat_depl_dur[plat][1]:7.1f}')
Platform Name     # Deployments   Hours
-------------     -------------   -----
MS1                           2    77.5
MS2                           2    77.0
MS3                           2    77.0
MS5                           2    77.0
CCEBIN                        6   363.0
BED08                         9     0.4
BED11                         3     0.1
BED03                         5     0.4
BED06                         8     0.2
BED05                         5     0.2
BED04                         1     0.1
BED00                         1     1.9
BED10                         2     0.1
BED09                        15   161.8

Activity start and end date values may be incorrect in legacy databases. To correct them this script can be run by the database admininstrator to update them based on the actual InstantPoint timevalues:

db = 'stoqs_canon_april2017'
for act in Activity.objects.using(db):
    ip_qs = (InstantPoint.objects.using(db)
                .filter(activity=act)
                .aggregate(Max('timevalue'), Min('timevalue')))
    if ip_qs['timevalue__min'] and ip_qs['timevalue__max']:
        act.startdate = ip_qs['timevalue__min']
        act.enddate = ip_qs['timevalue__max']
        act.save(using=db)
    else:
        act.delete(using=db)
In [2]:
%matplotlib inline

import matplotlib.pyplot as plt
from matplotlib import pylab
from numpy import arange
import operator

pylab.rcParams['figure.figsize'] = (15, 9);
fig, ax = plt.subplots()
plat_labels = []

# Plot in order by platformtype name and platform name
xpos = max([dr[1] for dr in list(plat_start_ends.values())[0]])
for ypos, plat in enumerate(
                    sorted(plat_start_ends.keys(),
                           key=operator.attrgetter('platformtype.name', 'name'))):
    plat_labels.append(f'{plat.name} ({plat.platformtype.name})')    
    for bdate, edate in plat_start_ends[plat]:
        dd = edate - bdate
        if dd < 1:
            dd = 1
        ax.barh(ypos+0.5, dd, left=bdate, height=0.8, 
                align='center', color='#' + plat.color, alpha=1.0) 

ax.set_title(Campaign.objects.using(db).get(id=1).description)
ax.set_ylim(-0.5, len(plat_labels) + 0.5)
ax.set_yticks(arange(len(plat_labels)) + 0.5)
ax.set_yticklabels(plat_labels)
ax.grid(True)
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%B %Y'))
plt.gca().xaxis.set_major_locator(mdates.MonthLocator())
plt.gca().xaxis.set_minor_locator(mdates.DayLocator())
plt.gcf().autofmt_xdate()
plt.show()
In [ ]: