Commit 1e17bee9 authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Add the function do_stackedchart.

parent ad305472
......@@ -7,6 +7,7 @@ import matplotlib
from datetime import datetime
from graph_tools import (do_linechart,
do_stackedchart,
mathplotlib_backend_server,
savefig)
......@@ -29,7 +30,7 @@ def index():
# stacked chart
if graph.stack_axis:
return "Not yet implemented..."
ax = do_stackedchart(db.publications, selector, graph)
# line char
else:
......
......@@ -81,13 +81,12 @@ def do_linechart(publications, selector):
# build the dataframe
# the index of the DataSerie is the time (month, ...)
data = []
time_cvt = get_time_converter(selector.year_start, selector.year_end)
for row in rows:
submitted = row.publications.submitted
if not rx_submitted.match(submitted):
continue
data.append([time_cvt(submitted), row[count]])
data.append([submitted[:7], row[count]])
df = DataFrame(data, columns=['time', 'count'])
df = df.set_index('time')
......@@ -96,6 +95,10 @@ def do_linechart(publications, selector):
if selector.cumulative:
df = df.cumsum()
# polish the label for the time axis (YYYY-MM)
cvt = get_time_converter(selector.year_start, selector.year_end)
df.index = [cvt(el) for el in df.index]
# instantiate the plot
ax = df.plot(legend=False)
......@@ -137,6 +140,89 @@ def do_query(publications, selector):
return query
def do_stackedchart(publications, selector, graph):
"""Build a stacked chart showing the number of publications as a function
of the time.
Args:
publications (gluon.dal.Table): the publications table.
selector (plugin_dbui.Selector): the selector with user criteria.
graph (gluon.dal.Row): the chart configuration.
Returns:
matplotlib.AxesSubplot: axes subplot
"""
db = publications._db
rx_submitted = re.compile(REG_SUBMITTED)
# the stack field
tablename = graph.stack_axis
fieldname = graph.stack_granularity
stackedfield = db[tablename][fieldname]
# query directive to count publications including
# foreign key constraints and user requirements
# related to team, project, authors roles and year
query = do_query(publications, selector)
# count the number of publications
# they are grouped per year, per month and per stacked value
group_by = [publications.submitted[:4],
publications.submitted[5:7],
stackedfield]
count = publications.id.count()
rows = db(query).select(publications.submitted,
stackedfield,
count,
groupby=group_by,
orderby=group_by)
# build the dataframe
data = []
for row in rows:
submitted = row.publications.submitted
if not rx_submitted.match(submitted):
continue
li = [submitted[:7], row[tablename][fieldname], row[count]]
data.append(li)
df = DataFrame(data, columns=['time', fieldname, 'count'])
# move to a DataSerie in which values are ordered by stacked value
# and by time
df = df.set_index([fieldname, 'time'])
# pivot to a table time versus stacked value in which each cell contains
# the number of publications
df = df.unstack(level=0)
# simplify the name of the column replace NaN by zero
df.columns = [el[1] for el in df.columns]
df = df.fillna(0)
# cumulative serie
if selector.cumulative:
df = df.cumsum()
# polish the label for the time axis (YYYY-MM)
cvt = get_time_converter(selector.year_start, selector.year_end)
df.index = [cvt(el) for el in df.index]
# instantiate the plot
ax = df.plot(colormap="Pastel1",
kind="area",
stacked=True)
do_labels(ax, "", "Number of publications / month")
do_tick(ax)
do_title(ax, db, selector)
return ax
def do_tick(ax):
"""Polish the tick mark
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment