Changeset 1054d21 in osmose-frontend


Ignore:
Timestamp:
Oct 29, 2012 8:49:12 PM (5 years ago)
Author:
Frédéric Rodrigo <frodrigo@…>
Branches:
master
Children:
c537e71
Parents:
a471d0e
Message:

Switch to graph to matplotlib

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • errors.py

    r184d4e1 r1054d21  
    3131    return map(lambda x: int(x), filter(lambda x: x and x!='',s).split(',')) 
    3232 
    33 @route('/errors/graph.png') 
    34 def graph(db): 
     33@route('/errors/graph.<format:ext>') 
     34def graph(db, format='png'): 
    3535    class options: 
    3636        sources = request.params.get('sources', type=int_list, default=[]) 
     
    4242 
    4343    try: 
    44         data = errors_graph.make_plt(db, options) 
    45         response.content_type = "image/png" 
     44        data = errors_graph.make_plt(db, options, format) 
     45        response.content_type = {'png':'image/png', 'svg':'image/svg+xml', 'pdf':'application/pdf'}[format] 
    4646        return data 
    4747    except Exception, e: 
  • errors_graph.py

    r7f3b062 r1054d21  
    2121########################################################################### 
    2222 
    23 import time, sys, datetime, os, commands 
     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 
    2430 
    2531 
    2632def get_data(db, options): 
    27     sql =  "SELECT dynpoi_stats.source, dynpoi_stats.class, dynpoi_stats.timestamp, dynpoi_stats.count " 
    28     sql += "FROM dynpoi_stats %s " 
    29     sql += "WHERE 1=1 %s " 
    30     sql += "ORDER BY timestamp" 
     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""" 
    3156 
    3257    join_item = "" 
    3358    where_sql = "" 
    3459 
    35     if len(options.items)==1: 
    36        join_item += "JOIN dynpoi_class ON dynpoi_stats.source = dynpoi_class.source AND dynpoi_stats.class = dynpoi_class.class " 
    37        where_sql += "AND dynpoi_class.item=%d " % options.items[0] 
    38     elif len(options.items)>=1: 
    39        join_item += "JOIN dynpoi_class ON dynpoi_stats.source = dynpoi_class.source AND dynpoi_stats.class = dynpoi_class.class " 
    40        where_sql += "AND dynpoi_class.item in (%s) " % convIntsToStr(options.items) 
     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) 
    4167 
    42     if len(options.classes)==1: 
    43        where_sql += "AND dynpoi_stats.class=%d " % options.classes[0] 
    44     elif len(options.classes)>=1: 
    45        where_sql += "AND dynpoi_stats.class in (%s) " % convIntsToStr(options.classes) 
     68    if len(options.classes)>=1: 
     69        where_sql += "AND dynpoi_stats.class in (%s) " % convIntsToStr(options.classes) 
    4670 
    47     if len(options.sources)==1: 
    48        where_sql += "AND dynpoi_stats.source=%d " % options.sources[0] 
    49     elif len(options.sources)>=1: 
    50        where_sql += "AND dynpoi_stats.source in (%s) " % convIntsToStr(options.sources) 
     71    if len(options.sources)>=1: 
     72        where_sql += "AND dynpoi_stats.source in (%s) " % convIntsToStr(options.sources) 
    5173 
    5274    if options.country: 
    53        join_item += "JOIN dynpoi_source ON dynpoi_stats.source = dynpoi_source.source " 
    54        where_sql += "AND dynpoi_source.comment LIKE '%%-%s%%' " % 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 
    5580 
    5681    sql = sql % (join_item, where_sql) 
     
    5984      print sql 
    6085 
     86    result = [] 
    6187    db.execute(sql) 
     88    for r in db.fetchall(): 
     89        result.append((r[0],r[1])) 
     90    return result 
    6291 
    63     if len(options.sources)!=1: 
    64         delay = datetime.timedelta(days=1) 
    65     else: 
    66         delay = datetime.timedelta(seconds=1) 
    67  
    68     result = [] 
    69     last = {} 
    70     timestamp = 0 
    71     prev_timestamp = 0 
    72     for res in db.fetchall(): 
    73         timestamp = res['timestamp'] 
    74         if prev_timestamp == 0: 
    75             prev_timestamp = timestamp 
    76  
    77         last[(res["source"],res["class"])] = res['count'] 
    78         if (timestamp - prev_timestamp) > delay: 
    79             result.append((timestamp.strftime('%d/%m/%Y'), sum(last.itervalues()))) 
    80             prev_timestamp = timestamp 
    81  
    82     if last: 
    83         result.append((timestamp.strftime('%d/%m/%Y'), sum(last.itervalues()))) 
    84     return result 
    8592 
    8693def get_text(db, options): 
    8794    if len(options.sources)==1 and len(options.classes)==1: 
    8895        db.execute("SELECT title->'en' FROM dynpoi_class WHERE source=%s AND class=%s;", (options.sources[0], options.classes[0])) 
    89  
    9096    elif len(options.items)==1 and len(options.classes)==1: 
    9197        db.execute("SELECT title->'en' FROM dynpoi_class WHERE class=%s AND item=%s LIMIT 1;", (options.classes[0], options.items[0])) 
    92  
     98    elif len(options.items)==1: 
     99        db.execute("SELECT menu->'en' FROM dynpoi_item WHERE item=%s LIMIT 1;", (options.items[0],)) 
    93100    else: 
    94101        return "" 
     
    100107        return "" 
    101108 
     109 
    102110def get_src(db, options): 
    103111    if len(options.sources) != 1: 
     
    107115        return db.fetchone()[0] 
    108116 
    109 def make_plt(db, options): 
    110  
    111     data = get_data(db, options) 
    112     text = get_text(db, options) 
    113  
    114     if not data or len(data) < 2: 
    115          raise SystemError("no data available") 
    116  
    117     gnuplotFilename = "/tmp/data_%i.plt"%os.getpid() 
    118     dataFilename = "/tmp/data_%i.dat"%os.getpid() 
    119  
    120     f_plt = open(gnuplotFilename, 'w') 
    121     f_plt.write("set terminal png\n") 
    122     f_plt.write("set title \"Source : %s\"\n"%get_src(db, options)) 
    123 #    f_plt.write("set style data fsteps\n") 
    124     f_plt.write("set style data line\n") 
    125     f_plt.write("set timefmt \"%d/%m/%Y\"\n") 
    126     f_plt.write("set xdata time\n") 
    127     f_plt.write("set xrange [ \"%s\":\"%s\" ]\n"%(data[0][0], data[-1][0])) 
    128     f_plt.write("set format x \"%d/%m\\n%Y\"\n") 
    129     #f_plt.write("set xlabel \"Date\nTime\"\n") 
    130     f_plt.write("set yrange [ %d : %d ]\n"%(0,100*(max([x[1] for x in data])/100+2))) 
    131     #f_plt.write("set ylabel "Concentration\nmg/l"\n") 
    132     f_plt.write("set grid\n") 
    133     f_plt.write("set key left\n") 
    134     f_plt.write("plot '%s' using 1:2 t '%s'\n"%(dataFilename, text)) 
    135     f_plt.close() 
    136  
    137     f_dat = open(dataFilename, 'w') 
    138     for x in data: 
    139         f_dat.write("%s %d\n"%(x[0], x[1])) 
    140     f_dat.close() 
    141  
    142     s, o = commands.getstatusoutput("gnuplot "+gnuplotFilename) 
    143  
    144     if s: 
    145         raise SystemError("error in gnuplot generation") 
    146  
    147     os.remove(gnuplotFilename) 
    148     os.remove(dataFilename) 
    149  
    150     return o 
    151  
    152  
    153 def convStrToInts(string): 
    154     """ 
    155     Convertie une chaine en liste d'entier 
    156     """ 
    157     if not string: 
    158         return [] 
    159  
    160     string = string.replace(" ", "") 
    161     if string=="": 
    162         return [] 
    163  
    164     return [int(elt) for elt in string.split(",")] 
    165117 
    166118def convIntsToStr(values): 
     
    171123 
    172124 
     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 
    173163if __name__ == "__main__": 
    174164    from optparse import OptionParser, SUPPRESS_HELP 
     
    176166 
    177167    parser = OptionParser() 
    178  
    179168    parser.add_option("--source", dest="sources", type="int", action="append", default=[]) 
    180169    parser.add_option("--class", dest="classes", type="int", action="append", default=[]) 
  • osmose.py

    r968dae2 r1054d21  
    2323 
    2424def ext_filter(config): 
    25     regexp = r'html|json|xml|rss' 
     25    regexp = r'html|json|xml|rss|png|svg|pdf' 
    2626    def to_python(match): 
    27         return match if match in ('html', 'json', 'xml', 'rss') else 'html' 
     27        return match if match in ('html', 'json', 'xml', 'rss', 'png', 'svg', 'pdf') else 'html' 
    2828    def to_url(ext): 
    2929        return ext 
Note: See TracChangeset for help on using the changeset viewer.