mirror of
				https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
				synced 2025-11-03 20:27:54 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1246 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1246 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
"""
 | 
						|
NAME: lf_graph.py
 | 
						|
 | 
						|
PURPOSE:
 | 
						|
Common Library for generating graphs for LANforge output
 | 
						|
 | 
						|
SETUP:
 | 
						|
/lanforge/html-reports directory needs to be present or output generated in local file
 | 
						|
 | 
						|
EXAMPLE:
 | 
						|
see: /py-scritps/lf_report_test.py for example
 | 
						|
 | 
						|
COPYRIGHT:
 | 
						|
    Copyright 2021 Candela Technologies Inc
 | 
						|
    License: Free to distribute and modify. LANforge systems must be licensed.
 | 
						|
 | 
						|
INCLUDE_IN_README
 | 
						|
"""
 | 
						|
import sys
 | 
						|
import os
 | 
						|
import importlib
 | 
						|
import matplotlib.pyplot as plt
 | 
						|
import numpy as np
 | 
						|
import pdfkit
 | 
						|
from matplotlib.colors import ListedColormap
 | 
						|
import matplotlib.ticker as mticker
 | 
						|
import argparse
 | 
						|
import traceback
 | 
						|
import logging
 | 
						|
 | 
						|
 | 
						|
# TODO have scipy be part of the base install
 | 
						|
try:
 | 
						|
    from scipy import interpolate
 | 
						|
 | 
						|
except Exception as x:
 | 
						|
    print("Info:  scipy package not installed, Needed for smoothing linear plots 'pip install scipy'  ")
 | 
						|
    traceback.print_exception(Exception, x, x.__traceback__, chain=True)
 | 
						|
 | 
						|
 | 
						|
sys.path.append(os.path.join(os.path.abspath(__file__ + "../../../")))
 | 
						|
 | 
						|
logger = logging.getLogger(__name__)
 | 
						|
lf_logger_config = importlib.import_module("py-scripts.lf_logger_config")
 | 
						|
 | 
						|
lf_csv = importlib.import_module("py-scripts.lf_csv")
 | 
						|
lf_csv = lf_csv.lf_csv
 | 
						|
 | 
						|
# internal candela references included during intial phases, to be deleted
 | 
						|
# at future date
 | 
						|
 | 
						|
# graph reporting classes
 | 
						|
 | 
						|
 | 
						|
