add support for multiple series by graph

This commit is contained in:
Frédéric Péters 2017-10-15 22:05:31 +02:00
parent 36d791ccad
commit afb98a9536
3 changed files with 71 additions and 30 deletions

View File

@ -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'))

View File

@ -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'}

View File

@ -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'))