diff --git a/eodb/events/management/commands/activity.py b/eodb/events/management/commands/activity.py index cd818fb..cba685a 100644 --- a/eodb/events/management/commands/activity.py +++ b/eodb/events/management/commands/activity.py @@ -2,6 +2,7 @@ import datetime import matplotlib import matplotlib.dates import matplotlib.pyplot as plt +import numpy as np from .common import GraphCommand @@ -22,35 +23,50 @@ class Command(GraphCommand): if options.get('committime'): datetime_var = 'commit_datetime' - events = {} - for commit in self.get_events(options): - commit_date = getattr(commit, datetime_var).date() - if options.get('groupby') == 'weeks': - graph_date = commit_date - datetime.timedelta(days=commit_date.weekday()) - elif options.get('groupby') == 'months': - graph_date = commit_date.replace(day=1) - elif options.get('groupby') == 'years': - graph_date = commit_date.replace(month=1, day=1) + total_events = {} + plots = [] + for i, (legend, serie) in enumerate(self.get_series(options)): + events = {} + for commit in serie: + commit_date = getattr(commit, datetime_var).date() + if options.get('groupby') == 'weeks': + graph_date = commit_date - datetime.timedelta(days=commit_date.weekday()) + elif options.get('groupby') == 'months': + graph_date = commit_date.replace(day=1) + elif options.get('groupby') == 'years': + graph_date = commit_date.replace(month=1, day=1) - date = matplotlib.dates.date2num(graph_date) + date = matplotlib.dates.date2num(graph_date) + if options.get('modulecount'): + if not date in events: + events[date] = {} + if not commit.module in events[date]: + events[date][commit.module] = 0 + events[date][commit.module] += 1 + else: + if not date in events: + events[date] = 0 + events[date] += 1 + + dates = sorted(events.keys()) if options.get('modulecount'): - if not date in events: - events[date] = {} - if not commit.module in events[date]: - events[date][commit.module] = 0 - events[date][commit.module] += 1 + values = [len([y for y in events[x].values() if y > options.get('modulecount')]) for x in dates] else: - if not date in events: - events[date] = 0 - events[date] += 1 + values = [events[x] for x in dates] - dates = sorted(events.keys()) - if options.get('modulecount'): - values = [len([y for y in events[x].values() if y > options.get('modulecount')]) for x in dates] - else: - values = [events[x] for x in dates] + bottoms = [total_events.get(x, 0) for x in dates] + plot = plt.bar(dates, values, width=20, bottom=bottoms) + plots.append((legend, plot)) + + for key, value in events.items(): + if not key in total_events: + total_events[key] = 0 + total_events[key] += value + + if i > 1: + plt.legend([plot[0] for legend, plot in plots], + [legend for legend, plot in plots]) - plt.bar(dates, values, width=20) plt.gca().xaxis.set_major_locator(matplotlib.dates.YearLocator()) plt.gca().xaxis.set_minor_locator(matplotlib.dates.MonthLocator()) plt.gca().xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m/%Y')) diff --git a/eodb/events/management/commands/common.py b/eodb/events/management/commands/common.py index 77b6ff0..f8e7a26 100644 --- a/eodb/events/management/commands/common.py +++ b/eodb/events/management/commands/common.py @@ -1,6 +1,6 @@ import matplotlib.pyplot as plt -from django.core.management.base import BaseCommand +from django.core.management.base import BaseCommand, CommandError from django.utils.dateparse import parse_date from eodb.events.models import Commit, Email @@ -18,6 +18,24 @@ class GraphCommand(BaseCommand): parser.add_argument('--notitle', action='store_true') parser.add_argument('--filename', metavar='FILENAME') + def get_series(self, options): + usernames = options['username'].split(',') if options.get('username') else [] + modules = options['module'].split(',') if options.get('module') else [] + + if len(usernames) > 1 and len(modules) > 1: + raise CommandError('only one dimension is allowed') + + if len(usernames) > 1: + for username in usernames: + options['username'] = username + yield (username, self.get_events(options)) + elif len(modules) > 1: + for module in modules: + options['module'] = module + yield (module, self.get_events(options)) + else: + yield (None, self.get_events(options)) + def get_events(self, options): filters = {'author_email__endswith': '@entrouvert.com'} diff --git a/eodb/events/management/commands/times.py b/eodb/events/management/commands/times.py index 88e4649..5662a33 100644 --- a/eodb/events/management/commands/times.py +++ b/eodb/events/management/commands/times.py @@ -17,12 +17,19 @@ class Command(GraphCommand): event_dates = [] event_times = [] - for commit in self.get_events(options): - graph_date = getattr(commit, datetime_var) - event_dates.append(matplotlib.dates.date2num(graph_date.date())) - event_times.append(graph_date.hour + graph_date.minute / 60. + graph_date.second / 3600) + plots = [] + for i, (legend, serie) in enumerate(self.get_series(options)): + for commit in serie: + graph_date = getattr(commit, datetime_var) + event_dates.append(matplotlib.dates.date2num(graph_date.date())) + event_times.append(graph_date.hour + graph_date.minute / 60. + graph_date.second / 3600) + plot = plt.scatter(event_dates, event_times, alpha=options.get('opacity')) + plots.append((legend, plot)) + + if i > 1: + plt.legend([plot[0] for legend, plot in plots], + [legend for legend, plot in plots]) - plt.scatter(event_dates, event_times, alpha=options.get('opacity')) plt.gca().xaxis.set_major_locator(matplotlib.dates.YearLocator()) plt.gca().xaxis.set_minor_locator(matplotlib.dates.MonthLocator()) plt.gca().xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m/%Y'))