From 9e00e24f81a4fefaa908b842a2a44cf56e3d5899 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Thu, 3 Oct 2013 00:33:57 +0200 Subject: [PATCH 1/5] Update PR plotter. --- doc/tools/plot_pr.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/tools/plot_pr.py b/doc/tools/plot_pr.py index 08f4fc0e..60f5de54 100644 --- a/doc/tools/plot_pr.py +++ b/doc/tools/plot_pr.py @@ -25,7 +25,9 @@ releases = OrderedDict([ ('0.3', u'2011-10-10 03:28:47 -0700'), ('0.4', u'2011-12-03 14:31:32 -0800'), ('0.5', u'2012-02-26 21:00:51 -0800'), - ('0.6', u'2012-06-24 21:37:05 -0700')]) + ('0.6', u'2012-06-24 21:37:05 -0700'), + ('0.7', u'2012-09-29 18:08:49 -0700'), + ('0.8', u'2013-03-04 20:46:09 +0100')]) month_duration = 24 @@ -106,7 +108,7 @@ this_month = datetime(year=now.year, month=now.month, day=1, bins = [this_month - relativedelta(months=i) \ for i in reversed(range(-1, month_duration))] bins = seconds_from_epoch(bins) -plt.hist(dates_f, bins=bins) +n, bins, _ = plt.hist(dates_f, bins=bins) ax = plt.gca() ax.xaxis.set_major_formatter(FuncFormatter(date_formatter)) @@ -124,10 +126,15 @@ for version, date in releases.items(): plt.title('Pull request activity').set_y(1.05) plt.xlabel('Date') -plt.ylabel('PRs created') +plt.ylabel('PRs per month') plt.legend(loc=2, title='Release') plt.subplots_adjust(top=0.875, bottom=0.225) +import numpy as np +ax2 = plt.twinx() +ax2.plot(bins[:-1], np.cumsum(n), 'black', linewidth=2) +ax2.set_ylabel('Total PRs') + plt.savefig('PRs.png') plt.show() From 5ff79a795df33a8ccac15ea3c5ce59a3f2970817 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Thu, 3 Oct 2013 06:38:10 +0200 Subject: [PATCH 2/5] Correctly plot cumulative sum. --- doc/tools/plot_pr.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/tools/plot_pr.py b/doc/tools/plot_pr.py index 60f5de54..96860e7f 100644 --- a/doc/tools/plot_pr.py +++ b/doc/tools/plot_pr.py @@ -131,8 +131,11 @@ plt.legend(loc=2, title='Release') plt.subplots_adjust(top=0.875, bottom=0.225) import numpy as np +cumulative = np.cumsum(n) +cumulative += len(dates) - cumulative[-1] + ax2 = plt.twinx() -ax2.plot(bins[:-1], np.cumsum(n), 'black', linewidth=2) +ax2.plot(bins[:-1], cumulative, 'black', linewidth=2) ax2.set_ylabel('Total PRs') plt.savefig('PRs.png') From 2ac11113286ba298af045ae82f3a68bdb6272555 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Fri, 11 Oct 2013 19:16:49 +0200 Subject: [PATCH 3/5] Add labels to releases. --- doc/tools/plot_pr.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/tools/plot_pr.py b/doc/tools/plot_pr.py index 96860e7f..aa9a6653 100644 --- a/doc/tools/plot_pr.py +++ b/doc/tools/plot_pr.py @@ -22,7 +22,7 @@ cache = '_pr_cache.txt' releases = OrderedDict([ #('0.1', u'2009-10-07 13:52:19 +0200'), #('0.2', u'2009-11-12 14:48:45 +0200'), - ('0.3', u'2011-10-10 03:28:47 -0700'), + #('0.3', u'2011-10-10 03:28:47 -0700'), ('0.4', u'2011-12-03 14:31:32 -0800'), ('0.5', u'2012-02-26 21:00:51 -0800'), ('0.6', u'2012-06-24 21:37:05 -0700'), @@ -123,11 +123,12 @@ for l in labels: for version, date in releases.items(): date = seconds_from_epoch([date])[0] plt.axvline(date, color='r', label=version) + plt.text(date, n.max() * 0.9, version, color='orange', rotation=90, + fontsize=16) plt.title('Pull request activity').set_y(1.05) plt.xlabel('Date') plt.ylabel('PRs per month') -plt.legend(loc=2, title='Release') plt.subplots_adjust(top=0.875, bottom=0.225) import numpy as np From 98dcc736e1e1a8509776fc4d1e740932c9813579 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sat, 12 Oct 2013 09:38:29 -0500 Subject: [PATCH 4/5] Plot cleanup and tweak to total PRs line. --- doc/tools/plot_pr.py | 89 ++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/doc/tools/plot_pr.py b/doc/tools/plot_pr.py index aa9a6653..ee5ca88d 100644 --- a/doc/tools/plot_pr.py +++ b/doc/tools/plot_pr.py @@ -1,14 +1,15 @@ -import urllib import json -import copy +import urllib +import dateutil.parser from collections import OrderedDict +from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta +import numpy as np import matplotlib.pyplot as plt from matplotlib.ticker import FuncFormatter +from matplotlib.transforms import blended_transform_factory -import dateutil.parser -from dateutil.relativedelta import relativedelta -from datetime import datetime, timedelta cache = '_pr_cache.txt' @@ -32,8 +33,6 @@ releases = OrderedDict([ month_duration = 24 -for r in releases: - releases[r] = dateutil.parser.parse(releases[r]) def fetch_PRs(user='scikit-image', repo='scikit-image', state='open'): params = {'state': state, @@ -48,12 +47,12 @@ def fetch_PRs(user='scikit-image', repo='scikit-image', state='open'): 'repo': repo, 'params': urllib.urlencode(params)} - fetch_status = 'Fetching page %(page)d (state=%(state)s)' % params + \ - ' from %(user)s/%(repo)s...' % config + fetch_status = ('Fetching page %(page)d (state=%(state)s)' % params + + ' from %(user)s/%(repo)s...' % config) print(fetch_status) f = urllib.urlopen( - 'https://api.github.com/repos/%(user)s/%(repo)s/pulls?%(params)s' \ + 'https://api.github.com/repos/%(user)s/%(repo)s/pulls?%(params)s' % config ) @@ -69,6 +68,31 @@ def fetch_PRs(user='scikit-image', repo='scikit-image', state='open'): return data + +def seconds_from_epoch(dates): + seconds = [(dt - epoch).total_seconds() for dt in dates] + return seconds + + +def get_month_bins(dates): + now = datetime.now(tz=dates[0].tzinfo) + this_month = datetime(year=now.year, month=now.month, day=1, + tzinfo=dates[0].tzinfo) + + bins = [this_month - relativedelta(months=i) + for i in reversed(range(-1, month_duration))] + return seconds_from_epoch(bins) + + +def date_formatter(value, _): + dt = epoch + timedelta(seconds=value) + return dt.strftime('%Y/%m') + + +for r in releases: + releases[r] = dateutil.parser.parse(releases[r]) + + try: PRs = json.loads(open(cache, 'r').read()) print('Loaded PRs from cache...') @@ -89,28 +113,13 @@ dates = [dateutil.parser.parse(pr['created_at']) for pr in PRs] epoch = datetime(2009, 1, 1, tzinfo=dates[0].tzinfo) -def seconds_from_epoch(dates): - seconds = [(dt - epoch).total_seconds() for dt in dates] - return seconds - dates_f = seconds_from_epoch(dates) +bins = get_month_bins(dates) -def date_formatter(value, _): - dt = epoch + timedelta(seconds=value) - return dt.strftime('%Y/%m') +fig, ax = plt.subplots(figsize=(7, 5)) -plt.figure(figsize=(7, 5)) +n, bins, _ = ax.hist(dates_f, bins=bins, color='blue', alpha=0.6) -now = datetime.now(tz=dates[0].tzinfo) -this_month = datetime(year=now.year, month=now.month, day=1, - tzinfo=dates[0].tzinfo) - -bins = [this_month - relativedelta(months=i) \ - for i in reversed(range(-1, month_duration))] -bins = seconds_from_epoch(bins) -n, bins, _ = plt.hist(dates_f, bins=bins) - -ax = plt.gca() ax.xaxis.set_major_formatter(FuncFormatter(date_formatter)) ax.set_xticks(bins[:-1]) @@ -119,26 +128,26 @@ for l in labels: l.set_rotation(40) l.set_size(10) +mixed_transform = blended_transform_factory(ax.transData, ax.transAxes) for version, date in releases.items(): date = seconds_from_epoch([date])[0] - plt.axvline(date, color='r', label=version) - plt.text(date, n.max() * 0.9, version, color='orange', rotation=90, - fontsize=16) + ax.axvline(date, color='black', linestyle=':', label=version) + ax.text(date, 1, version, color='r', va='bottom', ha='center', + transform=mixed_transform) -plt.title('Pull request activity').set_y(1.05) -plt.xlabel('Date') -plt.ylabel('PRs per month') -plt.subplots_adjust(top=0.875, bottom=0.225) +ax.set_title('Pull request activity').set_y(1.05) +ax.set_xlabel('Date') +ax.set_ylabel('PRs per month', color='blue') +fig.subplots_adjust(top=0.875, bottom=0.225) -import numpy as np cumulative = np.cumsum(n) cumulative += len(dates) - cumulative[-1] -ax2 = plt.twinx() -ax2.plot(bins[:-1], cumulative, 'black', linewidth=2) -ax2.set_ylabel('Total PRs') +ax2 = ax.twinx() +ax2.plot(bins[1:], cumulative, color='black', linewidth=2) +ax2.set_ylabel('Total PRs', color='black') -plt.savefig('PRs.png') +fig.savefig('PRs.png') plt.show() From e93e8651983ed6293c245ebdf83d003d56f798b4 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sat, 12 Oct 2013 10:17:55 -0500 Subject: [PATCH 5/5] Label dates every 3 months instead of every month --- doc/tools/plot_pr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/plot_pr.py b/doc/tools/plot_pr.py index ee5ca88d..5f9b4aa6 100644 --- a/doc/tools/plot_pr.py +++ b/doc/tools/plot_pr.py @@ -121,7 +121,7 @@ fig, ax = plt.subplots(figsize=(7, 5)) n, bins, _ = ax.hist(dates_f, bins=bins, color='blue', alpha=0.6) ax.xaxis.set_major_formatter(FuncFormatter(date_formatter)) -ax.set_xticks(bins[:-1]) +ax.set_xticks(bins[2:-1:3]) # Date label every 3 months. labels = ax.get_xticklabels() for l in labels: