source: osmose-frontend/errors_graph.py @ 1054d21

Last change on this file since 1054d21 was 1054d21, checked in by Frédéric Rodrigo <frodrigo@…>, 6 years ago

Switch to graph to matplotlib

  • Property mode set to 100644
File size: 5.5 KB
Line 
1#! /usr/bin/env python
2#-*- coding: utf-8 -*-
3
4###########################################################################
5##                                                                       ##
6## Copyrights Etienne Chové <chove@crans.org> 2009                       ##
7##                                                                       ##
8## This program is free software: you can redistribute it and/or modify  ##
9## it under the terms of the GNU General Public License as published by  ##
10## the Free Software Foundation, either version 3 of the License, or     ##
11## (at your option) any later version.                                   ##
12##                                                                       ##
13## This program is distributed in the hope that it will be useful,       ##
14## but WITHOUT ANY WARRANTY; without even the implied warranty of        ##
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         ##
16## GNU General Public License for more details.                          ##
17##                                                                       ##
18## You should have received a copy of the GNU General Public License     ##
19## along with this program.  If not, see <http://www.gnu.org/licenses/>. ##
20##                                                                       ##
21###########################################################################
22
23import time, sys, datetime, StringIO, os, tempfile
24os.environ['MPLCONFIGDIR'] = tempfile.mkdtemp()
25import matplotlib
26# Force matplotlib to not use any Xwindows backend.
27matplotlib.use('Agg')
28import pylab
29from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
30
31
32def get_data(db, options):
33    sql = """
34SELECT
35    date,
36    SUM(count)
37FROM (
38SELECT
39    date_trunc('day', dynpoi_stats.timestamp) AS date,
40    AVG(dynpoi_stats.count) AS count
41FROM
42    dynpoi_stats
43    %s
44WHERE 1=1
45    %s
46GROUP BY
47    dynpoi_stats.source,
48    dynpoi_stats.class,
49    date
50) AS t
51GROUP BY
52    date
53ORDER BY
54    date
55"""
56
57    join_item = ""
58    where_sql = ""
59
60    if len(options.items)>=1:
61        join_item += """
62    JOIN dynpoi_class ON
63        dynpoi_stats.source = dynpoi_class.source AND
64        dynpoi_stats.class = dynpoi_class.class AND
65        dynpoi_class.item in (%s)
66        """ % convIntsToStr(options.items)
67
68    if len(options.classes)>=1:
69        where_sql += "AND dynpoi_stats.class in (%s) " % convIntsToStr(options.classes)
70
71    if len(options.sources)>=1:
72        where_sql += "AND dynpoi_stats.source in (%s) " % convIntsToStr(options.sources)
73
74    if options.country:
75        join_item += """
76    JOIN dynpoi_source ON
77        dynpoi_stats.source = dynpoi_source.source AND
78        dynpoi_source.comment LIKE '%%-%s%%'
79        """ % options.country
80
81    sql = sql % (join_item, where_sql)
82
83    if len(sys.argv)>1:
84      print sql
85
86    result = []
87    db.execute(sql)
88    for r in db.fetchall():
89        result.append((r[0],r[1]))
90    return result
91
92
93def get_text(db, options):
94    if len(options.sources)==1 and len(options.classes)==1:
95        db.execute("SELECT title->'en' FROM dynpoi_class WHERE source=%s AND class=%s;", (options.sources[0], options.classes[0]))
96    elif len(options.items)==1 and len(options.classes)==1:
97        db.execute("SELECT title->'en' FROM dynpoi_class WHERE class=%s AND item=%s LIMIT 1;", (options.classes[0], options.items[0]))
98    elif len(options.items)==1:
99        db.execute("SELECT menu->'en' FROM dynpoi_item WHERE item=%s LIMIT 1;", (options.items[0],))
100    else:
101        return ""
102
103    res = db.fetchone()
104    if res:
105        return res[0]
106    else:
107        return ""
108
109
110def get_src(db, options):
111    if len(options.sources) != 1:
112        return "All"
113    else:
114        db.execute("SELECT comment FROM dynpoi_source WHERE source=%s;", (options.sources[0], ))
115        return db.fetchone()[0]
116
117
118def convIntsToStr(values):
119    """
120    Convertie une liste d'entier en chaine
121    """
122    return ", ".join([str(elt) for elt in values])
123
124
125def make_plt(db, options, format):
126    data = get_data(db, options)
127    text = get_text(db, options)
128    src = get_src(db, options)
129    return plot(data, text+' '+src, format)
130
131
132def plot(data, title, format):
133    months   = MonthLocator()  # every month
134    days     = MonthLocator()  # every days
135    monthsFmt = DateFormatter('%Y-%m')
136
137    dates = [q[0] for q in data]
138    opens = [q[1] for q in data]
139
140    fig = pylab.figure()
141    ax = fig.add_subplot(111)
142    ax.plot_date(dates, opens, '-', color='r')
143
144    ax.set_title(title)
145
146    # format the ticks
147    ax.xaxis.set_major_locator(months)
148    ax.xaxis.set_major_formatter(monthsFmt)
149    ax.xaxis.set_minor_locator(days)
150    ax.autoscale_view()
151
152    # format the coords message box
153    ax.fmt_ydata = lambda x: '$%1.2f'%x
154    ax.grid(True)
155
156    fig.autofmt_xdate()
157
158    buf = StringIO.StringIO()
159    pylab.savefig(buf, format = format)
160    return buf.getvalue()
161
162
163if __name__ == "__main__":
164    from optparse import OptionParser, SUPPRESS_HELP
165    start = time.clock()
166
167    parser = OptionParser()
168    parser.add_option("--source", dest="sources", type="int", action="append", default=[])
169    parser.add_option("--class", dest="classes", type="int", action="append", default=[])
170    parser.add_option("--item", dest="items", type="int", action="append", default=[])
171    parser.add_option("--country", dest="country", type="string", default=None)
172    (options, args) = parser.parse_args()
173
174    data = make_plt(None, options)
175    f = open("graph.png", "w")
176    f.write(data)
177    f.close()
178    end = time.clock()
179    print "graph.png generated in %ims"%((end-start)*1000)
180    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.