Parcourir la source

add pie charts to plot tool

Daniel Sheffield il y a 2 ans
Parent
commit
bdbf6ec68f
3 fichiers modifiés avec 48 ajouts et 13 suppressions
  1. 34 6
      app/activities/Plot.py
  2. 12 7
      app/db_utils.py
  3. 2 0
      app/price_view.py

+ 34 - 6
app/activities/Plot.py

@@ -1,7 +1,8 @@
 from app.db_utils import QueryManager
 from app.db_utils import QueryManager, display_mapper
+from datetime import date, datetime
 import seaborn as sns
-import seaborn as sns
+import pandas as pd
 import matplotlib.pyplot as plt
 import os
 import sys
@@ -65,15 +66,42 @@ if unit not in ALL_UNITS:
 
 print(f'Getting data for selection:\n  ')
 print(f'\n  '.join([f'{k.title()}: {v}' for k,v in fields.items()]))
-d = query_manager.get_historic_prices_data(unit, **dict((k,v) for k,v in fields.items() if k != 'unit'))
+d = pd.DataFrame(query_manager.get_historic_prices_data(unit, **dict((k,v) for k,v in fields.items() if k != 'unit')))
 if d.empty:
     sys.exit(1)
-sns.set_theme()
-d = d.pivot_table(index=['ts_raw',], columns=['product',], values=['$/unit'], aggfunc='mean')
-d.columns = d.columns.droplevel()
 print(d.info())
 print(d)
-ax = sns.lineplot(data=d, markers=True)
+sns.set_theme()
+now = datetime.now().date()
+d['ts_month'] = d['ts_raw'].apply(lambda x: date(x.date().year, x.date().month,1))
+p = d[d['ts_month'] == date(now.year,now.month,1) ].groupby(['ts_month','group',])['price', 'quantity'].sum()
+
+if not p.empty:
+  p = p.reset_index().set_index('group')
+  p['price'] = p['price'].apply(float)
+  p['quantity'] = p['quantity'].apply(float)
+  print(p.info())
+  print(p)
+  ax = p.plot.pie(y='quantity', figsize=(5, 5))
+  ax.get_legend().remove()
+  ax.set_xlabel('')
+  ax.set_ylabel('')
+  ax.set_title(f'Quantity ({unit})')
+  plt.show()
+  ax = p.plot.pie(y='price', figsize=(5, 5))
+  ax.get_legend().remove()
+  ax.set_xlabel('')
+  ax.set_ylabel('')
+  ax.set_title(f'Price ($)')
+  plt.show()
+
+p = d.pivot_table(index=['ts_raw',], columns=['product',], values=['$/unit'], aggfunc='mean')
+p.columns = p.columns.droplevel()
+print(p.info())
+print(p)
+ax = sns.lineplot(data=p, markers=True)
 ax.set_xlabel('Time')
 ax.set_ylabel(f'$ / {unit}')
 plt.show()
+
+

+ 12 - 7
app/db_utils.py

@@ -45,11 +45,14 @@ def cursor_as_dict(cur):
         #print(row)
         yield row
 
-def get_data(cursor, statement, display):
+def get_data(cursor, statement, display=None):
     cursor.execute(statement)
-    yield from  map(lambda x: dict([
-        (k, display(v, k)) for k,v in x.items()
-    ]), cursor_as_dict(cursor))
+    if display is not None:
+        yield from  map(lambda x: dict(
+            map(lambda k: (k, display(x[k], k)), x)
+        ), cursor_as_dict(cursor))
+    else:
+        yield from cursor_as_dict(cursor)
 
 def get_session_transactions(cursor, statement, display):
     #print(cur.mogrify(statement).decode("utf-8"))
@@ -130,10 +133,12 @@ class QueryManager(object):
         statement = get_historic_prices_statement(unit, sort=None, product=product, category=category, group=group, organic=organic, limit=limit)
         #print(self.cursor.mogrify(statement).decode('utf-8'))
         #input()
-        return pd.DataFrame(get_data(self.cursor, statement, self.display))
+        return get_data(self.cursor, statement)
 
     def get_historic_prices(self, rating_cb, sort, product, unit, organic=None, limit=None):
-        df = self.get_historic_prices_data(unit, sort=sort, product=product, organic=organic, limit=limit)
+        df = pd.DataFrame(map(lambda x: dict(
+            map(lambda k: (k, self.display(x[k], k)), x)
+        ), self.get_historic_prices_data(unit, sort=sort, product=product, organic=organic, limit=limit)))
         if df.empty:
             rating_cb(None, None, None)
             return ''
@@ -141,7 +146,7 @@ class QueryManager(object):
         rating_cb(_avg, _min, _max)
 
         return df.drop(labels=[
-            'id', 'avg', 'min', 'max', 'ts_raw', 'product', 'category', 'group'
+            'id', 'avg', 'min', 'max', 'price', 'quantity', 'ts_raw', 'product', 'category', 'group'
         ], axis=1).to_string(header=[
             'Date', 'Store', '$/unit', 'Org',
         ], justify='justify-all', max_colwidth=16, index=False)

+ 2 - 0
app/price_view.py

@@ -81,6 +81,8 @@ def get_historic_prices_statement(unit, sort=None, product=None, category=None,
         ('avg', SQL(f"""TRUNC(sum(price) OVER {partition} / sum(quantity * factor) OVER {partition}, 4)""")),
         ('min', SQL(f"""TRUNC(min(price / (quantity * factor)) OVER {partition}, 4)""")),
         ('max', SQL(f"""TRUNC(max(price / (quantity * factor)) OVER {partition}, 4)""")),
+        ('price', SQL(f"""TRUNC(price, 4)::numeric""")),
+        ('quantity', SQL(f"""TRUNC(quantity*factor, 4)::numeric""")),
         ('product', Identifier('products','name')),
         ('category', Identifier('categories', 'name')),
         ('group', Identifier('groups', 'name')),