Source code for pyexplainer.pyexplainer_explainer

import json
import string
import os
from sklearn.utils import check_random_state


[docs]def data_validation(data): """Validate the if the given data format is a list of dictionary. Parameters ---------- param1 : :obj:`Any` Data to be validated. Returns ------- :obj:`bool` True: The data is a list of dictionary.\n False: The data is not a list of dictionary. Examples -------- >>> from pypkgs import pypkgs >>> a = pd.Categorical(["character", "hits", "your", "eyeballs"]) >>> b = pd.Categorical(["but", "integer", "where it", "counts"]) >>> pypkgs.catbind(a, b) [character, hits, your, eyeballs, but, integer, where it, counts] Categories (8, object): [but, character, counts, eyeballs, hits, integer, where it, your] """ valid = True if str(type(data)) == "<class 'list'>": for i in range(len(data)): if str(type(data[i])) != "<class 'dict'>": print( "Data Format Error - the input data should be a list of dictionary") valid = False break else: valid = False return valid
[docs]def id_generator(size=15, random_state=None): """Generate unique ids for div tag which will contain the visualisation stuff from d3. Parameters ---------- param1 : :obj:`int` An integer that specifies the length of the returned id, default = 15. param2 : :obj:`np.random.RandomState`, default is None. A RandomState instance. Returns ------- :obj:`str` A random identifier. Examples -------- >>> from pypkgs import pypkgs >>> a = pd.Categorical(["character", "hits", "your", "eyeballs"]) >>> b = pd.Categorical(["but", "integer", "where it", "counts"]) >>> pypkgs.catbind(a, b) [character, hits, your, eyeballs, but, integer, where it, counts] Categories (8, object): [but, character, counts, eyeballs, hits, integer, where it, your] """ chars = list(string.ascii_uppercase + string.digits) return ''.join(random_state.choice(chars, size, replace=True))
[docs]class Explainer(): """ __init__ method of Explainer class. Parameters ---------- param1 : :obj:`list` of :obj:`dict` A list of dictionary that contains the specification of the bullet chart to be created. param2 : :obj:`list` of :obj:`dict` A list of dictionary that contains the information about risk scores. param3 : :obj:`np.random.RandomState`, default is None A RandomState instance. """ def __init__(self, bullet_data, risk_data, random_state=None): valid_bullet_data = data_validation(bullet_data) if valid_bullet_data: self.set_bullet_data(str(bullet_data)+";") else: self.set_bullet_data([{}]) print( "Bullet Data Format Error - the input data should be a list of dictionary") valid_risk_data = data_validation(risk_data) if valid_risk_data: self.set_risk_data(str(risk_data)+";") else: self.set_risk_data([{}]) print( "Risk Data Format Error - the input data should be a list of dictionary") self.random_state = random_state
[docs] def generate_html(self): """Generate html and return it as a String. Returns ---------- :obj:`str` html String Examples -------- >>> from pypkgs import pypkgs >>> a = pd.Categorical(["character", "hits", "your", "eyeballs"]) >>> b = pd.Categorical(["but", "integer", "where it", "counts"]) >>> pypkgs.catbind(a, b) [character, hits, your, eyeballs, but, integer, where it, counts] Categories (8, object): [but, character, counts, eyeballs, hits, integer, where it, your] """ unique_id = id_generator(random_state=check_random_state(self.get_random_state())) css_filepath = "css/styles.css" css_stylesheet = \ """ <link rel="stylesheet" href="%s" /> """ % (css_filepath) d3_filepath = "js/d3.min.js" bulletjs_filepath = "js/bullet.js" d3_script = \ """ <script src="%s"></script> <script src="%s"></script> """ % (d3_filepath, bulletjs_filepath) main_title = "What to do to decrease the risk of having defects?" title = \ """ <div style="position: relative; top: 0; width: 100vw; text-align: center"> <b>%s</b> </div> """ % main_title d3_operation_script = \ """ <script> var margin = { top: 5, right: 40, bottom: 20, left: 500 }, width = 1300 - margin.left - margin.right, height = 50 - margin.top - margin.bottom; var chart = d3.bullet().width(width).height(height); var bulletData = %s var riskData = %s // define the color of the box var boxColor = "box green"; var riskPred = riskData[0].riskPred[0]; if (riskPred.localeCompare("Yes")==0) { boxColor = "box orange"; } // append risk prediction and risk score d3.select("#d3-target-bullet-%s") .append("div") .attr("class", "riskPred") .data(riskData) .text((d) => d.riskPred) .append("div") .attr("class", boxColor); d3.select("#d3-target-bullet-%s") .append("div") .attr("class", "riskScore") .data(riskData) .text((d) => "Risk Score: " + d.riskScore); var svg = d3 .select("#d3-target-bullet-%s") .selectAll("svg") .data(bulletData) .enter() .append("svg") .attr("class", "bullet") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr( "transform", "translate(" + margin.left + "," + margin.top + ")" ) .call(chart); var title = svg .append("g") .style("text-anchor", "end") .attr("transform", "translate(-6," + height / 2 + ")"); title .append("text") .attr("class", "title") .text((d) => d.title); title .append("text") .attr("class", "subtitle") .attr("dy", "1em") .text((d) => d.subtitle); </script> """ % (self.get_bullet_data(), self.get_risk_data(), unique_id, unique_id, unique_id) html = \ """ <!DOCTYPE html> <html> <meta http-equiv="content-type" content="text/html; charset=UTF8"> <head> %s %s </head> <body> <div class="bullet-chart"> %s <div class="d3-target-bullet" id="d3-target-bullet-%s" /> </div> %s </body> </html> """ % (css_stylesheet, d3_script, title, unique_id, d3_operation_script) return html
[docs] def get_bullet_data(self): return self.bullet_data
[docs] def get_random_state(self): return self.random_state
[docs] def get_risk_data(self): return self.risk_data
[docs] def set_bullet_data(self, bullet_data): self.bullet_data = bullet_data
[docs] def set_random_state(self, random_state): self.random_state = random_state
[docs] def set_risk_data(self, risk_data): self.risk_data = risk_data
[docs] def show_visualisation(self): """Display the html string in a cell of Jupyter Notebook. Examples -------- >>> from pypkgs import pypkgs >>> a = pd.Categorical(["character", "hits", "your", "eyeballs"]) >>> b = pd.Categorical(["but", "integer", "where it", "counts"]) >>> pypkgs.catbind(a, b) [character, hits, your, eyeballs, but, integer, where it, counts] Categories (8, object): [but, character, counts, eyeballs, hits, integer, where it, your] """ self.generate_html() from IPython.core.display import display, HTML print(self.generate_html()) # TBR - (to be removed) display(HTML(self.generate_html()))