class lf_bar_graph:
 | 
						|
    def __init__(self, _data_set=None,
 | 
						|
                 _xaxis_name="x-axis",
 | 
						|
                 _yaxis_name="y-axis",
 | 
						|
                 _xaxis_categories=None,
 | 
						|
                 _xaxis_label=None,
 | 
						|
                 _graph_title="",
 | 
						|
                 _title_size=16,
 | 
						|
                 _graph_image_name="image_name",
 | 
						|
                 _label=None,
 | 
						|
                 _color=None,
 | 
						|
                 _bar_width=0.25,
 | 
						|
                 _color_edge='grey',
 | 
						|
                 _font_weight='bold',
 | 
						|
                 _color_name=None,
 | 
						|
                 _figsize=(10, 5),
 | 
						|
                 _show_bar_value=False,
 | 
						|
                 _xaxis_step=1,
 | 
						|
                 _xticks_font=None,
 | 
						|
                 _xaxis_value_location=0,
 | 
						|
                 _xticks_rotation=None,
 | 
						|
                 _text_font=None,
 | 
						|
                 _text_rotation=None,
 | 
						|
                 _grp_title="",
 | 
						|
                 _legend_handles=None,
 | 
						|
                 _legend_loc="best",
 | 
						|
                 _legend_box=None,
 | 
						|
                 _legend_ncol=1,
 | 
						|
                 _legend_fontsize=None,
 | 
						|
                 _dpi=96,
 | 
						|
                 _enable_csv=False,
 | 
						|
                 _remove_border=None,
 | 
						|
                 _alignment=None
 | 
						|
                 ):
 | 
						|
 | 
						|
        if _data_set is None:
 | 
						|
            _data_set = [[30.4, 55.3, 69.2, 37.1], [45.1, 67.2, 34.3, 22.4], [22.5, 45.6, 12.7, 34.8]]
 | 
						|
        if _xaxis_categories is None:
 | 
						|
            _xaxis_categories = [1, 2, 3, 4]
 | 
						|
        if _xaxis_label is None:
 | 
						|
            _xaxis_label = ["a", "b", "c", "d"]
 | 
						|
        if _label is None:
 | 
						|
            _label = ["bi-downlink", "bi-uplink", 'uplink']
 | 
						|
        if _color_name is None:
 | 
						|
            _color_name = ['lightcoral', 'darkgrey', 'r', 'g', 'b', 'y']
 | 
						|
        self.data_set = _data_set
 | 
						|
        self.xaxis_name = _xaxis_name
 | 
						|
        self.yaxis_name = _yaxis_name
 | 
						|
        self.xaxis_categories = _xaxis_categories
 | 
						|
        self.xaxis_label = _xaxis_label
 | 
						|
        self.title = _graph_title
 | 
						|
        self.title_size = _title_size
 | 
						|
        self.graph_image_name = _graph_image_name
 | 
						|
        self.label = _label
 | 
						|
        self.color = _color
 | 
						|
        self.bar_width = _bar_width
 | 
						|
        self.color_edge = _color_edge
 | 
						|
        self.font_weight = _font_weight
 | 
						|
        self.color_name = _color_name
 | 
						|
        self.figsize = _figsize
 | 
						|
        self.show_bar_value = _show_bar_value
 | 
						|
        self.xaxis_step = _xaxis_step
 | 
						|
        self.xticks_font = _xticks_font
 | 
						|
        self._xaxis_value_location = _xaxis_value_location
 | 
						|
        self.text_font = _text_font
 | 
						|
        self.text_rotation = _text_rotation
 | 
						|
        self.grp_title = _grp_title
 | 
						|
        self.enable_csv = _enable_csv
 | 
						|
        self.lf_csv = lf_csv()
 | 
						|
        self.legend_handles = _legend_handles
 | 
						|
        self.legend_loc = _legend_loc
 | 
						|
        self.legend_box = _legend_box
 | 
						|
        self.legend_ncol = _legend_ncol
 | 
						|
        self.legend_fontsize = _legend_fontsize
 | 
						|
        self.remove_border = _remove_border
 | 
						|
        self.alignment = _alignment
 | 
						|
        self.xticks_rotation = _xticks_rotation
 | 
						|
 | 
						|
    def build_bar_graph(self):
 | 
						|
        if self.color is None:
 | 
						|
            i = 0
 | 
						|
            self.color = []
 | 
						|
            for _ in self.data_set:
 | 
						|
                self.color.append(self.color_name[i])
 | 
						|
                i = i + 1
 | 
						|
 | 
						|
        fig_size, ax = plt.subplots(figsize=self.figsize, gridspec_kw=self.alignment)
 | 
						|
        i = 0
 | 
						|
        # to remove the borders
 | 
						|
        if self.remove_border is not None:
 | 
						|
            for border in self.remove_border:
 | 
						|
                ax.spines[border].set_color(None)
 | 
						|
                if 'left' in self.remove_border:    # to remove the y-axis labeling
 | 
						|
                    yaxis_visable =False
 | 
						|
                else:
 | 
						|
                    yaxis_visable=True
 | 
						|
                ax.yaxis.set_visible(yaxis_visable)
 | 
						|
 | 
						|
        def show_value(rectangles):
 | 
						|
            for rect in rectangles:
 | 
						|
                h = rect.get_height()
 | 
						|
                plt.text(rect.get_x() + rect.get_width() / 2., h, h,
 | 
						|
                         ha='center', va='bottom', rotation=self.text_rotation, fontsize=self.text_font)
 | 
						|
 | 
						|
        for _ in self.data_set:
 | 
						|
            if i > 0:
 | 
						|
                br = br1
 | 
						|
                br2 = [x + self.bar_width for x in br]
 | 
						|
                rects = plt.bar(br2, self.data_set[i], color=self.color[i], width=self.bar_width,
 | 
						|
                                edgecolor=self.color_edge, label=self.label[i])
 | 
						|
                if self.show_bar_value:
 | 
						|
                    show_value(rects)
 | 
						|
                br1 = br2
 | 
						|
                i = i + 1
 | 
						|
            else:
 | 
						|
                br1 = np.arange(len(self.data_set[i]))
 | 
						|
                rects = plt.bar(br1, self.data_set[i], color=self.color[i], width=self.bar_width,
 | 
						|
                                edgecolor=self.color_edge, label=self.label[i])
 | 
						|
                if self.show_bar_value:
 | 
						|
                    show_value(rects)
 | 
						|
                i = i + 1
 | 
						|
        plt.xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        plt.ylabel(self.yaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        if self.xaxis_categories[0] == 0:
 | 
						|
            plt.xticks(np.arange(0,
 | 
						|
                                 len(self.xaxis_categories),
 | 
						|
                                 step=self.xaxis_step),
 | 
						|
                       fontsize=self.xticks_font,rotation=self.xticks_rotation)
 | 
						|
        else:
 | 
						|
            plt.xticks([i + self._xaxis_value_location for i in np.arange(0, len(self.data_set[0]), step=self.xaxis_step)],
 | 
						|
                       self.xaxis_categories, fontsize=self.xticks_font,rotation=self.xticks_rotation)
 | 
						|
        plt.legend(
 | 
						|
            handles=self.legend_handles,
 | 
						|
            loc=self.legend_loc,
 | 
						|
            bbox_to_anchor=self.legend_box,
 | 
						|
            ncol=self.legend_ncol,
 | 
						|
            fontsize=self.legend_fontsize)
 | 
						|
        plt.suptitle(self.title, fontsize=self.title_size)
 | 
						|
        plt.title(self.grp_title)
 | 
						|
        plt.gcf()
 | 
						|
        plt.savefig("%s.png" % self.graph_image_name, dpi=96)
 | 
						|
        plt.close()
 | 
						|
        logger.debug("{}.png".format(self.graph_image_name))
 | 
						|
        if self.enable_csv:
 | 
						|
            if self.data_set is not None and self.xaxis_categories is not None:
 | 
						|
                if len(self.xaxis_categories) == len(self.data_set[0]):
 | 
						|
                    self.lf_csv.columns = []
 | 
						|
                    self.lf_csv.rows = []
 | 
						|
                    self.lf_csv.columns.append(self.xaxis_name)
 | 
						|
                    self.lf_csv.columns.extend(self.label)
 | 
						|
                    self.lf_csv.rows.append(self.xaxis_categories)
 | 
						|
                    self.lf_csv.rows.extend(self.data_set)
 | 
						|
                    self.lf_csv.filename = f"{self.graph_image_name}.csv"
 | 
						|
                    self.lf_csv.generate_csv()
 | 
						|
                else:
 | 
						|
                    raise ValueError(
 | 
						|
                        "Length and x-axis values and y-axis values should be same.")
 | 
						|
            else:
 | 
						|
                 logger.debug("No Dataset Found")
 | 
						|
        logger.debug("{}.csv".format(self.graph_image_name))
 | 
						|
        return "%s.png" % self.graph_image_name
 | 
						|
 | 
						|
 | 
						|
 | 
						|
class lf_bar_graph_horizontal:
 | 
						|
    def __init__(self, _data_set=None,
 | 
						|
                 _xaxis_name="x-axis",
 | 
						|
                 _yaxis_name="y-axis",
 | 
						|
                 _yaxis_categories=None,
 | 
						|
                 _yaxis_label=None,
 | 
						|
                 _graph_title="",
 | 
						|
                 _title_size=16,
 | 
						|
                 _graph_image_name="image_name",
 | 
						|
                 _label=None,
 | 
						|
                 _color=None,
 | 
						|
                 _bar_height=0.25,
 | 
						|
                 _color_edge='grey',
 | 
						|
                 _font_weight='bold',
 | 
						|
                 _color_name=None,
 | 
						|
                 _figsize=(10, 5),
 | 
						|
                 _show_bar_value=False,
 | 
						|
                 _yaxis_step=1,
 | 
						|
                 _yticks_font=None,
 | 
						|
                 _yaxis_value_location=0,
 | 
						|
                 _yticks_rotation=None,
 | 
						|
                 _text_font=None,
 | 
						|
                 _text_rotation=None,
 | 
						|
                 _grp_title="",
 | 
						|
                 _legend_handles=None,
 | 
						|
                 _legend_loc="best",
 | 
						|
                 _legend_box=None,
 | 
						|
                 _legend_ncol=1,
 | 
						|
                 _legend_fontsize=None,
 | 
						|
                 _dpi=96,
 | 
						|
                 _enable_csv=False,
 | 
						|
                 _remove_border=None,
 | 
						|
                 _alignment=None
 | 
						|
                 ):
 | 
						|
 | 
						|
        if _data_set is None:
 | 
						|
            _data_set = [[30.4, 55.3, 69.2, 37.1], [45.1, 67.2, 34.3, 22.4], [22.5, 45.6, 12.7, 34.8]]
 | 
						|
        if _yaxis_categories is None:
 | 
						|
            _yaxis_categories = [1, 2, 3, 4]
 | 
						|
        if _yaxis_label is None:
 | 
						|
            _yaxis_label = ["a", "b", "c", "d"]
 | 
						|
        if _label is None:
 | 
						|
            _label = ["bi-downlink", "bi-uplink", 'uplink']
 | 
						|
        if _color_name is None:
 | 
						|
            _color_name = ['lightcoral', 'darkgrey', 'r', 'g', 'b', 'y']
 | 
						|
        self.data_set = _data_set
 | 
						|
        self.xaxis_name = _xaxis_name
 | 
						|
        self.yaxis_name = _yaxis_name
 | 
						|
        self.yaxis_categories = _yaxis_categories
 | 
						|
        self.yaxis_label = _yaxis_label
 | 
						|
        self.title = _graph_title
 | 
						|
        self.title_size = _title_size
 | 
						|
        self.graph_image_name = _graph_image_name
 | 
						|
        self.label = _label
 | 
						|
        self.color = _color
 | 
						|
        self.bar_height = _bar_height
 | 
						|
        self.color_edge = _color_edge
 | 
						|
        self.font_weight = _font_weight
 | 
						|
        self.color_name = _color_name
 | 
						|
        self.figsize = _figsize
 | 
						|
        self.show_bar_value = _show_bar_value
 | 
						|
        self.yaxis_step = _yaxis_step
 | 
						|
        self.yticks_font = _yticks_font
 | 
						|
        self._yaxis_value_location = _yaxis_value_location
 | 
						|
        self.text_font = _text_font
 | 
						|
        self.text_rotation = _text_rotation
 | 
						|
        self.grp_title = _grp_title
 | 
						|
        self.enable_csv = _enable_csv
 | 
						|
        self.lf_csv = lf_csv()
 | 
						|
        self.legend_handles = _legend_handles
 | 
						|
        self.legend_loc = _legend_loc
 | 
						|
        self.legend_box = _legend_box
 | 
						|
        self.legend_ncol = _legend_ncol
 | 
						|
        self.legend_fontsize = _legend_fontsize
 | 
						|
        self.remove_border = _remove_border
 | 
						|
        self.alignment = _alignment
 | 
						|
        self.yticks_rotation = _yticks_rotation
 | 
						|
 | 
						|
    def build_bar_graph_horizontal(self):
 | 
						|
        if self.color is None:
 | 
						|
            i = 0
 | 
						|
            self.color = []
 | 
						|
            for _ in self.data_set:
 | 
						|
                self.color.append(self.color_name[i])
 | 
						|
                i = i + 1
 | 
						|
 | 
						|
        fig_size, ax = plt.subplots(figsize=self.figsize, gridspec_kw=self.alignment)
 | 
						|
        i = 0
 | 
						|
        # to remove the borders
 | 
						|
        if self.remove_border is not None:
 | 
						|
            for border in self.remove_border:
 | 
						|
                ax.spines[border].set_color(None)
 | 
						|
                if 'left' in self.remove_border:    # to remove the y-axis labeling
 | 
						|
                    yaxis_visable =False
 | 
						|
                else:
 | 
						|
                    yaxis_visable=True
 | 
						|
                ax.yaxis.set_visible(yaxis_visable)
 | 
						|
 | 
						|
        def show_value(rectangles):
 | 
						|
            for rect in rectangles:
 | 
						|
                w = rect.get_width()
 | 
						|
                y = rect.get_y()
 | 
						|
                h = rect.get_height()
 | 
						|
                x = rect.get_x()
 | 
						|
                # adding 1 may not always work based on the x axis scale may need to be configurable
 | 
						|
                plt.text(w + 1 , rect.get_y() + rect.get_height() / 4., w,
 | 
						|
                         ha='center', va='bottom', rotation=self.text_rotation, fontsize=self.text_font)
 | 
						|
 | 
						|
        for _ in self.data_set:
 | 
						|
            if i > 0:
 | 
						|
                br = br1
 | 
						|
                br2 = [y + self.bar_height for y in br]
 | 
						|
                rects = plt.barh(br2, self.data_set[i], color=self.color[i], height=self.bar_height,
 | 
						|
                                edgecolor=self.color_edge, label=self.label[i])
 | 
						|
                if self.show_bar_value:
 | 
						|
                    show_value(rects)
 | 
						|
                br1 = br2
 | 
						|
                i = i + 1
 | 
						|
            else:
 | 
						|
                br1 = np.arange(len(self.data_set[i]))
 | 
						|
                rects = plt.barh(br1, self.data_set[i], color=self.color[i], height=self.bar_height,
 | 
						|
                                edgecolor=self.color_edge, label=self.label[i])
 | 
						|
                if self.show_bar_value:
 | 
						|
                    show_value(rects)
 | 
						|
                i = i + 1
 | 
						|
        plt.xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        plt.ylabel(self.yaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        if self.yaxis_categories[0] == 0:
 | 
						|
            plt.yticks(np.arange(0,
 | 
						|
                                 len(self.yaxis_categories),
 | 
						|
                                 step=self.yaxis_step),
 | 
						|
                       fontsize=self.yticks_font,rotation=self.yticks_rotation)
 | 
						|
        else:
 | 
						|
            plt.yticks([i + self._yaxis_value_location for i in np.arange(0, len(self.data_set[0]), step=self.yaxis_step)],
 | 
						|
                       self.yaxis_categories, fontsize=self.yticks_font,rotation=self.yticks_rotation)
 | 
						|
        plt.legend(
 | 
						|
            handles=self.legend_handles,
 | 
						|
            loc=self.legend_loc,
 | 
						|
            bbox_to_anchor=self.legend_box,
 | 
						|
            ncol=self.legend_ncol,
 | 
						|
            fontsize=self.legend_fontsize)
 | 
						|
        plt.suptitle(self.title, fontsize=self.title_size)
 | 
						|
        plt.title(self.grp_title)
 | 
						|
        plt.gcf()
 | 
						|
        plt.savefig("%s.png" % self.graph_image_name, dpi=96)
 | 
						|
        plt.close()
 | 
						|
        logger.debug("{}.png".format(self.graph_image_name))
 | 
						|
        if self.enable_csv:
 | 
						|
            if self.data_set is not None and self.yaxis_categories is not None:
 | 
						|
                if len(self.yaxis_categories) == len(self.data_set[0]):
 | 
						|
                    self.lf_csv.columns = []
 | 
						|
                    self.lf_csv.rows = []
 | 
						|
                    self.lf_csv.columns.append(self.yaxis_name)
 | 
						|
                    self.lf_csv.columns.extend(self.label)
 | 
						|
                    self.lf_csv.rows.append(self.yaxis_categories)
 | 
						|
                    self.lf_csv.rows.extend(self.data_set)
 | 
						|
                    self.lf_csv.filename = f"{self.graph_image_name}.csv"
 | 
						|
                    self.lf_csv.generate_csv()
 | 
						|
                else:
 | 
						|
                    raise ValueError(
 | 
						|
                        "Length and x-axis values and y-axis values should be same.")
 | 
						|
            else:
 | 
						|
                 logger.debug("No Dataset Found")
 | 
						|
        logger.debug("{}.csv".format(self.graph_image_name))
 | 
						|
        return "%s.png" % self.graph_image_name
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
class lf_scatter_graph:
 | 
						|
    def __init__(self,
 | 
						|
                 _x_data_set=None,
 | 
						|
                 _y_data_set=None,
 | 
						|
                 _values=None,
 | 
						|
                 _xaxis_name="x-axis",
 | 
						|
                 _yaxis_name="y-axis",
 | 
						|
                 _label=None,
 | 
						|
                 _graph_image_name="image_name1",
 | 
						|
                 _color=None,
 | 
						|
                 _figsize=(9, 4),
 | 
						|
                 _enable_csv=True):
 | 
						|
        if _x_data_set is None:
 | 
						|
            _x_data_set = ["sta0 ", "sta1", "sta2", "sta3"]
 | 
						|
        if _y_data_set is None:
 | 
						|
            _y_data_set = [[30, 55, 69, 37]]
 | 
						|
        if _label is None:
 | 
						|
            _label = ["num1", "num2"]
 | 
						|
        self.x_data_set = _x_data_set
 | 
						|
        self.y_data_set = _y_data_set
 | 
						|
        self.xaxis_name = _xaxis_name
 | 
						|
        self.yaxis_name = _yaxis_name
 | 
						|
        self.figsize = _figsize
 | 
						|
        self.graph_image_name = _graph_image_name
 | 
						|
        self.color = _color
 | 
						|
        self.label = _label
 | 
						|
        self.values = _values
 | 
						|
        self.enable_csv = _enable_csv
 | 
						|
        self.lf_csv = lf_csv()
 | 
						|
 | 
						|
    def build_scatter_graph(self):
 | 
						|
        if self.color is None:
 | 
						|
            self.color = [
 | 
						|
                "orchid",
 | 
						|
                "lime",
 | 
						|
                "aquamarine",
 | 
						|
                "royalblue",
 | 
						|
                "darkgray",
 | 
						|
                "maroon"]
 | 
						|
        plt.subplots(figsize=self.figsize)
 | 
						|
        if self.values is None:
 | 
						|
            plt.scatter(
 | 
						|
                self.x_data_set,
 | 
						|
                self.y_data_set[0],
 | 
						|
                color=self.color[0],
 | 
						|
                label=self.label[0])
 | 
						|
            if len(self.y_data_set) > 1:
 | 
						|
                for i in range(1, len(self.y_data_set)):
 | 
						|
                    plt.scatter(
 | 
						|
                        self.x_data_set,
 | 
						|
                        self.y_data_set[i],
 | 
						|
                        color=self.color[i],
 | 
						|
                        label=self.label[i])
 | 
						|
            plt.xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
 | 
						|
            plt.ylabel(self.yaxis_name, fontweight='bold', fontsize=15)
 | 
						|
            plt.gcf().autofmt_xdate()
 | 
						|
            plt.legend()
 | 
						|
        else:
 | 
						|
            colours = ListedColormap(self.color)
 | 
						|
            scatter = plt.scatter(
 | 
						|
                self.x_data_set,
 | 
						|
                self.y_data_set,
 | 
						|
                c=self.values,
 | 
						|
                cmap=colours)
 | 
						|
            plt.xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
 | 
						|
            plt.ylabel(self.yaxis_name, fontweight='bold', fontsize=15)
 | 
						|
            plt.gcf().autofmt_xdate()
 | 
						|
            plt.legend(handles=scatter.legend_elements()[0], labels=self.label)
 | 
						|
        plt.savefig("%s.png" % self.graph_image_name, dpi=96)
 | 
						|
        plt.close()
 | 
						|
        logger.debug("{}.png".format(self.graph_image_name))
 | 
						|
        if self.enable_csv:
 | 
						|
            self.lf_csv.columns = self.label
 | 
						|
            self.lf_csv.rows = self.y_data_set
 | 
						|
            self.lf_csv.filename = f"{self.graph_image_name}.csv"
 | 
						|
            self.lf_csv.generate_csv()
 | 
						|
 | 
						|
        return "%s.png" % self.graph_image_name
 | 
						|
 | 
						|
# have a second yaxis with line graph
 | 
						|
class lf_bar_line_graph:
 | 
						|
    def __init__(self,
 | 
						|
                 _data_set1=None,
 | 
						|
                 # Note data_set2, data_set2_poly and data_set2_spline needs same size list
 | 
						|
                 _data_set2=None,
 | 
						|
                 _data_set2_poly=[False], # Values are True or False
 | 
						|
                 _data_set2_poly_degree=[3],
 | 
						|
                 _data_set2_interp1d=[False], # Values are True or False
 | 
						|
                 _xaxis_name="x-axis",
 | 
						|
                 _y1axis_name="y1-axis",
 | 
						|
                 _y2axis_name="y2-axis",
 | 
						|
                 _xaxis_categories=None,
 | 
						|
                 _xaxis_label=None,
 | 
						|
                 _graph_title="",
 | 
						|
                 _title_size=16,
 | 
						|
                 _graph_image_name="image_name",
 | 
						|
                 _label1=None,
 | 
						|
                 _label2=None,
 | 
						|
                 _label2_poly=None,
 | 
						|
                 _label2_interp1d=None,
 | 
						|
                 _color1=None,
 | 
						|
                 _color2=None,
 | 
						|
                 _color2_poly=None,
 | 
						|
                 _color2_interp1d=None,
 | 
						|
                 _bar_width=0.25,
 | 
						|
                 _color_edge='grey',
 | 
						|
                 _font_weight='bold',
 | 
						|
                 _color_name1=None,
 | 
						|
                 _color_name2=None,
 | 
						|
                 _marker=None,
 | 
						|
                 _figsize=(10, 5),
 | 
						|
                 _show_bar_value=False,
 | 
						|
                 _xaxis_step=1,
 | 
						|
                 _xticks_font=None,
 | 
						|
                 _xaxis_value_location=0,
 | 
						|
                 _text_font=None,
 | 
						|
                 _text_rotation=None,
 | 
						|
                 _grp_title="",
 | 
						|
                 _legend_handles=None,
 | 
						|
                 _legend_loc1="best",
 | 
						|
                 _legend_loc2="best",
 | 
						|
                 _legend_box1=None,
 | 
						|
                 _legend_box2=None,
 | 
						|
                 _legend_ncol=1,
 | 
						|
                 _legend_fontsize=None,
 | 
						|
                 _dpi=96,
 | 
						|
                 _enable_csv=False):
 | 
						|
 | 
						|
        if _data_set1 is None:
 | 
						|
            _data_set1 = [[30.4, 55.3, 69.2, 37.1], [45.1, 67.2, 34.3, 22.4], [22.5, 45.6, 12.7, 34.8]]
 | 
						|
        if _xaxis_categories is None:
 | 
						|
            _xaxis_categories = [1, 2, 3, 4]
 | 
						|
        if _xaxis_label is None:
 | 
						|
            _xaxis_label = ["a", "b", "c", "d"]
 | 
						|
        if _label1 is None:
 | 
						|
            _label1 = ["bi-downlink", "bi-uplink", 'uplink']
 | 
						|
        if _label2 is None:
 | 
						|
            _label2 = ["bi-downlink", "bi-uplink", 'uplink']
 | 
						|
 | 
						|
        if _color_name1 is None:
 | 
						|
            _color_name1 = ['lightcoral', 'darkgrey', 'r', 'g', 'b', 'y']
 | 
						|
        if _color_name2 is None:
 | 
						|
            _color_name2 = ['lightcoral', 'darkgrey', 'r', 'g', 'b', 'y']
 | 
						|
        self.data_set1 = _data_set1
 | 
						|
        self.data_set2 = _data_set2
 | 
						|
        self.data_set2_poly = _data_set2_poly
 | 
						|
        self.data_set2_poly_degree = _data_set2_poly_degree
 | 
						|
        self.data_set2_interp1d = _data_set2_interp1d
 | 
						|
        self.xaxis_name = _xaxis_name
 | 
						|
        self.y1axis_name = _y1axis_name
 | 
						|
        self.y2axis_name = _y2axis_name
 | 
						|
        self.xaxis_categories = _xaxis_categories
 | 
						|
        self.xaxis_label = _xaxis_label
 | 
						|
        self.title = _graph_title
 | 
						|
        self.title_size = _title_size
 | 
						|
        self.graph_image_name = _graph_image_name
 | 
						|
        self.label1 = _label1
 | 
						|
        self.label2 = _label2
 | 
						|
        self.label2_poly = _label2_poly
 | 
						|
        self.label2_interp1d = _label2_interp1d
 | 
						|
        self.color1 = _color1
 | 
						|
        self.color2 = _color2
 | 
						|
        self.color2_poly = _color2_poly
 | 
						|
        self.color2_interp1d = _color2_interp1d
 | 
						|
        self.marker = _marker
 | 
						|
        self.bar_width = _bar_width
 | 
						|
        self.color_edge = _color_edge
 | 
						|
        self.font_weight = _font_weight
 | 
						|
        self.color_name1 = _color_name1
 | 
						|
        self.color_name2 = _color_name2
 | 
						|
        self.figsize = _figsize
 | 
						|
        self.show_bar_value = _show_bar_value
 | 
						|
        self.xaxis_step = _xaxis_step
 | 
						|
        self.xticks_font = _xticks_font
 | 
						|
        self._xaxis_value_location = _xaxis_value_location
 | 
						|
        self.text_font = _text_font
 | 
						|
        self.text_rotation = _text_rotation
 | 
						|
        self.grp_title = _grp_title
 | 
						|
        self.enable_csv = _enable_csv
 | 
						|
        self.lf_csv = lf_csv()
 | 
						|
        self.legend_handles = _legend_handles
 | 
						|
        self.legend_loc1 = _legend_loc1
 | 
						|
        self.legend_loc2 = _legend_loc2
 | 
						|
        self.legend_box1 = _legend_box1
 | 
						|
        self.legend_box2 = _legend_box2
 | 
						|
        self.legend_ncol = _legend_ncol
 | 
						|
        self.legend_fontsize = _legend_fontsize
 | 
						|
 | 
						|
    def build_bar_line_graph(self):
 | 
						|
        if self.color1 is None:
 | 
						|
            i = 0
 | 
						|
            self.color1 = []
 | 
						|
            for _ in self.data_set1:
 | 
						|
                self.color1.append(self.color_name[i])
 | 
						|
                i = i + 1
 | 
						|
 | 
						|
        fig, ax1 = plt.subplots(figsize=self.figsize)
 | 
						|
 | 
						|
        ax2 = ax1.twinx()
 | 
						|
 | 
						|
        i = 0
 | 
						|
 | 
						|
        def show_value(rectangles):
 | 
						|
            for rect in rectangles:
 | 
						|
                h = rect.get_height()
 | 
						|
                ax1.text(rect.get_x() + rect.get_width() / 2., h, h,
 | 
						|
                         ha='center', va='bottom', rotation=self.text_rotation, fontsize=self.text_font)
 | 
						|
 | 
						|
        for _ in self.data_set1:
 | 
						|
            if i > 0:
 | 
						|
                br = br1
 | 
						|
                br2 = [x + self.bar_width for x in br]
 | 
						|
                rects = ax1.bar(br2, self.data_set1[i], color=self.color1[i], width=self.bar_width,
 | 
						|
                                edgecolor=self.color_edge, label=self.label1[i])
 | 
						|
                if self.show_bar_value:
 | 
						|
                    show_value(rects)
 | 
						|
                br1 = br2
 | 
						|
                i = i + 1
 | 
						|
            else:
 | 
						|
                br1 = np.arange(len(self.data_set1[i]))
 | 
						|
                rects = ax1.bar(br1, self.data_set1[i], color=self.color1[i], width=self.bar_width,
 | 
						|
                                edgecolor=self.color_edge, label=self.label1[i])
 | 
						|
                if self.show_bar_value:
 | 
						|
                    show_value(rects)
 | 
						|
                i = i + 1
 | 
						|
        ax1.set_xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        ax1.set_ylabel(self.y1axis_name, fontweight='bold', fontsize=15)
 | 
						|
        if self.xaxis_categories[0] == 0:
 | 
						|
            xsteps = plt.xticks(np.arange(0,
 | 
						|
                                 len(self.xaxis_categories),
 | 
						|
                                 step=self.xaxis_step),
 | 
						|
                       fontsize=self.xticks_font)
 | 
						|
        else:
 | 
						|
            xsteps = plt.xticks([i + self._xaxis_value_location for i in np.arange(0, len(self.data_set1[0]), step=self.xaxis_step)],
 | 
						|
                       self.xaxis_categories, fontsize=self.xticks_font)
 | 
						|
        ax1.legend(
 | 
						|
            handles=self.legend_handles,
 | 
						|
            loc=self.legend_loc1,
 | 
						|
            bbox_to_anchor=self.legend_box1,
 | 
						|
            ncol=self.legend_ncol,
 | 
						|
            fontsize=self.legend_fontsize)
 | 
						|
 | 
						|
 | 
						|
        # overlay line graph
 | 
						|
        def show_value2(data):
 | 
						|
            for item, value in enumerate(data):
 | 
						|
                ax2.text(item, value, "{value}".format(value=value), ha='center',rotation=self.text_rotation, fontsize=self.text_font)
 | 
						|
 | 
						|
        i = 0
 | 
						|
        for _ in self.data_set2:
 | 
						|
            br1 = np.arange(len(self.data_set2[i]))
 | 
						|
            ax2.plot(
 | 
						|
                br1,
 | 
						|
                self.data_set2[i],
 | 
						|
                color=self.color2[i],
 | 
						|
                label=self.label2[i],
 | 
						|
                marker=self.marker[i])
 | 
						|
            show_value2(self.data_set2[i])
 | 
						|
            # do polynomial smoothing
 | 
						|
            if self.data_set2_poly[i]:
 | 
						|
                poly = np.polyfit(br1,self.data_set2[i],self.data_set2_poly_degree[i])
 | 
						|
                poly_y = np.poly1d(poly)(br1)
 | 
						|
                ax2.plot(
 | 
						|
                    br1,
 | 
						|
                    poly_y,
 | 
						|
                    color=self.color2_poly[i],
 | 
						|
                    label=self.label2_poly[i]
 | 
						|
                )
 | 
						|
            if self.data_set2_interp1d[i]:
 | 
						|
                cubic_interpolation_model = interpolate.interp1d(br1, self.data_set2[i],kind="cubic")
 | 
						|
 | 
						|
                x_sm = np.array(br1)
 | 
						|
                x_smooth = np.linspace(x_sm.min(), x_sm.max(), 500)
 | 
						|
                y_smooth = cubic_interpolation_model(x_smooth)
 | 
						|
                ax2.plot(
 | 
						|
                    x_smooth,
 | 
						|
                    y_smooth,
 | 
						|
                    color=self.color2_interp1d[i],
 | 
						|
                    label=self.label2_interp1d[i]
 | 
						|
                )
 | 
						|
 | 
						|
            i += 1
 | 
						|
        ax2.set_xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        ax2.set_ylabel(self.y2axis_name, fontweight='bold', fontsize=15)
 | 
						|
        ax2.tick_params(axis = 'y', labelcolor = 'orange')
 | 
						|
 | 
						|
        ax2.legend(
 | 
						|
            handles=self.legend_handles,
 | 
						|
            loc=self.legend_loc2,
 | 
						|
            bbox_to_anchor=self.legend_box2,
 | 
						|
            ncol=self.legend_ncol,
 | 
						|
            fontsize=self.legend_fontsize)
 | 
						|
        plt.suptitle(self.title, fontsize=self.title_size)
 | 
						|
        plt.title(self.grp_title)
 | 
						|
        plt.gcf()
 | 
						|
        plt.savefig("%s.png" % self.graph_image_name, dpi=96)
 | 
						|
        plt.close()
 | 
						|
        logger.debug("{}.png".format(self.graph_image_name))
 | 
						|
        # TODO work though this for two axis
 | 
						|
        if self.enable_csv:
 | 
						|
            if self.data_set is not None and self.xaxis_categories is not None:
 | 
						|
                if len(self.xaxis_categories) == len(self.data_set[0]):
 | 
						|
                    self.lf_csv.columns = []
 | 
						|
                    self.lf_csv.rows = []
 | 
						|
                    self.lf_csv.columns.append(self.xaxis_name)
 | 
						|
                    self.lf_csv.columns.extend(self.label)
 | 
						|
                    self.lf_csv.rows.append(self.xaxis_categories)
 | 
						|
                    self.lf_csv.rows.extend(self.data_set)
 | 
						|
                    self.lf_csv.filename = f"{self.graph_image_name}.csv"
 | 
						|
                    self.lf_csv.generate_csv()
 | 
						|
                else:
 | 
						|
                    raise ValueError(
 | 
						|
                        "Length and x-axis values and y-axis values should be same.")
 | 
						|
            else:
 | 
						|
                 logger.debug("No Dataset Found")
 | 
						|
        logger.debug("{}.csv".format(self.graph_image_name))
 | 
						|
        return "%s.png" % self.graph_image_name
 | 
						|
 | 
						|
 | 
						|
 | 
						|
class lf_stacked_graph:
 | 
						|
    """
 | 
						|
    usage: This will generate a vertically stacked graph with list _data_set as well as with dictionary _data_set.
 | 
						|
 | 
						|
    example :
 | 
						|
 | 
						|
    For a graph with dictionary data_set
 | 
						|
 | 
						|
        obj = lf_stacked_graph(_data_set={'FCC0':0, 'FCC1':88.4,'FCC2':77.8,'FCC3':57.8,'FCC4':90.0,'FCC95':60.4,'FCC6':33.0},
 | 
						|
                               _xaxis_name="", _yaxis_name="", _enable_csv=False, _remove_border=True)
 | 
						|
        obj.build_stacked_graph()
 | 
						|
 | 
						|
    For a graph with list data_set
 | 
						|
 | 
						|
        obj = lf_stacked_graph(_data_set=[['FCC0', 'FCC1', 'FCC2', 'FCC3', 'FCC4', 'FCC95', 'FCC6'],
 | 
						|
                                          [0, 88.4, 77.8, 57.8, 90.0, 60.4, 33.0],
 | 
						|
                                          [100.0, 11.6, 22.2, 42.2, 10.0, 39.6, 67.0]])
 | 
						|
        obj.build_stacked_graph()
 | 
						|
 | 
						|
    """
 | 
						|
    def __init__(self,
 | 
						|
                 _data_set=None,
 | 
						|
                 _xaxis_name="Stations",
 | 
						|
                 _yaxis_name="Numbers",
 | 
						|
                 _label=None,
 | 
						|
                 _graph_image_name="image_name2",
 | 
						|
                 _color=None,
 | 
						|
                 _figsize=(9, 4),
 | 
						|
                 _enable_csv=True,
 | 
						|
                 _width=0.79,
 | 
						|
                 _bar_text_color='white',
 | 
						|
                 _bar_font_weight='bold',
 | 
						|
                 _bar_font_size=8,
 | 
						|
                 _legend_title="Issues",
 | 
						|
                 _legend_bbox=(1.13, 1.01),
 | 
						|
                 _legend_loc="upper right",
 | 
						|
                 _remove_border=False,
 | 
						|
                 _bar_text_rotation=0,
 | 
						|
                 _x_ticklabels_rotation=0):
 | 
						|
        if _data_set is None:
 | 
						|
            _data_set = [[1, 2, 3, 4], [1, 1, 1, 1], [1, 1, 1, 1]]
 | 
						|
        if _label is None:
 | 
						|
            _label = ['Success', 'Fail']
 | 
						|
        self.data_set = _data_set  # [x_axis,y1_axis,y2_axis]
 | 
						|
        self.xaxis_name = _xaxis_name
 | 
						|
        self.yaxis_name = _yaxis_name
 | 
						|
        self.figsize = _figsize
 | 
						|
        self.graph_image_name = _graph_image_name
 | 
						|
        self.label = _label
 | 
						|
        self.color = _color
 | 
						|
        self.enable_csv = _enable_csv
 | 
						|
        self.lf_csv = lf_csv()
 | 
						|
        self.width = _width
 | 
						|
        self.bar_text_color = _bar_text_color
 | 
						|
        self.bar_font_weight = _bar_font_weight
 | 
						|
        self.bar_font_size = _bar_font_size
 | 
						|
        self.legend_title = _legend_title
 | 
						|
        self.legend_bbox = _legend_bbox
 | 
						|
        self.legend_loc = _legend_loc
 | 
						|
        self.remove_border = _remove_border
 | 
						|
        self.bar_text_rotation = _bar_text_rotation
 | 
						|
        self.x_ticklabels_rotation = _x_ticklabels_rotation
 | 
						|
 | 
						|
    def build_stacked_graph(self):
 | 
						|
        fig, axes_subplot = plt.subplots(figsize=self.figsize)
 | 
						|
        if self.color is None:
 | 
						|
            self.color = [
 | 
						|
                "darkred",
 | 
						|
                "tomato",
 | 
						|
                "springgreen",
 | 
						|
                "skyblue",
 | 
						|
                "indigo",
 | 
						|
                "plum"]
 | 
						|
        if type(self.data_set) is list:
 | 
						|
            plt.bar(self.data_set[0], self.data_set[1], color=self.color[0])
 | 
						|
            plt.bar(
 | 
						|
                self.data_set[0],
 | 
						|
                self.data_set[2],
 | 
						|
                bottom=self.data_set[1],
 | 
						|
                color=self.color[1])
 | 
						|
            if len(self.data_set) > 3:
 | 
						|
                for i in range(3, len(self.data_set)):
 | 
						|
                    plt.bar(self.data_set[0], self.data_set[i],
 | 
						|
                            bottom=np.array(self.data_set[i - 2]) + np.array(self.data_set[i - 1]),color=self.color[i - 1])
 | 
						|
            plt.legend(self.label)
 | 
						|
        elif type(self.data_set) is dict:
 | 
						|
            lable_values = []
 | 
						|
            pass_values = []
 | 
						|
            fail_values = []
 | 
						|
            for i in self.data_set:
 | 
						|
                lable_values.append(i)
 | 
						|
            for j in self.data_set:
 | 
						|
                pass_values.append(self.data_set[j])
 | 
						|
                fail_values.append(round(float(100.0 - self.data_set[j]), 1))
 | 
						|
 | 
						|
            width = self.width
 | 
						|
            figure_size, axes_subplot = plt.subplots(figsize=self.figsize)
 | 
						|
 | 
						|
            # building vertical bar plot
 | 
						|
            bar_1 = plt.bar(lable_values, pass_values, width, color='green')
 | 
						|
            bar_2 = plt.bar(lable_values, fail_values, width, bottom=pass_values, color='red')
 | 
						|
 | 
						|
            # inserting bar text
 | 
						|
            if len(list(self.data_set.keys())) > 10:
 | 
						|
                self.bar_text_rotation = 90
 | 
						|
                self.x_ticklabels_rotation = 90
 | 
						|
            for i, v in enumerate(pass_values):
 | 
						|
                if v != 0:
 | 
						|
                    plt.text(i + .005, v * 0.45, "%s%s" % (v, "%"), color=self.bar_text_color,
 | 
						|
                             fontweight=self.bar_font_weight,
 | 
						|
                             fontsize=self.bar_font_size, ha="center", va="center", rotation=self.bar_text_rotation)
 | 
						|
            for i, v in enumerate(fail_values):
 | 
						|
                if v != 0:
 | 
						|
                    plt.text(i + .005, v * 0.45 + pass_values[i], "%s%s" % (v, "%"), color=self.bar_text_color,
 | 
						|
                             fontweight=self.bar_font_weight, fontsize=self.bar_font_size, ha="center", va="center" ,
 | 
						|
                             rotation=self.bar_text_rotation)
 | 
						|
            plt.legend([bar_1, bar_2], self.label, title=self.legend_title, bbox_to_anchor=self.legend_bbox,
 | 
						|
                       loc=self.legend_loc)
 | 
						|
            axes_subplot.set_xticks(list(self.data_set.keys()))
 | 
						|
            axes_subplot.set_xticklabels(list(self.data_set.keys()), rotation=self.x_ticklabels_rotation)
 | 
						|
 | 
						|
        # to remove the borders
 | 
						|
        if self.remove_border:
 | 
						|
            for border in ['top', 'right', 'left', 'bottom']:
 | 
						|
                axes_subplot.spines[border].set_visible(False)
 | 
						|
                axes_subplot.yaxis.set_visible(False)
 | 
						|
 | 
						|
        plt.xlabel(self.xaxis_name)
 | 
						|
        plt.ylabel(self.yaxis_name)
 | 
						|
        plt.savefig("%s.png" % self.graph_image_name, bbox_inches="tight", dpi=96)
 | 
						|
        plt.close()
 | 
						|
        logger.debug("{}.png".format(self.graph_image_name))
 | 
						|
        if self.enable_csv:
 | 
						|
            self.lf_csv.columns = self.label
 | 
						|
            self.lf_csv.rows = self.data_set
 | 
						|
            self.lf_csv.filename = f"{self.graph_image_name}.csv"
 | 
						|
            self.lf_csv.generate_csv()
 | 
						|
        return "%s.png" % self.graph_image_name
 | 
						|
 | 
						|
 | 
						|
class lf_horizontal_stacked_graph:
 | 
						|
    def __init__(self,
 | 
						|
                 _seg=2,
 | 
						|
                 _yaxis_set=('A', 'B'),
 | 
						|
                 _xaxis_set1=None,
 | 
						|
                 _xaxis_set2=None,
 | 
						|
                 _unit="%",
 | 
						|
                 _xaxis_name="Stations",
 | 
						|
                 _label=None,
 | 
						|
                 _graph_image_name="image_name3",
 | 
						|
                 _color=None,
 | 
						|
                 _figsize=(9, 4),
 | 
						|
                 _disable_xaxis=False,
 | 
						|
                 _enable_csv=True):
 | 
						|
        if _xaxis_set1 is None:
 | 
						|
            _xaxis_set1 = [12, 0, 0, 16, 15]
 | 
						|
        if _xaxis_set2 is None:
 | 
						|
            _xaxis_set2 = [23, 34, 23, 0]
 | 
						|
        if _label is None:
 | 
						|
            _label = ['Success', 'Fail']
 | 
						|
        if _color is None:
 | 
						|
            _color = ["success", "Fail"]
 | 
						|
        self.unit = _unit
 | 
						|
        self.seg = _seg
 | 
						|
        self.xaxis_set1 = _xaxis_set1
 | 
						|
        self.xaxis_set2 = _xaxis_set2
 | 
						|
        self.yaxis_set = _yaxis_set
 | 
						|
        self.xaxis_name = _xaxis_name
 | 
						|
        self.figsize = _figsize
 | 
						|
        self.graph_image_name = _graph_image_name
 | 
						|
        self.label = _label
 | 
						|
        self.color = _color
 | 
						|
        self.disable_xaxis = _disable_xaxis
 | 
						|
        self.enable_csv = _enable_csv
 | 
						|
        self.lf_csv = lf_csv()
 | 
						|
 | 
						|
    def build_horizontal_stacked_graph(self):
 | 
						|
        def sumzip(items):
 | 
						|
            return [sum(values) for values in zip(items)]
 | 
						|
 | 
						|
        fig, ax = plt.subplots(figsize=self.figsize)
 | 
						|
 | 
						|
        n = self.seg
 | 
						|
        values1 = self.xaxis_set1
 | 
						|
        values2 = self.xaxis_set2
 | 
						|
 | 
						|
        ind = np.arange(n) + .15
 | 
						|
        width = 0.3
 | 
						|
 | 
						|
        plt.barh(
 | 
						|
            ind,
 | 
						|
            values1,
 | 
						|
            width,
 | 
						|
            color=self.color[0],
 | 
						|
            label=self.label[0])
 | 
						|
        plt.barh(
 | 
						|
            ind,
 | 
						|
            values2,
 | 
						|
            width,
 | 
						|
            left=sumzip(values1),
 | 
						|
            color=self.color[1],
 | 
						|
            label=self.label[1])
 | 
						|
 | 
						|
        extra_space = 0.15
 | 
						|
        ax.set_yticks(ind + width - extra_space)
 | 
						|
        ax.set_yticklabels(self.yaxis_set)
 | 
						|
        ax.yaxis.set_tick_params(length=0, labelbottom=True)
 | 
						|
 | 
						|
        for i, v in enumerate(values1):
 | 
						|
            if v != 0:
 | 
						|
                plt.text(v * 0.45, i + .145, "%s%s" % (v, self.unit), color='white', fontweight='bold', fontsize=10,
 | 
						|
                         ha='center', va='center')
 | 
						|
 | 
						|
        for i, v in enumerate(values2):
 | 
						|
            if v != 0:
 | 
						|
                plt.text(v * 0.45 + values1[i], i + .145, "%s%s" % (v, self.unit), color='white', fontweight='bold',
 | 
						|
                         fontsize=10,
 | 
						|
                         ha='center', va='center')
 | 
						|
 | 
						|
        ax.spines['right'].set_visible(False)
 | 
						|
        ax.spines['top'].set_visible(False)
 | 
						|
        ax.legend(loc='upper right')
 | 
						|
        if self.disable_xaxis:
 | 
						|
            plt.tick_params(
 | 
						|
                axis='x',
 | 
						|
                which='both',
 | 
						|
                bottom=False,
 | 
						|
                top=False,
 | 
						|
                labelbottom=False)  # disable x-axis
 | 
						|
        plt.savefig("%s.png" % self.graph_image_name, dpi=96)
 | 
						|
        plt.close()
 | 
						|
        logger.debug("{}.png".format(self.graph_image_name))
 | 
						|
        if self.enable_csv:
 | 
						|
            self.lf_csv.columns = self.label
 | 
						|
            self.lf_csv.rows = self.data_set
 | 
						|
            self.lf_csv.filename = f"{self.graph_image_name}.csv"
 | 
						|
            self.lf_csv.generate_csv()
 | 
						|
        return "%s.png" % self.graph_image_name
 | 
						|
 | 
						|
 | 
						|
class lf_line_graph:
 | 
						|
    def __init__(self, _data_set=None,
 | 
						|
                 _xaxis_name="x-axis",
 | 
						|
                 _yaxis_name="y-axis",
 | 
						|
                 _xaxis_categories=None,
 | 
						|
                 _xaxis_label=None,
 | 
						|
                 _graph_title="",
 | 
						|
                 _title_size=16,
 | 
						|
                 _graph_image_name="line_graph",
 | 
						|
                 _label=None,
 | 
						|
                 _font_weight='bold',
 | 
						|
                 _color=None,
 | 
						|
                 _figsize=(10, 5),
 | 
						|
                 _xaxis_step=5,
 | 
						|
                 _xticks_font=None,
 | 
						|
                 _text_font=None,
 | 
						|
                 _legend_handles=None,
 | 
						|
                 _legend_loc="best",
 | 
						|
                 _legend_box=None,
 | 
						|
                 _legend_ncol=1,
 | 
						|
                 _legend_fontsize=None,
 | 
						|
                 _marker=None,
 | 
						|
                 _dpi=96,
 | 
						|
                 _grid=True,
 | 
						|
                 _enable_csv=False,
 | 
						|
                 _reverse_x=False,
 | 
						|
                 _reverse_y=False):
 | 
						|
        if _data_set is None:
 | 
						|
            _data_set = [[30.4, 55.3, 69.2, 37.1, 44.0], [45.1, 67.2, 34.3, 22.4, 37.6], [22.5, 45.6, 12.7, 34.8, 22.5]]
 | 
						|
        if _xaxis_categories is None:
 | 
						|
            _xaxis_categories = [1, 2, 3, 4, 5]
 | 
						|
        if _xaxis_label is None:
 | 
						|
            _xaxis_label = ["a", "b", "c", "d", "e"]
 | 
						|
        if _label is None:
 | 
						|
            _label = ["bi-downlink", "bi-uplink", 'uplink']
 | 
						|
        if _color is None:
 | 
						|
            _color = ['forestgreen', 'c', 'r', 'g', 'b', 'p']
 | 
						|
        if _marker is None:
 | 
						|
            _marker = ['s', 'o', 'v']  # available markers =  '.', 'o', 'v', '<', 's', '*', 'p', 'P'
 | 
						|
        self.grid = _grid
 | 
						|
        self.data_set = _data_set
 | 
						|
        self.xaxis_name = _xaxis_name
 | 
						|
        self.yaxis_name = _yaxis_name
 | 
						|
        self.xaxis_categories = _xaxis_categories
 | 
						|
        self.xaxis_label = _xaxis_label
 | 
						|
        self.grp_title = _graph_title
 | 
						|
        self.title_size = _title_size
 | 
						|
        self.graph_image_name = _graph_image_name
 | 
						|
        self.label = _label
 | 
						|
        self.color = _color
 | 
						|
        self.font_weight = _font_weight
 | 
						|
        self.figsize = _figsize
 | 
						|
        self.xaxis_step = _xaxis_step
 | 
						|
        self.xticks_font = _xticks_font
 | 
						|
        self.text_font = _text_font
 | 
						|
        self.marker = _marker
 | 
						|
        self.enable_csv = _enable_csv
 | 
						|
        self.lf_csv = lf_csv()
 | 
						|
        self.legend_handles = _legend_handles
 | 
						|
        self.legend_loc = _legend_loc
 | 
						|
        self.legend_box = _legend_box
 | 
						|
        self.legend_ncol = _legend_ncol
 | 
						|
        self.legend_fontsize = _legend_fontsize
 | 
						|
        self.reverse_x = _reverse_x
 | 
						|
        self.reverse_y = _reverse_y
 | 
						|
 | 
						|
    def build_line_graph(self):
 | 
						|
        plt.subplots(figsize=self.figsize)
 | 
						|
        i = 0
 | 
						|
        for data in self.data_set:
 | 
						|
            plt.plot(
 | 
						|
                self.xaxis_categories,
 | 
						|
                data,
 | 
						|
                color=self.color[i],
 | 
						|
                label=self.label[i],
 | 
						|
                marker=self.marker[i])
 | 
						|
            i += 1
 | 
						|
 | 
						|
        plt.xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        plt.ylabel(self.yaxis_name, fontweight='bold', fontsize=15)
 | 
						|
        if self.grid:
 | 
						|
            plt.grid(True, linestyle=':')  # available line styles = ':', '-', '--', '-.'
 | 
						|
        plt.legend(
 | 
						|
            handles=self.legend_handles,
 | 
						|
            loc=self.legend_loc,
 | 
						|
            bbox_to_anchor=self.legend_box,
 | 
						|
            ncol=self.legend_ncol,
 | 
						|
            fontsize=self.legend_fontsize)
 | 
						|
        plt.suptitle(self.grp_title, fontsize=self.title_size)
 | 
						|
        if self.reverse_y:
 | 
						|
            plt.gca().invert_yaxis()
 | 
						|
        if self.reverse_x:
 | 
						|
            plt.gca().invert_xaxis()
 | 
						|
        plt.gcf()
 | 
						|
        plt.savefig("%s.png" % self.graph_image_name, dpi=96)
 | 
						|
        plt.close()
 | 
						|
        logger.debug("{}.png".format(self.graph_image_name))
 | 
						|
        if self.enable_csv:
 | 
						|
            if self.data_set is not None:
 | 
						|
                self.lf_csv.columns = self.label
 | 
						|
                self.lf_csv.rows = self.data_set
 | 
						|
                self.lf_csv.filename = f"{self.graph_image_name}.csv"
 | 
						|
                self.lf_csv.generate_csv()
 | 
						|
            else:
 | 
						|
                logger.debug("No Dataset Found")
 | 
						|
        logger.debug("{}.csv".format(self.graph_image_name))
 | 
						|
        return "%s.png" % self.graph_image_name
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    help_summary = '''\
 | 
						|
     This script facilitates the generation of comprehensive graphical reports. It offers a variety of graph types, 
 | 
						|
     including bar graphs, horizontal bar graphs, scatter graphs, bar-line graphs, stacked graphs, horizontal stacked 
 | 
						|
     graphs, and line graphs. 
 | 
						|
    '''
 | 
						|
    # arguments
 | 
						|
    parser = argparse.ArgumentParser(
 | 
						|
        prog='lf_graph.py',
 | 
						|
        formatter_class=argparse.RawTextHelpFormatter,
 | 
						|
        epilog='''\
 | 
						|
            lf_graph.py : unit test in lf_graph.py for exersizing the lf_graph.py library
 | 
						|
            ''',
 | 
						|
        description='''\
 | 
						|
-----------------
 | 
						|
NAME: lf_graph.py
 | 
						|
 | 
						|
PURPOSE:
 | 
						|
Common Library for generating graphs for LANforge output
 | 
						|
 | 
						|
SETUP:
 | 
						|
/lanforge/html-reports directory needs to be present or output generated in local file
 | 
						|
 | 
						|
EXAMPLE:
 | 
						|
see: /py-scritps/lf_report_test.py for example
 | 
						|
 | 
						|
COPYWRITE
 | 
						|
    Copyright 2021 Candela Technologies Inc
 | 
						|
    License: Free to distribute and modify. LANforge systems must be licensed.
 | 
						|
 | 
						|
INCLUDE_IN_README
 | 
						|
---------------------
 | 
						|
            ''')
 | 
						|
    parser.add_argument(
 | 
						|
        '--mgr',
 | 
						|
        '--lfmgr',
 | 
						|
        dest='lfmgr',
 | 
						|
        help='sample argument: where LANforge GUI is running',
 | 
						|
        default='localhost')
 | 
						|
    # logging configuration
 | 
						|
    parser.add_argument(
 | 
						|
        '--debug',
 | 
						|
        help='--debug this will enable debugging in py-json method',
 | 
						|
        action='store_true')
 | 
						|
    parser.add_argument('--log_level',
 | 
						|
                        default=None,
 | 
						|
                        help='Set logging level: debug | info | warning | error | critical')
 | 
						|
 | 
						|
    parser.add_argument(
 | 
						|
        "--lf_logger_config_json",
 | 
						|
        help="--lf_logger_config_json <json file> , json configuration of logger")
 | 
						|
 | 
						|
    parser.add_argument('--help_summary', help='Show summary of what this script does', default=None,
 | 
						|
                        action="store_true")
 | 
						|
 | 
						|
    # the args parser is not really used , this is so the report is not generated when testing
 | 
						|
    # the imports with --help
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
    if args.help_summary:
 | 
						|
        print(help_summary)
 | 
						|
        exit(0)
 | 
						|
 | 
						|
    # set up logger
 | 
						|
    logger_config = lf_logger_config.lf_logger_config()
 | 
						|
 | 
						|
    # set the logger level to debug
 | 
						|
    if args.log_level:
 | 
						|
        logger_config.set_level(level=args.log_level)
 | 
						|
 | 
						|
    # lf_logger_config_json will take presidence to changing debug levels
 | 
						|
    if args.lf_logger_config_json:
 | 
						|
        # logger_config.lf_logger_config_json = "lf_logger_config.json"
 | 
						|
        logger_config.lf_logger_config_json = args.lf_logger_config_json
 | 
						|
        logger_config.load_lf_logger_config()
 | 
						|
 | 
						|
    logger.debug("LANforge manager {lfmgr}".format(lfmgr=args.lfmgr))
 | 
						|
 | 
						|
    output_html_1 = "graph_1.html"
 | 
						|
    output_pdf_1 = "graph_1.pdf"
 | 
						|
 | 
						|
    # test build_bar_graph with defaults
 | 
						|
    graph = lf_bar_graph()
 | 
						|
    graph_html_obj = """
 | 
						|
        <img align='center' style='padding:15;margin:5;width:1000px;' src=""" + "%s" % (graph.build_bar_graph()) + """ border='1' />
 | 
						|
        <br><br>
 | 
						|
        """
 | 
						|
    #
 | 
						|
    test_file = open(output_html_1, "w")
 | 
						|
    test_file.write(graph_html_obj)
 | 
						|
    test_file.close()
 | 
						|
 | 
						|
    # write to pdf
 | 
						|
    # write logic to generate pdf here
 | 
						|
    # wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
 | 
						|
    # sudo apt install ./wkhtmltox_0.12.6-1.focal_amd64.deb
 | 
						|
    # prevent eerror Blocked access to file
 | 
						|
    options = {"enable-local-file-access": None}
 | 
						|
    pdfkit.from_file(output_html_1, output_pdf_1, options=options)
 | 
						|
 | 
						|
    # test build_bar_graph setting values
 | 
						|
    dataset = [[45, 67, 34, 22], [22, 45, 12, 34], [30, 55, 69, 37]]
 | 
						|
    x_axis_values = [1, 2, 3, 4]
 | 
						|
 | 
						|
    output_html_2 = "graph_2.html"
 | 
						|
    output_pdf_2 = "graph_2.pdf"
 | 
						|
 | 
						|
    # test build_bar_graph with defaults
 | 
						|
    graph = lf_bar_graph(_data_set=dataset,
 | 
						|
                         _xaxis_name="stations",
 | 
						|
                         _yaxis_name="Throughput 2 (Mbps)",
 | 
						|
                         _xaxis_categories=x_axis_values,
 | 
						|
                         _graph_image_name="Bi-single_radio_2.4GHz",
 | 
						|
                         _label=["bi-downlink", "bi-uplink", 'uplink'],
 | 
						|
                         _color=None,
 | 
						|
                         _color_edge='red',
 | 
						|
                         _show_bar_value=True,
 | 
						|
                         _text_font=7,
 | 
						|
                         _text_rotation=None,
 | 
						|
                         _enable_csv=True)
 | 
						|
    graph_html_obj = """
 | 
						|
        <img align='center' style='padding:15;margin:5;width:1000px;' src=""" + "%s" % (graph.build_bar_graph()) + """ border='1' />
 | 
						|
        <br><br>
 | 
						|
        """
 | 
						|
    #
 | 
						|
    test_file = open(output_html_2, "w")
 | 
						|
    test_file.write(graph_html_obj)
 | 
						|
    test_file.close()
 | 
						|
 | 
						|
    graph = lf_line_graph()
 | 
						|
 | 
						|
    graph.build_line_graph()
 | 
						|
 | 
						|
    # write to pdf
 | 
						|
    # write logic to generate pdf here
 | 
						|
    # wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
 | 
						|
    # sudo apt install ./wkhtmltox_0.12.6-1.focal_amd64.deb
 | 
						|
    # prevent eerror Blocked access to file
 | 
						|
    options = {"enable-local-file-access": None}
 | 
						|
    pdfkit.from_file(output_html_2, output_pdf_2, options=options)
 | 
						|
 | 
						|
    # test build_bar_graph_horizontal with defaults
 | 
						|
    dataset = [[45, 67, 34, 22, 31, 52, 60, 71, 24, 25, 45, 67, 34, 22, 31, 52, 60, 71, 24, 25], [22, 45, 12, 34, 70, 80, 14, 35, 44, 45,22, 45, 12, 34, 70, 80, 14, 35, 44, 45 ], [30, 55, 69, 37, 77, 24, 25, 77, 77, 80, 30, 55, 69, 37, 77, 24, 25, 77, 77, 80]]
 | 
						|
    y_axis_values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
 | 
						|
 | 
						|
    # calculate the height of the y-axis .25 * number of values
 | 
						|
    y_fig_size = len(y_axis_values) * len(dataset) * .35
 | 
						|
    x_fig_size = 10
 | 
						|
 | 
						|
    output_html_3 = "graph_3.html"
 | 
						|
    output_pdf_3 = "graph_3.pdf"
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    graph = lf_bar_graph_horizontal(_data_set=dataset,
 | 
						|
                         _xaxis_name="Throughput 2 (Mbps)",
 | 
						|
                         _yaxis_name="stations",
 | 
						|
                         _yaxis_categories=y_axis_values,
 | 
						|
                         _graph_image_name="Bi-single_radio_2.4GHz",
 | 
						|
                         _label=["bi-downlink", "bi-uplink", 'uplink'],
 | 
						|
                         _color=None,
 | 
						|
                         _color_edge='red',
 | 
						|
                         _figsize=(x_fig_size, y_fig_size),
 | 
						|
                         _show_bar_value= True,
 | 
						|
                        _text_font=6,
 | 
						|
                        _text_rotation=True,
 | 
						|
                        _enable_csv=True)
 | 
						|
    graph_html_obj = """
 | 
						|
        <img align='center' style='padding:15;margin:5;width:1000px;' src=""" + "%s" % (graph.build_bar_graph_horizontal()) + """ border='1' />
 | 
						|
        <br><br>
 | 
						|
        """
 | 
						|
    #
 | 
						|
    test_file = open(output_html_3, "w")
 | 
						|
    test_file.write(graph_html_obj)
 | 
						|
    test_file.close()
 | 
						|
 | 
						|
    # write to pdf
 | 
						|
    # write logic to generate pdf here
 | 
						|
    # wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
 | 
						|
    # sudo apt install ./wkhtmltox_0.12.6-1.focal_amd64.deb
 | 
						|
    # prevent eerror Blocked access to file
 | 
						|
    options = {"enable-local-file-access": None}
 | 
						|
    pdfkit.from_file(output_html_3, output_pdf_3, options=options)
 | 
						|
 | 
						|
 | 
						|
# Unit Test
 | 
						|
if __name__ == "__main__":
 | 
						|
    main()
 |