Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
improve stats and charts module to add formats pie chart #15
Browse files Browse the repository at this point in the history
  • Loading branch information
Guts committed Sep 4, 2019
1 parent 3e6d42c commit 76c8216
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 83 deletions.
199 changes: 116 additions & 83 deletions isogeotoxlsx/utils/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
class Stats(object):
"""Doc for Isogeo."""

data_formats = []
md_empty_fields = defaultdict(list)
md_types_repartition = defaultdict(int)
md_tags_occurences = defaultdict(int)
Expand All @@ -67,7 +68,11 @@ def __init__(self, lang="fr"):

def attributes(self, ws_attributes: Worksheet, all_attributes: list):
"""Perform feature attributes analisis and write results into the
dedicatedWworksheet."""
wanted worksheet.
:param Worksheet ws_attributes: sheet of a Workbook to write analisis
:param list all_attributes: list of all feature attributes. It's a list of dicts.
"""
idx_fa = 1
# local arrays
fa_names = []
Expand Down Expand Up @@ -97,19 +102,86 @@ def attributes(self, ws_attributes: Worksheet, all_attributes: list):
ws["A{}".format(idx_fa)] = fa
ws["B{}".format(idx_fa)] = frq_names.get(fa)

# def fillfull(self):
# """Calculate fields fillfull level."""
# return "HOHOHOHO"
def source_formats(
self,
ws: Worksheet,
li_formats: list = None,
cell_start_table: str = "A20",
cell_start_chart: str = "D20",
):
"""Calculates metadata types repartition and add a Pie chart to the wanted sheet of Workbook.
:param Worksheet ws: sheet of a Workbook to write analisis
:param list li_formats: list of all formats labels. If not specified, the class attribute will be used instaed
:param str cell_start_table: cell of the sheet where to start writing table
:param str cell_start_chart: cell of the sheet where to start writing the chart
"""
if li_formats is None:
li_formats = self.data_formats

# build the data for pie chart
data = Counter(li_formats)

# get starting cells
min_cell_start_table = ws[cell_start_table]

# def week_work(self, search_results=list):
# """Return histogram data to represent cataloging activity per week."""
# for md in search_results:
# print(md.get("type", "No md, no type"))
# write headers
ws.cell(
row=min_cell_start_table.row,
column=min_cell_start_table.column,
value=self.tr.get("format"),
)
ws.cell(
row=min_cell_start_table.row,
column=min_cell_start_table.column + 1,
value=self.tr.get("occurrences"),
)

# write data into worksheet
row = min_cell_start_table.row
for frmt, count in data.items():
row += 1
ws.cell(row=row, column=min_cell_start_table.column, value=frmt.title())
ws.cell(row=row, column=min_cell_start_table.column + 1, value=count)

# Pie chart
pie = PieChart()
labels = Reference(
worksheet=ws,
min_col=min_cell_start_table.column,
min_row=min_cell_start_table.row + 1,
max_row=row,
)
data = Reference(
worksheet=ws,
min_col=min_cell_start_table.column + 1,
min_row=min_cell_start_table.row + 1,
max_row=row,
)
pie.add_data(data)
pie.set_categories(labels)
pie.title = self.tr.get("format") + "s"

# return "weekly baby!"
# Cut the first slice out of the pie
slice = DataPoint(idx=0, explosion=20)
pie.series[0].data_points = [slice]

def metadata_types(self, ws: Worksheet, types_counters: dict = None):
"""Return histogram data to represent cataloging activity per week."""
ws.add_chart(pie, cell_start_chart)

def metadata_types(
self,
ws: Worksheet,
types_counters: dict = None,
cell_start_table: str = "A1",
cell_start_chart: str = "D1",
):
"""Calculates metadata types repartition and add a Pie chart to the wanted sheet of Workbook.
:param Worksheet ws: sheet of a Workbook to write analisis
:param dict types_counters: dictionary of types/count. If not specified, the class attribute will be used instaed
:param str cell_start_table: cell of the sheet where to start writing table
:param str cell_start_chart: cell of the sheet where to start writing the chart
"""
if types_counters is None:
types_counters = self.md_types_repartition

Expand Down Expand Up @@ -138,89 +210,50 @@ def metadata_types(self, ws: Worksheet, types_counters: dict = None):
slice = DataPoint(idx=0, explosion=20)
pie.series[0].data_points = [slice]

ws.add_chart(pie, "D1")

# def keywords_bar(self, sheet, results, total=20):
# """Return histogram data to represent cataloging activity per week."""
# # tags parsing
# li_keywords = []
# li_inspire = []
# for md in results:
# li_keywords.extend(
# (
# i.get("text")
# for i in md.get("keywords", [])
# if i.get("_tag").startswith("keyword:is")
# )
# )
# li_inspire.extend(
# (
# i.get("text")
# for i in md.get("keywords", [])
# if i.get("_tag").startswith("keyword:in")
# )
# )
# keywords = Counter(li_keywords)
# inspire = Counter(li_inspire)

# data_k = [("Keyword", "Count")]
# for k, c in keywords.most_common(50):
# data_k.append((k, c))

# # write data into worksheet
# for row in data_k:
# sheet.append(row)

# bar = BarChart()
# bar.type = "bar"
# bar.style = 10
# bar.title = "Keywords by occurrences"
# bar.y_axis.title = "Occurences"
# bar.x_axis.title = "Keywords"

# data = Reference(sheet, min_col=2, min_row=1, max_row=50, max_col=3)
# cats = Reference(sheet, min_col=1, min_row=2, max_row=50)
# bar.add_data(data, titles_from_data=True)
# bar.set_categories(cats)
# bar.shape = 4

# return bar
ws.add_chart(pie, cell_start_chart)


# ############################################################################
# ###### Stand alone program ########
# ###################################
if __name__ == "__main__":
"""Standalone execution and tests."""
from os import environ
from isogeo_pysdk import Isogeo, __version__ as pysdk_version
from openpyxl import Workbook

# API access
share_id = environ.get("ISOGEO_API_DEV_ID")
share_token = environ.get("ISOGEO_API_DEV_SECRET")
isogeo = Isogeo(client_id=share_id, client_secret=share_token)
bearer = isogeo.connect()

# search
search = isogeo.search(bearer, whole_results=0, include=["keywords"])

# this module
app = Stats()
# workbook
wb = Workbook()
# ws = wb.active

# this app
app = Stats()
# app.week_work(search.get("results"))
# print(type(app.fillfull()))

# metadata types
ws_d = wb.create_sheet(title="Dashboard")
# # pie = app.type_pie(ws_d,
# search.get('total'))
# # ws_d.add_chart(pie, "D1")
# types of metadatas
ws_types = wb.create_sheet(title="Types")
app.md_types_repartition = {
"raster": 50,
"resource": 10,
"service": 40,
"vector": 100,
}

app.metadata_types(ws_types)

# formats of source datasets
ws_formats = wb.create_sheet(title="Formats")
app.data_formats = [
"PostGIS",
"WFS",
"PostGIS",
"WMS",
"Esri Shapefiles",
"Esri Shapefiles",
"Esri Shapefiles",
"Esri Shapefiles",
"Esri Shapefiles",
]

app.source_formats(
ws_formats,
# cell_start_table="A" # you can specify where to write table
)

bar = app.keywords_bar(ws_d, search.get("results"))
ws_d.add_chart(bar, "A10")
# write xlsx
wb.save("test.xlsx")
wb.save("test_stats_charts.xlsx")
91 changes: 91 additions & 0 deletions tests/test_stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# -*- coding: UTF-8 -*-
#! python3

"""
Usage from the repo root folder:
```python
# for whole test
python -m unittest tests.test_stats
# for specific
python -m unittest tests.test_stats.TestStats.test_translations_length
```
"""

# #############################################################################
# ########## Libraries #############
# ##################################

# Standard library
import unittest

# 3rd party
from openpyxl import Workbook

# target
from isogeotoxlsx.utils import Stats


# #############################################################################
# ########## Classes ###############
# ##################################


class TestStats(unittest.TestCase):
"""Test stats and charts module."""

def setUp(self):
"""Executed before each test."""
pass

def tearDown(self):
"""Executed after each test."""
pass

# -- TESTS ---------------------------------------------------
def test_translations_length(self):
"""Ensure that different translations have the same length"""
# this module
app = Stats()
# workbook
wb = Workbook()

# types of metadatas
ws_types = wb.create_sheet(title="Types")
app.md_types_repartition = {
"raster": 50,
"resource": 10,
"service": 40,
"vector": 100,
}

app.metadata_types(ws_types)

# formats of source datasets
ws_formats = wb.create_sheet(title="Formats")
app.data_formats = [
"PostGIS",
"WFS",
"PostGIS",
"WMS",
"Esri Shapefiles",
"Esri Shapefiles",
"Esri Shapefiles",
"Esri Shapefiles",
"Esri Shapefiles",
]

app.source_formats(
ws_formats,
# cell_start_table="A" # you can specify where to write table
)

# write xlsx
wb.save("test_stats_charts.xlsx")


# #############################################################################
# ##### Stand alone program ########
# ##################################
if __name__ == "__main__":
unittest.main()

0 comments on commit 76c8216

Please sign in to comment.