├── setup.cfg ├── Engezny ├── __init__.py └── Engezny.py ├── LICENSE ├── setup.py └── README.md /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md -------------------------------------------------------------------------------- /Engezny/__init__.py: -------------------------------------------------------------------------------- 1 | from Engezny.Engezny import Engezny -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Mohammed Saleh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | with open('README.md') as f: 4 | long_description = f.read() 5 | 6 | setup( 7 | name = 'Engezny', # How you named your package folder (MyLib) 8 | packages = ['Engezny'], # Chose the same as "name" 9 | version = '1.3', # Start with a small number and increase it with every change you make 10 | license='MIT', # Chose a license from here: https://help.github.com/articles/licensing-a-repository 11 | description = 'Quick generation for charts from DataFrame', # Give a short description about your library 12 | long_description = long_description, 13 | long_description_content_type='text/markdown', 14 | author = 'Mohammed Saleh', # Type in your name 15 | author_email = 'MohammedSaleh@ieee.org', # Type in your E-Mail 16 | url = 'https://github.com/MDSH14', # Provide either the link to your github or to your website 17 | download_url = 'https://github.com/MDSH14/Engezny/archive/refs/tags/1.3.tar.gz', # I explain this later on 18 | keywords = ['Analysis', 'Data', 'Charts'], # Keywords that define your package best 19 | install_requires=[ # I get to this in a second 20 | 'numpy', 21 | 'pandas', 22 | 'python-bidi', 23 | 'arabic_reshaper', 24 | 'matplotlib', 25 | 'pillow' 26 | ], 27 | classifiers=[ 28 | 'Development Status :: 4 - Beta', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package 29 | 'Intended Audience :: Developers', # Define that your audience are developers 30 | 'Topic :: Software Development :: Build Tools', 31 | 'License :: OSI Approved :: MIT License', # Again, pick a license 32 | 'Programming Language :: Python :: 3', #Specify which pyhton versions that you want to support 33 | 'Programming Language :: Python :: 3.4', 34 | 'Programming Language :: Python :: 3.5', 35 | 'Programming Language :: Python :: 3.6', 36 | ], 37 | ) 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Engezny 2 | [![](https://img.shields.io/github/license/sourcerer-io/hall-of-fame.svg?colorB=ff0000)](https://github.com/akshaybahadur21/Facial-Recognition-using-Facenet/blob/master/LICENSE.txt) [![](https://img.shields.io/badge/Mohammed-Saleh-org.svg?colorB=ff0000)](https://mohammedsaleh.org/programming) 3 | 4 | ***Engezny*** is a python package that quickly generates all possible charts from your dataframe and save them for you, and engezny is only supporting now uniparameter visualization using the pie, bar and barh visualizations. 5 | 6 | ## New release features: 7 | 1. Full control with colors used in charts. 8 | 2. Arabic issues solved. 9 | 4. Base of data control. 10 | 5. Issues solved with saving charts. 11 | 6. New list of options which make your customization easier (Check them in parameters). 12 | 13 | ## Advanteges 14 | 1. Totally supports Arabic Language. 15 | 2. Handles multi-parameters columns and separates them by a comma. 16 | 3. The output charts are fully descriptive. 17 | 18 | ## Installation Guide 19 | To install ***Engezny*** Package: 20 | - Make sure python3 and pip is installed in your machine. 21 | - Use the command line and type: `pip install Engezny` or `pip3 install Engezny` 22 | - You can check if the package is installed by typing: `pip freeze | grep Engezny` or `pip3 freeze | grep Engezny` 23 | 24 | ## How to Use? 25 | The most simple format of using ***Engezny*** is as follow: 26 | ```python 27 | from Engezny import Engezny 28 | import pandas as pd 29 | 30 | Data = pd.read_csv("FileName.csv") 31 | Egz = Engezny(Data) 32 | Egz.visualize() 33 | ``` 34 | 35 | ## Visualization Parameters 36 | - `start (int) default = 0`: The first column to start with index 37 | - `end (int) default = None`: The final column to end with index 38 | - `location (str) default ='Charts/'`: The file location to save charts in. The package creates the file if not exsist 39 | - `extention (str) default = 'jpg'`: The extention of the created charts 40 | - `colors (list) default = None`: A list of colors HEX codes to use in charts 41 | - `save (bool) default = True`: The save option to save generated charts to the local machine 42 | - `multi_sep (str) default = None`: the separator delimiter for multiselection columns 43 | - `single_sep (str) default = None`: A delimiter to split single values with 44 | - `figsize (tuple) default = (15, 15)`: The figure size of charts 45 | - `base (str) default = 'total_values'`: The base to use in charts. Makes a difference with multiselection columns and has three available options: 46 | - `'total_values'`: Uses the sum of total values as a base 47 | - `'data_base'`: Uses the total number of rows in data as a base 48 | - `'column_base'`: Uses the count of non-null cells in the column as a base 49 | - `other (bool) default = False` The other option takes only the top 4 values and combine the rest in and other value 50 | -------------------------------------------------------------------------------- /Engezny/Engezny.py: -------------------------------------------------------------------------------- 1 | from bidi.algorithm import get_display 2 | import arabic_reshaper 3 | import matplotlib 4 | import matplotlib.pyplot as plt 5 | import pandas as pd 6 | import os 7 | class Engezny: 8 | def __init__(self, DataFrame): 9 | self.DataFrame = DataFrame 10 | 11 | def __labelcolor(self, colors): 12 | rgb = [tuple(int(item.lstrip('#')[i:i+2], 16) for i in (0, 2, 4)) for item in colors] 13 | return ["white" if (0.2126*item[0] + 0.7152*item[1] + 0.0722*item[2]) < 128 else "black" for item in rgb] 14 | 15 | def __value_counts(self, Data, multi_sep=None, single_sep=None): 16 | if multi_sep == None and single_sep == None: 17 | return dict(Data.value_counts()) 18 | Dict = dict() 19 | try: 20 | for i in Data.dropna().index: 21 | Words = str(Data[i]).split(multi_sep) 22 | for Word in Words: 23 | if single_sep != None: 24 | Word = Word.split(single_sep)[0].strip() 25 | else: 26 | Word = Word.strip() 27 | if Word in Dict.keys(): 28 | Dict[Word] += 1 29 | else: 30 | Dict[Word] = 1 31 | except: 32 | return "Error" 33 | return dict(sorted(Dict.items(), key=lambda item: item[1], reverse=True)) 34 | 35 | 36 | def __save(self, location, Count, extention, item): 37 | Title = '{}'.format(item).title() 38 | Title = ''.join(e for e in Title if e.isalnum()) 39 | try: 40 | os.mkdir(location) 41 | except: 42 | pass 43 | plt.savefig('{}{}. {}.{}'.format(location, Count, Title, extention), bbox_inches='tight', transparent=True); 44 | 45 | 46 | def visualize(self, 47 | start= 0, 48 | end = None, 49 | location = 'Charts/', 50 | extention = 'jpg', 51 | colors = ['#1f77b4', 52 | '#ff7f0e', 53 | '#2ca02c', 54 | '#d62728', 55 | '#9467bd', 56 | '#8c564b', 57 | '#e377c2', 58 | '#7f7f7f', 59 | '#bcbd22', 60 | '#17becf'], 61 | save=True, 62 | multi_sep=None, 63 | single_sep=None, 64 | figsize=(15, 15), 65 | base = 'total_values', 66 | other= False): 67 | Count = 1 68 | for item in list(self.DataFrame)[start:end]: 69 | Dict = self.__value_counts(self.DataFrame[item], multi_sep, single_sep) 70 | if Dict == "Error": 71 | continue 72 | 73 | if other: 74 | if len(Dict) > 5: 75 | Tot = sum(Dict.values()) 76 | Dict = dict(list(Dict.items())[:4]) 77 | Dict['Other'] = Tot - sum(Dict.values()) 78 | 79 | Keys = list() 80 | for Key in Dict.keys(): 81 | Keys.append(get_display(arabic_reshaper.reshape(str(Key)))) 82 | Values = list(Dict.values()) 83 | 84 | labels = [] 85 | if not other: 86 | if base == 'total_values': 87 | Tot = sum(Values) 88 | elif base == "data_base": 89 | Tot = len(self.DataFrame) 90 | elif base == "column_base": 91 | Tot = len(self.DataFrame[item].dropna()) 92 | else: 93 | raise ValueError('Unknown base !') 94 | 95 | for i in Values: 96 | labels.append("{}/{} ({}%)".format(i, Tot, int((i/Tot)*100))) 97 | 98 | matplotlib.rcParams.update({'font.size': 25}) 99 | f, ax = plt.subplots(figsize=figsize) 100 | 101 | if len(Keys) <= 5 and base == 'total_values': 102 | for i in range(len(Keys)): 103 | Keys[i] += " (" + labels[i].split()[0] + ")" 104 | 105 | _, _, autotexts = plt.pie(Values, labels=["" for k in Keys], autopct="%.1f%%", colors=colors) 106 | for color, autotext in zip(self.__labelcolor(colors), autotexts): 107 | autotext.set_color(color) 108 | plt.legend(loc = 'lower center', bbox_to_anchor=(0.25, -0.1, 0.5, 0.5), labels = Keys) 109 | 110 | elif len(Keys) < 8: 111 | for i, v in enumerate(labels): 112 | ax.text(i-0.5, Values[i], str(v), fontsize=25) 113 | 114 | plt.bar(Keys, Values, color=colors[0]) 115 | plt.xticks(rotation = 90) 116 | 117 | else: 118 | Keys.reverse() 119 | Values.reverse() 120 | labels.reverse() 121 | if len(Keys) > 20: 122 | for i, v in enumerate(labels[-20:]): 123 | ax.text(Values[-20:][i], i, str(v), fontsize=25) 124 | plt.barh(Keys[-20:], Values[-20:], color=colors[0]) 125 | else: 126 | for i, v in enumerate(labels): 127 | ax.text(Values[i], i, str(v), fontsize=25) 128 | plt.barh(Keys, Values, color=colors[0]) 129 | 130 | plt.title(get_display(arabic_reshaper.reshape(item.title())), fontsize=35) 131 | if save: 132 | self.__save(location, Count, extention, item) 133 | plt.show() 134 | Count += 1 135 | --------------------------------------------------------------------------------