3 # Create a figure with the NeuroDebian repo subscription stats from the apache logs
5 # zgrep "GET /lists/[a-z\.]\+ HTTP" neuro.debian.net-*access*gz | sed -e 's,.*gz:\([0-9\.]\+\).*\[\(.*\):.*:.*:.*/lists/\(.*\) HTTP.*,\2;\3;\1,' -e 's,/, ,g'
6 # either from a file or on stdin. Needs output filename as the only argument
10 from datetime import datetime
15 from matplotlib.dates import date2num
16 from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
17 from matplotlib.font_manager import FontProperties
18 from ConfigParser import SafeConfigParser
27 def make_figure(data):
28 fig = pl.figure(figsize=(14,3))
29 ax = fig.add_subplot(121)
30 plot_datehist(ax, data, 10, [code for code in cfg.options('release codenames') if cfg.get('release codenames', code).count('Debian')], title="Debian", ymax=11)
31 ax = fig.add_subplot(122)
32 plot_datehist(ax, data, 10, [code for code in cfg.options('release codenames') if cfg.get('release codenames', code).count('Ubuntu')], title="Ubuntu", ymax=11)
37 def plot_datehist(ax, data, bins, suites, title=None, ymax=None):
38 colors=['#ff0088', '#20435C', '#45902C', '#E08720']
43 for i, suite in enumerate(suites):
44 dates = data['date'][data['suite'] == suite]
46 history_length = dates.max() - dates.min()
47 # make approx monthly bins, smaller bins yield spiky curves
48 # needs new=True to work with oldish numpy
49 (hist, bin_edges) = np.histogram(dates, np.ceil(history_length/30.), new=True)
50 width = bin_edges[1] - bin_edges[0]
52 ax.plot(bin_edges[:-1]+(width/2), hist / width,
53 label=suite, color=colors[i%4], linestyle=linestyle[i//4], lw=2)
54 # transparent curve shading
55 ax.fill_between(bin_edges[:-1]+(width/2), 0, hist / width, alpha=0.2,
56 label=suite, color=colors[i%4])
57 # figure out axis limits to avoid whitespace in plots
58 x_max = bin_edges[-2] + width/2
59 x_min = bin_edges[0] + width/2
60 if global_x_max is None or x_max > global_x_max:
62 if global_x_min is None or x_min < global_x_min:
65 ax.set_xlim(global_x_min, global_x_max)
66 ax.set_ylabel('New subscriptions [1/day]')
73 # see: http://matplotlib.sourceforge.net/examples/api/date_demo.html
74 ax.xaxis.set_major_locator(YearLocator())
75 ax.xaxis.set_major_formatter(DateFormatter('\n\n%Y'))
76 ax.xaxis.set_minor_locator(MonthLocator())
77 ax.xaxis.set_minor_formatter(DateFormatter('%b'))
78 # format the coords message box
79 ax.format_xdata = DateFormatter('%Y-%m-%d')
81 # pukes with old matplotlib
82 #font = FontProperties()
84 pl.legend(loc='upper left', #prop=font,
85 labelspacing=.2, borderaxespad=.2,
86 handletextpad=.2, borderpad=.2)
89 if __name__ == '__main__':
90 if not len(sys.argv) > 1:
91 print 'Need output filename.'
93 cfg_path="/home/neurodebian/neurodebian.git/neurodebian.cfg"
94 cfg = SafeConfigParser()
97 for line in fileinput.FileInput(sys.argv[2:], openhook=fileinput.hook_compressed):
98 date, list_, ip = line.split(';')
100 suite, loc = list_.split('.')
104 date = datetime.strptime(date, "%d %b %Y")
105 data.append((ip.strip(), loc, suite, date2num(date)))
106 data = np.array(data, dtype=dt)
107 make_figure(data).savefig(sys.argv[1], bbox_inches='tight', dpi=60)