Newer
Older
annotation-plotter / annotation-plotter.py
#!/usr/bin/env python
import warnings
warnings.filterwarnings("ignore")


import numpy as np
import matplotlib
matplotlib.use('PDF')
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import pylab
import math
import matplotlib.ticker as mticker
import argparse
import sys
import datetime


############CONFIG VARIABLES
###########CONFIG VARIABLES

COLOR_COLORARRAY = ['b' , 'g' , 'r', 'c' ,'m' , 'y' , 'k' , '#9AFE2E' , '#FF8000', '#DF01D7', '#A4A4A4', 'b' , 'g' , 'r', 'c' ,'m' , 'y' , 'k' , '#9AFE2E' , '#FF8000', '#DF01D7', '#A4A4A4']
GRAYSCALE_COLORARRAY = ['0.1','0.3','0.5','0.7','0.9','0.2','0.4','0.6','0.8','0.1','0.3','0.5','0.7','0.9','0.2','0.4','0.6','0.8'] ##GRAYSCALE
GRAPH_LENGHT = 180  ### The lenght of one graph in sec
GRAPH_PER_PAGE = 3
PAGE_SUPTITLE = "Interaktionen"
OUTPUT_FILENAME = "interactions_graph"


##########COMMAND LINE ARGUMENTS HANDLING

parser = argparse.ArgumentParser(prog=sys.argv[0], usage='%(prog)s [options]')
parser.add_argument('-f', '--filename', required=True, help="The input txt file" )
parser.add_argument('-o', '--outputfilename', required=False, default = OUTPUT_FILENAME, help = "the output filename without extension" )
parser.add_argument('-g', '--grayscale', required=False, action="store_true",  default = False, help = "grayscale bars on the charts for printing" )
parser.add_argument('-t', '--title', required=False, default = PAGE_SUPTITLE, help = "The prefix of the title of the graphs" )
parser.add_argument('-l', '--lenght', required=False, default = GRAPH_LENGHT, help = "The lenght of the graphs in sec, default is 180 sec")
args = parser.parse_args()


if args.grayscale:
    COLORARRAY = GRAYSCALE_COLORARRAY
else:
    COLORARRAY = COLOR_COLORARRAY
    
#Converts str into float
conv=lambda s:float(s)

#Use numpy to read the data in. 
data=np.genfromtxt(args.filename,converters={1: conv,2: conv, 3: conv}, names=['caption','start','stop','duration'], dtype=None)
cap,start,stop,  duration=data['caption'], data['start'], data['stop'], data['duration']
print type(data)
print type(data[0]['caption'])
#Get unique captions
captions = np.unique(cap)
counter = captions.size-1
print ("Please give the needed sequence of the captions on the y axises (from the bottom) as a space delimited list of numbers")
print ("To keep this sequence, just press enter")
for i in reversed(captions):
    print "%d -- %s" % (counter, i)
    counter = counter -1
print "Sequence:",
sequence = sys.stdin.readline()
print (len(sequence))

ycaptions = ['']

if len(sequence) > 1:
    
    seqlist = sequence.split()
    print seqlist[0]
    print type(sequence)
    ar = np.array(seqlist, dtype='i')
    if ar.size != captions.size:
        print ("incorrect number of elements")
        exit(1)
    for i in range(0, captions.size):
        ycaptions.append(captions[ar[i]])

else:
    for i in range (0, captions.size):
         ycaptions.append(captions[i])
    print "original order kept"
print "the new sequence of the captions on the y axis:"

counter = captions.size
for element in reversed(ycaptions):
   # print element
    print "%d -- %s" % (counter, element)
    counter = counter -1



##Generating and array for the indexes on the y axis:
tickindexes  = np.arange(0,captions.size+1,+1)

NumberOfInteractions = captions.size

pdfdoc = PdfPages(args.outputfilename + '.pdf')
graph_counter = 0

NumOfGraphs = int(math.ceil (max(stop)/float(args.lenght)))
NumOfPages = int(math.ceil(NumOfGraphs/GRAPH_PER_PAGE))

formatter = mticker.FuncFormatter(lambda x, y: '%02d:%02d' % divmod(x, 60))
locator = mticker.LinearLocator(9)



print "Will create %d graphs on %d pages" % ( NumOfGraphs, NumOfPages )





for i in range(0, NumOfPages):
   fig = plt.figure(figsize=(11,7))
   fig.suptitle(args.title)
   subplots = []
   for j in range (0, GRAPH_PER_PAGE):
   
    
       graph_counter = graph_counter +1

       print "Creating graph #%d" %(graph_counter)

       subplots.append (fig.add_subplot(GRAPH_PER_PAGE,1,j+1))
       Loc   = mticker.MultipleLocator(20)
       subplots[j].xaxis.set_major_locator(Loc)
       
       if (graph_counter == NumOfGraphs):
           subplots[j].set_xlim(xmin=(graph_counter-1)*float(args.lenght) ,xmax=max(stop))
           box = subplots[j].get_position()
           lenght_orig = box.x1
           lenght_sec = max(stop)-(graph_counter-1)*float(args.lenght)           
           print lenght_sec
           print args.lenght
           print lenght_sec / args.lenght
           print box.x1
           box.x1 = lenght_orig * (lenght_sec / args.lenght) + 0.08
           print box.x1
           subplots[j].set_position(box)
           print subplots[j].get_position()
       else:
           subplots[j].set_xlim(xmin=(graph_counter-1)*float(args.lenght) ,xmax=graph_counter*(float(args.lenght)))
       

       subplots[j].set_ylim(0, NumberOfInteractions+1)
       subplots[j].set_yticks(tickindexes)
       subplots[j].set_yticklabels(ycaptions)
       subplots[j].set_autoscaley_on(False)
       subplots[j].set_autoscalex_on(False)


       if (j ==  GRAPH_PER_PAGE-1):
           subplots[j].set_xlabel('time (mm:ss)')
       for line in data:
           caption_index = ycaptions.index(line['caption'])
           subplots[j].bar(line['start'], 
                           1,
                           line['duration'],
                           bottom=caption_index-0.5,
                           color = COLORARRAY[caption_index-1])
       subplots[j].xaxis.set_major_formatter(formatter)


   fig.savefig(pdfdoc ,format= 'pdf', orientation = 'landscape')


pdfdoc.close()

print "Creating long image..."

reload( matplotlib)
matplotlib.use('Agg')
reload (plt)

plt.switch_backend('Agg')  

figpic = plt.figure(figsize=(max(stop)/20 ,4))
figpic.suptitle(args.title)

majorLocator   = mticker.MultipleLocator(60)
minorLocator   = mticker.MultipleLocator(5)



figsubplot = figpic.add_subplot(111)
figsubplot.set_xlim(0,max(stop))
figsubplot.set_ylim(0, NumberOfInteractions+1)
figsubplot.set_yticks(tickindexes)
figsubplot.set_yticklabels(ycaptions)
figsubplot.set_autoscaley_on(False)
figsubplot.set_autoscalex_on(False)

figsubplot.xaxis.set_major_locator(majorLocator)

##  'caption', 'count', 'lenght'
statistic = []
for item in ycaptions:
  statistic.append ({'caption': item, 'count':0, 'lenght':0, 'percentage_count':0, 'percentage_time':0 })

for line in data:
           
           caption_index = ycaptions.index(line['caption'])
           statistic[caption_index]['count'] = statistic[caption_index]['count']+1
           statistic[caption_index]['lenght'] = statistic[caption_index]['lenght']+line['duration']

           figsubplot.bar(line['start'],
                           1,
                           line['duration'],
                           bottom=caption_index-0.5,
                           color = COLORARRAY[caption_index-1])
figsubplot.xaxis.set_major_formatter(formatter)
figpic.savefig(args.outputfilename + '.png', bbox_inches='tight')


f = open(args.outputfilename+'_statistics.txt','w')

print "total number of interactions:%d " % len(data)
f.write ("total number of interactions:%d\n " % len(data))
print "total lenght of video: %d" % max(stop)
f.write ("total lenght of video: %d\n" % max(stop))
#{'count': 2, 'caption': 'TN-andere', 'lenght': '0:00:23.219000', 'percentage_time': '1.11%', 'percentage_count': '2.67%'}
f.write ("Interaction\tTotal count\tCount percentage\tTotal length\tTime percentage\n")

for interaction_stat in statistic:
    percentage = (1.0 * interaction_stat['count'] / len(data)) * 100 
    interaction_stat['percentage_count'] = str("%.2f" % percentage)+'%'
    percentage = (1.0 * interaction_stat['lenght'] /max(stop) ) * 100 
    interaction_stat['percentage_time'] = str("%.2f" % percentage)+'%'
    interaction_stat['lenght'] = str(int(interaction_stat['lenght'] / 60)) + ':'+ str(int(interaction_stat['lenght'] % 60))
    if interaction_stat['caption']:
        f.write("%-10s\t%s\t\t\t%s\t\t%s\t\t%s\n" %
                (interaction_stat['caption'],
                interaction_stat['count'],
                interaction_stat['percentage_count'],
                interaction_stat['lenght'],
                interaction_stat['percentage_time']))
        print interaction_stat
print
f.close()

print "Ready! Graph outfiles are: %s and %s" % (args.outputfilename+'.pdf', args.outputfilename+'.png')
print "Statistics outfile is: %s" % (args.outputfilename+'_statistics.txt')