Commit f7dab14f authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Update graphs/citations controller and views to one plot per graph.

parent 2bcee882
""" Controllers for building graphs using pandas library
"""
from citations_tools import (PLOT_ALL,
PLOT_PER_DOMAIN,
PLOT_PER_PROJECT,
PLOT_PER_TEAM)
from citations_tools import (PLOT_CITATIONS_AVG,
PLOT_CITATIONS_HINDEX,
PLOT_CITATIONS_OVERVIEW,
PLOT_CITATIONS_TOTAL)
from gluon import current
from gluon.storage import Storage
from graph_tools import (FROM_TO,
......@@ -28,6 +28,7 @@ def citations():
"""
import pandas as pd
import matplotlib as mpl
from citations_tools import (estimator_versus_time,
get_acl,
......@@ -38,6 +39,14 @@ def citations():
from reporting_tools import repr_team_project
mplstyle()
mpl.rcParams['date.autoformatter.year'] = '%Y'
mpl.rcParams['date.autoformatter.month'] = '%b'
mpl.rcParams['date.autoformatter.day'] = '%d %b'
mpl.rcParams['date.autoformatter.hour'] = '%b %d %H'
mpl.rcParams['date.autoformatter.minute'] = '%H:%M'
mpl.rcParams['date.autoformatter.second'] = '%H:%M:%S'
pd.set_option("display.width", None)
pd.set_option("display.max_rows", 500)
......@@ -66,25 +75,9 @@ def citations():
#
acl = get_acl(db, selector)
if selector.graphs == T(PLOT_ALL):
cols = ["id_publication", "scan", "citations"]
idx = ["id_publication"]
fgroupby = False
elif selector.graphs == T(PLOT_PER_DOMAIN):
cols = ["id_publication", "scan", "citations", "domain"]
idx = ["id_publication", "domain"]
fgroupby = True
elif selector.graphs == T(PLOT_PER_TEAM):
cols = ["id_publication", "scan", "citations", "team"]
idx = ["id_publication", "team"]
fgroupby = True
elif selector.graphs == T(PLOT_PER_PROJECT):
cols = ["id_publication", "scan", "citations", "project"]
idx = ["id_publication", "project"]
fgroupby = True
cols = ["id_publication", "scan", "citations"]
idx = ["id_publication"]
fgroupby = False
df = (acl[cols].set_index(idx))
......@@ -106,51 +99,56 @@ def citations():
#
# histogram citations for the last scan
#
fig1 = histogram(df[last_scan], last_scan, legend)
if selector.graphs == T(PLOT_CITATIONS_OVERVIEW):
fig = histogram(df[last_scan], last_scan, legend)
# ........................................................................
#
# Sum of citations as a function of time
#
data = (df.groupby(level=1).sum().T if fgroupby else df.sum())
fig2 = estimator_versus_time(data,
last_scan,
legend,
delta=not fgroupby,
logy=fgroupby,
xtitle="$\sum$ citations")
elif selector.graphs == T(PLOT_CITATIONS_TOTAL):
data = (df.groupby(level=1).sum().T if fgroupby else df.sum())
fig = estimator_versus_time(data,
last_scan,
legend,
delta=not fgroupby,
logy=fgroupby,
xtitle="$\sum$ citations")
# ........................................................................
#
# Average citations per article as a function of time
#
data = (df.groupby(level=1).mean().T if fgroupby else df.mean())
fig3 = estimator_versus_time(data,
last_scan,
legend,
xtitle="mean citations / article")
elif selector.graphs == T(PLOT_CITATIONS_AVG):
data = (df.groupby(level=1).mean().T if fgroupby else df.mean())
fig = estimator_versus_time(data,
last_scan,
legend,
xtitle="mean citations / article")
# ........................................................................
#
# h-index as a function of time
#
data = \
(df.groupby(level=1).agg(h_index).T if fgroupby else df.apply(h_index))
elif selector.graphs == T(PLOT_CITATIONS_HINDEX):
data = (df.groupby(level=1).agg(h_index).T if fgroupby
else df.apply(h_index))
fig4 = estimator_versus_time(data,
last_scan,
legend,
xtitle="h-index")
fig = estimator_versus_time(data,
last_scan,
legend,
xtitle="h-index")
# ........................................................................
#
# rendering
#
dct = dict(fig1=fig1,
fig2=fig2,
fig3=fig3,
fig4=fig4,
subtitle=repr_team_project(db, selector))
title = f"{selector.graphs} {repr_team_project(db, selector)}"
fig.text(0.05, 0.93, title, fontsize=11)
response.view = f"graphs/index.{request.extension}"
dct = dict(fig=fig)
return dct
......
......@@ -70,6 +70,7 @@
'authors_roles': 'rôles des auteurs',
'Automaton': 'Automate',
'Available databases and tables': 'Available databases and tables',
'Average citations per article': 'Moyenne des citations par article',
'axes': 'axes',
'Axes': 'Axes',
'Axes granularity': 'Axes granularity',
......@@ -303,6 +304,7 @@
'groups': 'groupes',
'Guides': 'Guides',
'guides': 'guides',
'H-index': 'H-index',
'Harvest': 'Moissonner',
'Harvester': 'Moissonneur',
'Harvester already exists with the same automaton ': 'Un moissonneur existe déjà avec le même automate ',
......@@ -469,6 +471,7 @@
'OS': 'OS',
'ouvrage': 'ouvrage',
'OV': 'OV',
'Overview': 'Vue générale',
'Page generated in %s seconds': 'Page générée en %s secondes',
'pages': 'pages',
'Pages': 'Pages',
......@@ -694,6 +697,7 @@
'Submitted date is not valid': "La date de soumission n'est pas valide",
'Substitute': 'Substitution',
'substitution mechanism: {tablename.fieldname} or {foreigntablename.fieldname}': 'régle de substitution : {tablename.fieldname} or {foreigntablename.fieldname}',
'Sum of citations': 'Somme des citations',
'Sum of publications': 'Somme des publications',
'Summary per collections': 'Résumé par collection',
'Synonym': 'Synonym',
......
......@@ -10,10 +10,11 @@ from gluon import current
from matplotlib.figure import Figure
import matplotlib.ticker as ticker
PLOT_ALL = "all articles"
PLOT_PER_DOMAIN = "per domain"
PLOT_PER_TEAM = "per team"
PLOT_PER_PROJECT = "per project"
PLOT_CITATIONS_OVERVIEW = "Overview"
PLOT_CITATIONS_TOTAL = "Sum of citations"
PLOT_CITATIONS_AVG = "Average citations per article"
PLOT_CITATIONS_HINDEX = "H-index"
def estimator_versus_time(ts,
......
"""Definitions of the selector(s)
"""
from citations_tools import (PLOT_ALL,
PLOT_PER_DOMAIN,
PLOT_PER_PROJECT,
PLOT_PER_TEAM)
from citations_tools import (PLOT_CITATIONS_AVG,
PLOT_CITATIONS_HINDEX,
PLOT_CITATIONS_OVERVIEW,
PLOT_CITATIONS_TOTAL)
from gluon import current
from gluon.validators import (IS_IN_DB,
IS_LENGTH,
......@@ -297,7 +297,7 @@ class Selector(object):
pyDAL.Table
"""
plot_all = T(PLOT_ALL)
plot_overview = T(PLOT_CITATIONS_OVERVIEW)
table = virtdb.define_table(
"graph_citation_selector",
......@@ -306,19 +306,19 @@ class Selector(object):
Field("id_teams", "reference teams", label="Team"),
Field("id_projects", "reference projects", label="Project"),
Field("id_authors_roles", "reference authors_roles", label="Role"),
Field("graphs", "string", default=plot_all, label="Graph"),
Field("graphs", "string", default=plot_overview, label="Graph"),
Field("format", "string", default="html", label="Format"))
table.id_authors_roles.requires = IS_IN_DB(db, "authors_roles.role")
table.id_projects.requires = IS_IN_DB(db, "projects.project")
table.id_teams.requires = IS_IN_DB(db, "teams.team")
table.format.requires = IS_IN_SET(["html", "pdf"])
table.format.requires = IS_IN_SET(["html", "pdf", "png"])
table.graphs.requires = IS_IN_SET([plot_all,
T(PLOT_PER_DOMAIN),
T(PLOT_PER_TEAM),
T(PLOT_PER_PROJECT)])
table.graphs.requires = IS_IN_SET([plot_overview,
T(PLOT_CITATIONS_TOTAL),
T(PLOT_CITATIONS_AVG),
T(PLOT_CITATIONS_HINDEX)])
return table
......
......@@ -198,14 +198,10 @@ class SelectorUI(object):
#
mdf = FieldsModifier("graph_citation_selector")
mdf.configure_field("graphs", hidden=True)
mdf.configure_field("year_start", flex=1)
mdf.configure_field("year_end", flex=1)
mdf.merge_fields("year_start", "year_end", fieldLabel=T("Year"))
mdf.configure_field("id_graphs", selectFirst=True)
mdf.configure_field("id_authors_roles",
emptyText=tr_select,
xtype="xcomboboxuserreset")
......
{{
#--------------------------------------------------------------------------
#
# The python controller return matplotlib image(s)
#
#--------------------------------------------------------------------------
import base64
import io
import urllib.parse
buf1 = io.BytesIO()
fig1.savefig(buf1, format="svg")
data1 = base64.b64encode(buf1.getbuffer()).decode("ascii")
data1 = urllib.parse.quote(data1)
buf2 = io.BytesIO()
fig2.savefig(buf2, format="svg")
data2 = base64.b64encode(buf2.getbuffer()).decode("ascii")
data2 = urllib.parse.quote(data2)
buf3 = io.BytesIO()
fig3.savefig(buf3, format="svg")
data3 = base64.b64encode(buf3.getbuffer()).decode("ascii")
data3 = urllib.parse.quote(data3)
buf4 = io.BytesIO()
fig4.savefig(buf4, format="svg")
data4 = base64.b64encode(buf4.getbuffer()).decode("ascii")
data4 = urllib.parse.quote(data4)
}}
<h2 class="dbui-h2" style="margin-bottom: 0ex; font-variant: small-caps;">
1 General {{=subtitle}}
</h2>
<img src="data:image/svg+xml;base64,{{=data1}}" height=400>
<h2 class="dbui-h2" style="margin-bottom: 0ex; font-variant: small-caps;">
2 Evolution of estimators as function of time
</h2>
<h2 class="dbui-h2" style="margin-bottom: 0ex;margin-top: 1ex;">
2.1 Total number of citations
</h2>
<img src="data:image/svg+xml;base64,{{=data2}}" height=400>
<h2 class="dbui-h2" style="margin-bottom: 0ex;margin-top: 0ex;">
2.2 Average number of citations per article
</h2>
<img src="data:image/svg+xml;base64,{{=data3}}" height=400>
<h2 class="dbui-h2" style="margin-bottom: 0ex;margin-top: 0ex;">
2.3 h-index
</h2>
<img src="data:image/svg+xml;base64,{{=data4}}" height=400>
{{
from datetime import datetime
#
# the footer, processing time of the request
#
delta = (datetime.now()-request.now).total_seconds()
delta = T('Page generated in %s seconds') % round(delta, 2)
=P(delta, BR(), request.now.strftime("%d %b %Y %H:%M"), _class="dbui-p")
=BR()
}}
\ No newline at end of file
{{
#--------------------------------------------------------------------------
#
# The python controller return matplotlib image(s)
#
#--------------------------------------------------------------------------
import base64
import io
import tempfile
from matplotlib.backends.backend_pdf import PdfPages
# save image into a PDF file
with tempfile.NamedTemporaryFile() as fi:
pdf = PdfPages(fi.name)
pdf.savefig(fig1)
pdf.savefig(fig2)
pdf.savefig(fig3)
pdf.savefig(fig4)
pdf.close()
fi.seek(0)
spdf = fi.read()
pass
# return the PDF to user
response.headers['Content-Type']='application/pdf'
response.body = io.StringIO()
s64 = base64.b64encode(spdf).decode("utf-8")
response.write(s64, escape=False)
}}
\ No newline at end of file
......@@ -8,20 +8,18 @@
import io
import urllib.parse
from datetime import datetime
buf = io.BytesIO()
fig.savefig(buf, format="svg")
data = base64.b64encode(buf.getbuffer()).decode("ascii")
data = urllib.parse.quote(data)
}}
<img src="data:image/svg+xml;base64,{{=data}}" height=400></img>
{{
from datetime import datetime
=IMG(_src=f"data:image/svg+xml;base64,{data}", _height=400)
#
# the footer, processing time of the request
#
delta = (datetime.now()-request.now).total_seconds()
delta = T('Page generated in %s seconds') % round(delta, 2)
=P(delta, BR(), request.now.strftime("%d %b %Y %H:%M"), _class="dbui-p")
......
......@@ -3,7 +3,7 @@
import io
buf = io.BytesIO()
fig.savefig(buf, format="pdf)
fig.savefig(buf, format="pdf")
data = base64.b64encode(buf.getbuffer()).decode("ascii")
response.body = io.StringIO()
......
{{
import base64
import io
buf = io.BytesIO()
fig.savefig(buf, format="png", dpi=300)
data = base64.b64encode(buf.getbuffer()).decode("ascii")
response.body = io.StringIO()
response.headers['Content-Type']='application/png'
......
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