From aabd9fad151321f8f7c12ca56734c80288cfdc4c Mon Sep 17 00:00:00 2001 From: GaoDechen Date: Fri, 16 Aug 2024 23:53:19 -0700 Subject: [PATCH] Update toolki --- car_dreamer/toolkit/visualization/bar.py | 556 ---------------------- car_dreamer/toolkit/visualization/line.py | 543 --------------------- 2 files changed, 1099 deletions(-) delete mode 100644 car_dreamer/toolkit/visualization/bar.py delete mode 100644 car_dreamer/toolkit/visualization/line.py diff --git a/car_dreamer/toolkit/visualization/bar.py b/car_dreamer/toolkit/visualization/bar.py deleted file mode 100644 index 3895346..0000000 --- a/car_dreamer/toolkit/visualization/bar.py +++ /dev/null @@ -1,556 +0,0 @@ -# import python data analysis library numpy and pandas -import argparse -from importlib.resources import path -# import module to read files -import mimetypes -import os -import urllib - -import matplotlib.font_manager -# import data visualization library matplotlib and seaborn -import matplotlib.pyplot as plt -import matplotlib.ticker as ticker -import numpy as np -import pandas as pd -import seaborn as sns -from seaborn.utils import relative_luminance - -parser = argparse.ArgumentParser() -parser.add_argument('--isframe', action='store_true') -parser.add_argument('--type', type=str, default='group') -parser.add_argument('--title', type=str, default='') -parser.add_argument('--title_pad', type=int, default=10) -parser.add_argument('--title_size', type=int, default=20) -parser.add_argument('--title_loc', type=str, default='center') -parser.add_argument('--legend_label', type=str, default='') -parser.add_argument('--plotwidth', type=int, default=10) -parser.add_argument('--plothight', type=int, default=6) -parser.add_argument('--line', type=int, default=1) -parser.add_argument('--valueformat', type=str, default='{:.0f}') -parser.add_argument('--bar_width', type=float, default=0.2) -parser.add_argument('--xax_length', type=int, default=1) -parser.add_argument('--yax_length', type=int, default=1) -parser.add_argument('--valuepad', type=int, default=1) -parser.add_argument('--err_series', type=str, default='') -parser.add_argument('--xtick_loc', type=int, default=1) -parser.add_argument('--ytick_loc', type=int, default=5) -parser.add_argument('--tick_labels', type=str, default='') -parser.add_argument('--tick_direction', type=str, default='out') -parser.add_argument('--fontfamily', type=str, default='sans') -parser.add_argument('--axfont_size', type=int, default=17) -parser.add_argument('--valuefont_size', type=int, default=13) -parser.add_argument('--tickfont_size', type=int, default=13) -parser.add_argument('--legfont_size', type=int, default=14) -parser.add_argument('--labelpad', type=int, default=10) -parser.add_argument('--fontsize', type=int, default=18) -parser.add_argument('--legendcol', type=int, default=1) -parser.add_argument('--legend_loc', type=str, default='upper right') -parser.add_argument('--gridline_width', type=float, default=0.2) -parser.add_argument('--colors', type=str, default='1'*50) -parser.add_argument('--bar_color', type=list, default=['#7173A9','#E8AA78','#E2918F','#629DDD', - '#A4BF7F','#A5D7D8','#A48BC1','#F4D470']) -parser.add_argument('--axis_color', type=str, default='0') -parser.add_argument('--grid_color', type=str, default='grey') -parser.add_argument('--edge_color', type=str, default='0') -parser.add_argument('--font_color', type=str, default='0') -parser.add_argument('--patterns', type=str, default=' '*50) -parser.add_argument('--bar_pattern', type=str, default='0') -parser.add_argument('--eline_width', type=float, default=0.7) -parser.add_argument('--line_width', type=int, default=1) - -parser.add_argument('--cap_size', type=int, default=0) -parser.add_argument('--cap_thick', type=int, default=1) -parser.add_argument('--is_save_fig', action='store_true') -parser.add_argument('--save_image', type=str, default='bar.pdf') -parser.add_argument('--show_value',action='store_false') -column_conf = parser.parse_args() -# import google colab to use google colab as editor -# if you use other editor, do not need to import google.colab here -#from google.colab import drive -#drive.mount('/content/drive', force_remount = True) -## setting path -# get current path -path_current = os.getcwd() -# the path is where the dataset saved -path = path_current + '/Example_Data/Bar/' -# the "path_img" is the position where final image will be saved -path_img = path_current + '/Images/' -class bar_chart: - - def __init__(self, y_series = '', path=path,path_img=path_img, label_list = '', - x_series = ''): - self.y_series = y_series - self.x_series = x_series - self.path=path - self.path_img=path_img - - ## read file function: read three kinds of format file csv/excel/text - # if you have other format of file, please change the function manually - # file: str, filename (e.g.'Vertical_Bar.txt') - def checkitem(self,conf): - if conf['type'] not in ['single','group']: - raise TypeError(f'the value of the type must be "single" or "group" !') - if conf['title_loc'] not in ['center','left','right']: - raise TypeError(f'the value of the title_loc must be "center","left", or "right"!') - if conf['tick_direction'] not in ['out','in','inout']: - raise TypeError(f'the value of the tick_direction must be "out","in", or "inout"!') - if conf['legend_loc'] not in ['best','upper right','upper left','lower left','lower right','right','center left','center right' - ,'lower center','upper center','center']: - raise TypeError(f'the value of the legend_loc must be "best","upper right","upper left",...!') - - - def read_file(self,file): - file_url = urllib.request.pathname2url(file) - ftype = mimetypes.guess_type(file_url, strict = True)[0] - ## read data file according to format, default file types: csv/excel/text - # read csv format data - if 'csv' in ftype: - data = pd.read_csv(self.path + file,index_col=0 ) - # read excel format data - elif 'sheet' in ftype: - data = pd.read_excel(self.path + file,index_col=0 ) - # read text format data - elif ftype == 'text/plain': - data = pd.read_csv(self.path + file, sep="\t") - elif 'excel' in ftype: - data = pd.read_csv(self.path + file,index_col=0 ) - else: - print("Cannot read file, change file type.") - return data - - def BarColor(self): - ## create example figure - fig = plt.figure(figsize = (conf['plotwidth'], conf['plotheight'])) - ax = fig.add_subplot(111) - - ## format ticks - # MultipleLocator: locates ticks at a multiple of the number provided - ax.xaxis.set_major_locator(ticker.MultipleLocator(1)) - ax.yaxis.set_major_locator(ticker.MultipleLocator(0.5)) - - ## set the ticks position - ax.xaxis.set_ticks_position('bottom') - # {'top', 'bottom', 'both', 'default', 'none'} - - ## draw example bar plot - for i in range(len(conf['colors'])): - ax.bar(i, 3, color= conf['colors'][i], edgecolor='black') - - ## show color match - plt.show() - - def BarPattern(self): - ## create example figure - fig = plt.figure(figsize = (conf['plotwidth'], conf['plotheight'])) - ax = fig.add_subplot(111) - - ## format ticks - # MultipleLocator: locates ticks at a multiple of the number you provide - ax.xaxis.set_major_locator(ticker.MultipleLocator(1)) - ax.yaxis.set_major_locator(ticker.MultipleLocator(0.5)) - - ## set the ticks position - ax.xaxis.set_ticks_position('bottom') - # {'top', 'bottom', 'both', 'default', 'none'} - - ## draw example bar plot - for i in range(len(conf['patterns'])): - ax.bar(i, 3, color='white', edgecolor='black', hatch=conf['patterns'][i]) - - ## show hatch patterns - plt.show() - - def Bar(self, file, x_col_name, y_col_name, x_label, y_label, direction, **kwargs): - - - conf = vars(column_conf) - self.checkitem(conf) - # elif paper_type == 'double': - # conf = double_column_conf - - # when new configuraton is set, update the original one - conf.update(kwargs) - - # conf['err_series'] - - ## set font dictionary - font_dict = {'family': conf['fontfamily'], - 'color': conf['font_color']} - - ## read file - data = self.read_file(file) - - ## create figure and set figure size - fig, ax = plt.subplots(figsize = (conf['plotwidth'], conf['plothight'])) - - - ## add axes and format axes - ax = fig.add_axes([0, 0, conf['xax_length'], conf['yax_length']]) - # The dimensions [left, bottom, width, height] of the new axes (range 0 to 1) - # All quantities are in fractions of figure width and height. - - ## plot size changes according to figure size and the width,height of axes - - if conf['type']=='single': - - ## draw vertical bar plot - # edgecolor: The colors of the bar edges. - # linewidth: Width of the bar edge(s). If 0, don't draw edges. - # color: The colors of the bar faces. Default setting 'C0'. - categories = [] - ticklabel_list = [0] - for x, v in enumerate(list(data[x_col_name])): - categories.append(x + 1.0) - ticklabel_list.append(v) - # choose the direction of bar: 'vertical' or 'horizontal' - - if direction == 'vertical': - rectobj = ax.bar(x=categories, height=data[y_col_name], width=conf['bar_width'], - data=data, label=conf['legend_label'],edgecolor=conf['edge_color'], - linewidth=conf['line_width'], color=conf['bar_color'], hatch=conf['bar_pattern']) - elif direction == 'horizontal': - rectobj = ax.barh(y=data[y_col_name], height=conf['bar_width'], width=data[x_col_name], - data=data, label=conf['legend_label'], edgecolor=conf['edge_color'], - linewidth=conf['line_width'], color=conf['bar_color'], hatch=conf['bar_pattern']) - - ## format axes spines - ## remove top and right spines - ## set color of left and bottom axes spines - # if False, top and right borders removing - if conf['isframe'] == False: - ax.spines['top'].set_visible(False) - ax.spines['right'].set_visible(False) - - ## format ticks - # MultipleLocator: locates ticks at a multiple of the number you provide - ax.xaxis.set_major_locator(ticker.MultipleLocator(conf['xtick_loc'])) - ax.yaxis.set_major_locator(ticker.MultipleLocator(conf['ytick_loc'])) - - ## set x, y tick's direction, default:out, can be set to in,out,inout - if conf['tick_direction'] == 'in': - matplotlib.rcParams['xtick.direction'] = 'in' - matplotlib.rcParams['ytick.direction'] = 'in' - elif conf['tick_direction'] == 'inout': - matplotlib.rcParams['xtick.direction'] = 'inout' - matplotlib.rcParams['ytick.direction'] = 'inout' - elif conf['tick_direction'] == 'out': - matplotlib.rcParams['xtick.direction'] = 'out' - matplotlib.rcParams['ytick.direction'] = 'out' - - ## format the tick color and tick labels - # color: the color of ticks - # labelsize: the font size of tick labels - # labelcolor: the color of tick labels - ax.tick_params(color = conf['axis_color'], labelsize = conf['tickfont_size'], labelcolor = conf['font_color']) - - if direction == 'vertical': - if conf['tick_labels'] == '': - ax.set_xticklabels(ticklabel_list) - else: - ax.set_xticklabels(conf['tick_labels']) - ## add background grid - ax.yaxis.grid(linestyle="--",color='gray', linewidth = conf['gridline_width'], alpha = 0.5) - # alpha: adjust the transparency - - elif direction == 'horizontal': - if conf['tick_labels']=='': - ax.set_yticklabels(ticklabel_list) - else: - ax.set_yticklabels(conf['tick_labels']) - ## add background grid - ax.xaxis.grid(linestyle="--",color='gray', linewidth = conf['gridline_width'], alpha = 0.5) - # alpha: adjust the transparency - - elif conf['type']=='group': - - - # number of groups - - - if direction == 'vertical': - # set location of bars on x-axis - # initialise list - conf['legend_label']=y_col_name - - n_groups = len(y_col_name) - xloc_list = [0]*n_groups - xloc = np.arange(len(x_col_name)) - for i in range(n_groups): - xloc_list[i] = [x + i*conf['bar_width'] for x in xloc] - - rectobj_list = [0] * n_groups - - ## draw bars - for i in range(n_groups): - if conf['err_series'] == '': - rectobj_list[i] = ax.bar(x=xloc_list[i], height=data[y_col_name[i]], width=data[y_col_name[i]], - color = conf['bar_color'][i], edgecolor = conf['edge_color'], - linewidth = conf['line_width'],label = conf['legend_label'][i]) - else: - err = data[conf['err_series'][i]].tolist() - rectobj_list[i] = ax.bar(x=xloc_list[i], height=data[y_col_name[i]], width=data[y_col_name[i]], - yerr=err, color=conf['bar_color'][i], - edgecolor = conf['edge_color'], linewidth = conf['line_width'], - label = conf['legend_label'][i], capsize = conf['cap_size'], - error_kw = {'elinewidth': conf['eline_width'], 'capthick': conf['eline_width']}) - - elif direction == 'horizontal': - ## set locations for the bars on y axis - # initialise list - conf['legend_label']=x_col_name - n_groups = len(x_col_name) - yloc_list=[0]*n_groups - yloc = np.arange(len(y_col_name)) - for i in range(n_groups): - yloc_list[i]=[y + i*conf['bar_width'] for y in yloc] - - rectobj_list = [0] * n_groups - ## draw grouped bars - for i in range(n_groups): - if conf['err_series']=='': - rectobj_list[i] = ax.barh(y=yloc_list[i], height=conf['bar_width'], width=data[x_col_name[i]], - color=conf['bar_color'][i], edgecolor=conf['edge_color'], linewidth=conf['line_width'], - label=conf['legend_label'][i]) - - else: - err=data[conf['err_series'][i]].tolist() - rectobj_list[i] = ax.barh(y=yloc_list[i], height=conf['bar_width'], width=data[x_col_name[i]], - xerr = err, color = conf['bar_color'][i], edgecolor = conf['edge_color'], - linewidth = conf['line_width'], label=conf['legend_label'][i], - capsize = conf['cap_size'], error_kw = {'elinewidth': conf['eline_width'],'capthick': conf['eline_width']}) - - - - ## format axes spines - ## remove top and right spines - ## set color of left and bottom axes spines - - if conf['isframe'] == False: - ax.spines['top'].set_visible(False) - ax.spines['right'].set_visible(False) - - - ## format ticks - # MultipleLocator: locates ticks at a multiple of the number you provide - ax.xaxis.set_major_locator(ticker.MultipleLocator(conf['xtick_loc'])) - ax.yaxis.set_major_locator(ticker.MultipleLocator(conf['ytick_loc'])) - - if direction == 'vertical': - - ## adjust the location of xticks label - if conf['tick_labels'] == '': - plt.xticks([x + conf['bar_width']*0.5*(n_groups-1) for x in range(len(data[x_col_name]))], data[x_col_name].tolist()) - else: - plt.xticks([x + conf['bar_width'] for x in range(n_groups)], conf['tick_labels']) - ## format tick color and tick labels - # color: the color of ticks - # labelsize: the font size of tick labels - # labelcolor: the color of tick labels - ax.tick_params(color = conf['axis_color'], labelsize = conf['tickfont_size'], labelcolor = conf['font_color']) - ## add background grid - ax.yaxis.grid(linestyle="--",color='gray', linewidth = conf['gridline_width'], alpha = 0.5) # alpha: adjust the transparency - - elif direction=='horizontal': - ## format tick color and tick labels - if conf['tick_labels'] == '': - # adjust the location of yticks label - plt.yticks([y + conf['bar_width']*0.5*(n_groups-1) for y in range(len(y_col_name))], y_col_name) - else: - # adjust the location of yticks label - plt.yticks([y + conf['bar_width']*0.5*(n_groups-1) for y in range(len(y_col_name))], conf['tick_labels']) - # color: the color of ticks - # labelsize: the font size of tick labels - # labelcolor: the color of tick labels - ax.tick_params(color = conf['axis_color'], labelsize = conf['tickfont_size'], labelcolor = conf['font_color']) - ## add background grid - ax.xaxis.grid(linestyle="--",color='gray', linewidth = conf['gridline_width'], alpha = 0.5) # alpha: adjust the transparency - - elif conf['type']=='stack': - if direction == 'vertical': - n_groups = len(y_col_name) - - ## set locations for the bars on x axis(vertical bar) - xloc = np.arange(len(x_col_name)) - - bottom_value_list = [[0]] * n_groups - rectobj_list = [0] * n_groups - - ## draw grouped bar plot - for i in (range(n_groups)): - if conf['err_series'] == '': - err = None - else: - err = data[conf['err_series'][i]].tolist() - if i == 0: - bottom_value_list[0] = 0 * n_groups - else: - bottom_value_list[i] = np.array(bottom_value_list[i-1]) + np.array(data[y_col_name[i-1]]) - - rectobj_list[i] = ax.bar(x=xloc, height=data[y_col_name[i]], width=data[y_col_name[i]], - yerr=err, bottom=bottom_value_list[i], color=conf['bar_color'][i], - edgecolor = conf['edge_color'], linewidth = conf['line_width'], - label = conf['legend_label'][i], capsize = conf['cap_size'], - error_kw = {'elinewidth': conf['eline_width'], 'capthick': conf['eline_width']}) - elif direction == 'horizontal': - n_groups = len(x_col_name) - - ## set locations for the bars on y axis(horizontal bar) - yloc = np.arange(len(y_col_name)) - - bottom_value_list = [[0]] * n_groups - rectobj_list = [0] * n_groups - ## draw grouped bar plot - for i in (range(n_groups)): - if conf['err_series'] == '': - err = None - else: - err = data[conf['err_series'][i]].tolist() - if i == 0: - bottom_value_list[0] = 0 * n_groups - else: - bottom_value_list[i] = np.array(bottom_value_list[i-1]) + np.array(data[x_col_name[i-1]]) - - rectobj_list[i] = ax.barh(y=yloc, height=conf['bar_width'], width=data[x_col_name[i]], - xerr=err, left=bottom_value_list[i], color=conf['bar_color'][i], - edgecolor = conf['edge_color'], linewidth = conf['line_width'], - label = conf['legend_label'][i], capsize = conf['cap_size'], - error_kw = {'elinewidth': conf['eline_width'], 'capthick': conf['eline_width']}) - - - - ## format ticks - # MultipleLocator: locates ticks at a multiple of the number you provide - ax.xaxis.set_major_locator(ticker.MultipleLocator(conf['xtick_loc'])) - ax.yaxis.set_major_locator(ticker.MultipleLocator(conf['ytick_loc'])) - - ## set x, y tick's direction, default:out, can be set to in,out,inout - if conf['tick_direction'] == 'in': - matplotlib.rcParams['xtick.direction'] = 'in' - matplotlib.rcParams['ytick.direction'] = 'in' - elif conf['tick_direction'] == 'inout': - matplotlib.rcParams['xtick.direction'] = 'inout' - matplotlib.rcParams['ytick.direction'] = 'inout' - elif conf['tick_direction'] == 'out': - matplotlib.rcParams['xtick.direction'] = 'out' - matplotlib.rcParams['ytick.direction'] = 'out' - - ## format the tick color and tick labels - # color: the color of ticks - # labelsize: the font size of tick labels - # labelcolor: the color of tick labels - ax.tick_params(color = conf['axis_color'], labelsize = conf['tickfont_size'], labelcolor = conf['font_color']) - - if direction == 'vertical': - if conf['tick_labels'] == '': - plt.xticks([x for x in range(len(x_col_name))], x_col_name) - else: - plt.xticks([x for x in range(len(x_col_name))], conf['tick_labels']) - ## add background grid - ax.yaxis.grid(linestyle="--",color='gray', linewidth = conf['gridline_width'], alpha = 0.5) - # alpha: adjust the transparency - - elif direction == 'horizontal': - - if conf['tick_labels']=='': - plt.yticks([y for y in range(len(y_col_name))], y_col_name) - else: - plt.yticks([y for y in range(len(x_col_name))], conf['tick_labels']) - ## add background grid - ax.xaxis.grid(linestyle="--",color='gray', linewidth = conf['gridline_width'], alpha = 0.5) - # alpha: adjust the transparency - - def autolabel(rects): - - if conf['err_series'] == '': - if direction == 'vertical': - ha='center' - va='bottom' - elif direction == 'horizontal': - ha='left' - va='center' - else: - if direction == 'vertical': - ha='center' - va='bottom' - elif direction == 'horizontal': - ha='left' - va='top' - if direction == 'vertical': - # Get y-axis height to calculate label position from. - (y_bottom, y_top) = ax.get_ylim() - y_height = y_top - y_bottom - for rect in rects: - height = rect.get_height() - # Fraction of axis height taken up by this rectangle - p_height = (height / y_height) - # If we can fit the label above the column, do that; - # otherwise, put it inside the column. - - label_position = height + (y_height * 0.01) - - ax.text(rect.get_x() + rect.get_width() / 2., label_position, - round(height, 2), ha=ha, va=va) - else: - # Get y-axis height to calculate label position from. - (x_left, x_right) = ax.get_xlim() - x_width = x_right - x_left - for rect in rects: - width = rect.get_width() - # Fraction of axis height taken up by this rectangle - p_width = (width / x_width) - # If we can fit the label above the column, do that; - # otherwise, put it inside the column. - - label_position = width + (x_width * 0.01) - - ax.text(label_position, rect.get_y() + rect.get_height()/2., - round(width, 2), ha=ha, va=va) - - ## format axes spines - ## remove top and right spines - ## set color of left and bottom axes spines - # if False, top and right borders removing - - if conf['isframe'] == False: - ax.spines['top'].set_visible(False) - ax.spines['right'].set_visible(False) - - if conf['show_value'] == True: - if conf['err_series'] == '': - if conf['type']=='single': - autolabel(rectobj) - else: - for i in range(n_groups): - autolabel(rectobj_list[i]) - else: - for i in (range(n_groups)): - if direction == 'vertical': - autolabel(rectobj_list[i]) - elif direction == 'horizontal': - autolabel(rectobj_list[i]) - - ## format title - if conf['title'] == '': - pass - else: - ax.set_title(conf['title'], fontsize=conf['title_size'], loc=conf['title_loc'], pad=conf['title_pad']) - - - ## create legend - # nocl: integer, the number of columns that the legend has - # fontsize: the font size of legend text - # loc: str or pair of floats, the location of the legend (default 'best' or 0) - plt.legend(ncol = conf['legendcol'], fontsize = conf['legfont_size'], loc = conf['legend_loc']) - - ## format x,y labels - plt.xlabel(x_label, fontsize = conf['axfont_size'], labelpad = conf['labelpad'], color = conf['font_color'], fontdict=font_dict) - plt.ylabel(y_label, fontsize = conf['axfont_size'], labelpad = conf['labelpad'], color = conf['font_color'], fontdict=font_dict) - # labelpad: Spacing in points between the label and the x-axis - - ## save image as pdf to path folder - # bbox in inches, only the given portion of the figure is saved, - # figure out the tight bbox of the figure - if conf['is_save_fig'] == True: - plt.savefig(self.path_img + conf['save_image'], bbox_inches = 'tight') - - plt.show() diff --git a/car_dreamer/toolkit/visualization/line.py b/car_dreamer/toolkit/visualization/line.py deleted file mode 100644 index fd6c96f..0000000 --- a/car_dreamer/toolkit/visualization/line.py +++ /dev/null @@ -1,543 +0,0 @@ -## import python data analysis library -import numpy as np -import pandas as pd - -## import data visualization library matplotlib and seaborn -import seaborn as sns -import matplotlib -import matplotlib.pyplot as plt -from matplotlib.ticker import MultipleLocator, FormatStrFormatter, AutoMinorLocator, FuncFormatter -from matplotlib.ticker import AutoMinorLocator, MultipleLocator, FuncFormatter -from matplotlib import rc -from mpl_toolkits.axes_grid.inset_locator import (inset_axes, InsetPosition, mark_inset, zoomed_inset_axes) - -## import module to read files -import mimetypes -import urllib -import os - -# import google colab to use google colab as editor -# if you use other editor, do not need to import google.colab here -#from google.colab import drive -#drive.mount('/content/drive') - -## setting path -# get current path -path_current = os.getcwd() -path_current=path_current.replace('\\', '/') -# the path is where the dataset saved -path = path_current + '/Example_Data/Line/' - -# the "path_img" is the position where final image will be saved -path_img = path_current + '/Images/' - -class line: - def __init__(self,path=path,path_img=path_img): - self.path=path - self.path_img=path_img - ## Configuration of the line chart - # plotwidth: width of the plot - # plotheight: height of the plot - # backgrid: backgrid of the plot - # isframe: frame of the plot - # my_font: the typeface of x, y labels - # linewidth: linewidth of the lines in the plot - # gridlinewidth: if backgrid is True, grid linewidth is the line width of background grid - # sa_linecolor: single column paper linecolors palette - # da_linecolor: double columns paper linecolors palette - # linestyle: line shapes library - # labeltext_size: text size of x,y labels - # labelpad: pad size of label - # legend_size: size of legend - # legend_loc: location of legend - # ncol: number of columns of legend - # title: True or False as options. If it is True, add title for the plot - # title_pad: if the title is True, modify pad size of title - # title_size: if the title is True, modify size of title - # title_loc: if the title is True, modify location of title - # markers: True or False as options. If it is True, add markers - # markersize: if the title is True, modify size of marker - # markers_shape: shapes library of marker - # xy_lim: True or False as options. If it is True, add x and y axis' value range - # x_range: if the xy_lim is True, set x axis range - # y_range: if the xy_lim is True, set x axis range - # inset: True or False as options. If it is True, add inset plot - # xin_start: if the inset is True, the inset plot x axis starts from xin_start - # xin_end: if the inset is True, the inset plot x axis ends from xin_end - # yin_start: if the inset is True, the inset plot y axis starts from yin_start - # yin_end: if the inset is True, the inset plot y axis starts from yin_end - # ticks: True or False as options. If it is True, add ticks of x and y axis. - # tick_size: size of tick - # tick_direction: 'out', 'inout' and 'in' options. - # x_minor_locator: number of minor ticks in x axis - # y_minor_locator: number of minor ticks in y axis - # present_linevalue: True or False as options. If it is True, present point value in the line - # double_axis: True or False as options. If it is True, add second axis on the right of figure - # save_image: True or False as options. If it is True, save chart - # savefig_bbox_inches: Bounding box in inches - self.conf={'plotwidth':9, - 'plothight':6, - 'backgrid':True, - 'isframe':True, - 'my_font':'DejaVu Sans', - 'linewidth':2, - 'gridlinewidth':0.5, - 'sa_linecolor':['#0173B2', '#DE8F05', '#029E73', '#D55E00', - '#CC78BC', '#8E5638', '#FBAFE4', '#949494', - '#ECE133', '#56B4E9'], - 'da_linecolor':{'left':['#D6DEBF','#AECEA1','#82BB92','#5EA28D', - '#49838A','#3E5F7E','#383C65','#2B1E3E'], - 'right':['#2C1E3D','#51315E','#764476','#9A5B88', - '#B77495','#CF91A3','#E0B1B4','#EDD1CB']}, - 'bg_color':["#ffd6a5","#fdffb6","#99d98c","#bde0fe",'#ffadad',"#48bfe3"], - 'linestyle':['-',':','-.','--','-',':','-.','--','-','-',':','-.'], - 'labeltext_size':18, - 'labelpad':10, - 'legend_size':10, - 'legend_loc':'upper right', - 'ncol':2, - 'title':False, - 'title_pad':10, - 'title_size':20, - 'title_loc':'center', - 'markers':False, - 'markersize':8, - 'markers_shape':['o','v','D','X','P','2','p','x','d','4','<','*'], - 'xy_lim':True, - 'x_range':False, - 'y_range':False, - 'xin_start':0, - 'xin_end':0, - 'yin_start':0, - 'yin_end':0, - 'ticks':True, - 'tick_size':14, - 'tick_direction':'out', - 'x_minor_locator':5, - 'y_minor_locator':2, - 'present_linevalue':False, - 'double_axis':False, - 'shadow':False, - 'inset':False, - 'save_image':False, - 'savefig_bbox_inches':'tight'} - - - ## read file function: read three kinds of format file csv/excel/text - # if you have other format of file, please change the function manually - # file: str, filename (e.g.'Vertical_Bar.txt') - def read_file(self,file): - file_url = urllib.request.pathname2url(file) - ftype = mimetypes.guess_type(file_url, strict=True)[0] - - ## read data file according to its formate, default includes three types of files: csv/excel/text - # read csv format data from the parking dataset - - if 'csv'or 'excel' in ftype: - # usecols: return a subset of the columns, here choose one column to use in the line chart - data = pd.read_csv(self.path+file) - # read excel format data from the parking dataset - elif 'sheet' in ftype: - data = pd.read_excel(self.path+file) - # read text format data from the parking dataset - elif ftype == 'text/plain': - data = pd.read_csv(self.path+file, sep="\t") - else: - print("File type cannot find!") - return data - - ## line chart plotting function - # file: file name of your data source - # x_col_name: ['index'] or ['x_column_name_a','x_column_name_b'...] - # y_col_name: ['y_column_name_a','y_column_name_b'...] - # x_label: x axis label - # y_label: y axis label - # legend_label: legend labels names - # paper_type: 'single' or 'double' - def plot(self, file, x_col_name=None, y_col_name=None,legend_label=None, x_label=None, y_label=None, **kwargs): - # read file - try: - self.data = self.read_file(file) - except Exception: - print('Sorry, this file does not exist, please check the file name') - - - cols = self.data.columns.to_list() - if not x_col_name: - if 'X' in cols: - self.x_col_name = ['X'] - else: - self.x_col_name = ['index'] - else: - self.x_col_name = x_col_name - - if not y_col_name: - self.y_col_name = [] - if 'X' in cols: - cols.remove('X') - for col in cols: - if "Unnamed" in col: - continue - self.y_col_name.append(col) - else: - self.y_col_name = y_col_name - - if not legend_label: - self.legend_label = self.y_col_name - else: - self.legend_label = legend_label - - if not x_label: - self.x_label = 'X' - else: - self.x_label = x_label - - - if not y_label: - if self.conf['double_axis'] == False: - self.y_label = 'Y' - elif self.conf['double_axis'] == True: - self.y_label = ['Y1', 'Y2'] - else: - self.y_label = y_label - - # when new configuraton is set, update the original one - self.conf.update(kwargs) - - cols = self.data.columns.to_list() - if self.conf['double_axis'] == False: - for x_col in self.x_col_name: - if x_col != 'index' and x_col not in cols: - raise KeyError("Invaild x_col_name") - if self.conf['shadow'] == True: - for y_cols in self.y_col_name: - for y_col in y_cols: - if y_col not in cols: - raise KeyError("Invaild y_col_name") - else: - for y_col in self.y_col_name: - if y_col not in cols: - raise KeyError("Invaild y_col_name") - elif self.conf['double_axis'] == True: - for x_col in self.x_col_name[0]: - if x_col != 'index' and x_col not in cols: - raise KeyError("Invaild x_col_name") - for x_col in self.x_col_name[1]: - if x_col != 'index' and x_col not in cols: - raise KeyError("Invaild x_col_name") - for y_col in self.y_col_name[0]: - if y_col not in cols: - raise KeyError("Invaild y_col_name") - for y_col in self.y_col_name[1]: - if y_col not in cols: - raise KeyError("Invaild y_col_name") - - - - self.len_sac = len(self.conf['sa_linecolor']) - self.len_dac_l = len(self.conf['da_linecolor']['left']) - self.len_dac_r = len(self.conf['da_linecolor']['right']) - self.len_lsty = len(self.conf['linestyle']) - self.len_mksh = len(self.conf['markers_shape']) - - - #Initializing the line - ## plot size setting - # figsize: the size of the line chart, (width,hight) - fig, self.ax_1eft = plt.subplots(figsize =(self.conf['plotwidth'], self.conf['plothight'])) - - ## background grid setting - if self.conf['backgrid'] == True: - self.ax_1eft.grid(linestyle="--", linewidth=self.conf['gridlinewidth'], color='gray', alpha=0.5) - - - if self.conf['double_axis'] == False: - if self.conf['shadow'] == True: - self.plot_shadow() - else: - self.plot_single_axis() - else: - self.plot_double_axis() - - ## x,y axis range limitation - if self.conf['x_range'] == False: - pass - else: - # x axis valure start from xaxis_start value, and end in max of the file add a small range of value - self.ax_1eft.set_xlim(self.conf['x_range'][0], self.conf['x_range'][1]) - - if self.conf['y_range'] == False: - pass - else: - # y axis valure start from yaxis_start value, and end in max of the file add a small range of value - self.ax_1eft.set_ylim(self.conf['y_range'][0], self.conf['y_range'][1]) - - ## ticks setting - if self.conf['ticks'] == True: - ## major and minor ticks for x axia - # set x axis' detailed ticks label - self.ax_1eft.xaxis.set_minor_locator(AutoMinorLocator(self.conf['x_minor_locator'])) - # set y axis' detailed ticks label - self.ax_1eft.yaxis.set_minor_locator(AutoMinorLocator(self.conf['y_minor_locator'])) - elif self.conf['ticks'] == False: - pass - - ## size of numbers on the ticks of x,y axis' setting - for tick in self.ax_1eft.xaxis.get_major_ticks(): - tick.label.set_fontsize(self.conf['tick_size']) - for tick in self.ax_1eft.yaxis.get_major_ticks(): - tick.label.set_fontsize(self.conf['tick_size']) - - - - # if False, top and right borders removing - if self.conf['isframe'] == False: - self.ax_1eft.spines['top'].set_visible(False) - self.ax_1eft.spines['right'].set_visible(False) - - ## set x, y tick's direction, default:out, can be set to in,out,inout - if self.conf['tick_direction'] == 'in': - matplotlib.rcParams['xtick.direction'] = 'in' - matplotlib.rcParams['ytick.direction'] = 'in' - elif self.conf['tick_direction'] == 'inout': - matplotlib.rcParams['xtick.direction'] = 'inout' - matplotlib.rcParams['ytick.direction'] = 'inout' - elif self.conf['tick_direction'] == 'out': - matplotlib.rcParams['xtick.direction'] = 'out' - matplotlib.rcParams['ytick.direction'] = 'out' - - ## legend setting - # ncol: number of legend column - # loc: position of the legend - if self.conf['double_axis'] == True: - self.ax_1eft.legend(ncol=self.conf['ncol'], loc=self.conf['legend_loc_l'], fontsize=self.conf['legend_size']) - self.ax_right.legend(ncol=self.conf['ncol'], loc=self.conf['legend_loc_r'], fontsize=self.conf['legend_size']) - else: - self.ax_1eft.legend(ncol=self.conf['ncol'], loc=self.conf['legend_loc'], fontsize=self.conf['legend_size']) - - - ## title and position - if self.conf['title'] == False: - pass - else: - self.ax_1eft.set_title(self.conf['title'], fontsize=self.conf['title_size'], loc=self.conf['title_loc'], pad=self.conf['title_pad']) - - ## save image as pdf to path folder - # bbox in inches, only the given portion of the figure is saved, figure out the tight bbox of the figure - if self.conf['save_image'] == True: - plt.savefig(self.path_img+'line_chart.pdf', bbox_inches=self.conf['savefig_bbox_inches']) - - # showing the image - plt.show() - - def plot_func(self, ax, x_col_name, y_col_name, legend_label, cur_color, len_color): - if x_col_name[0] == 'index': - # line with markers - if self.conf['markers'] == True: - for i in range(0, len(y_col_name)): - ax.plot(self.data.index, self.data[y_col_name[i]], marker=self.conf['markers_shape'][i%self.len_mksh], markersize=self.conf['markersize'], - linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], label=legend_label[i], color=cur_color[i%len_color]) - # line without markers - else: - for i in range(0, len(y_col_name)): - ax.plot(self.data.index, self.data[y_col_name[i]], linestyle=self.conf['linestyle'][0], - linewidth=self.conf['linewidth'], label=legend_label[i], color=cur_color[i%len_color]) - # x column is not index - else: - # line with markers - if self.conf['markers'] == True: - for i in range(0, len(y_col_name)): - if len(x_col_name)==1: - ax.plot(self.data[x_col_name[0]], self.data[y_col_name[i]], marker=self.conf['markers_shape'][i%self.len_mksh], markersize=self.conf['markersize'], - linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], label=legend_label[i], color=cur_color[i%len_color]) - else: - ax.plot(self.data[x_col_name[i]], self.data[y_col_name[i]], marker=self.conf['markers_shape'][i%self.len_mksh], markersize=self.conf['markersize'], - linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], label=legend_label[i], color=cur_color[i%len_color]) - # line without markers - else: - for i in range(0, len(y_col_name)): - if len(x_col_name)==1: - ax.plot(self.data[x_col_name[0]], self.data[y_col_name[i]], linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], - label=legend_label[i], color=cur_color[i%len_color]) - else: - ax.plot(self.data[x_col_name[i]], self.data[y_col_name[i]], linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], - label=legend_label[i], color=cur_color[i%len_color]) - - - - def plot_single_axis(self): - self.ax_1eft.set_xlabel(self.x_label, fontproperties=self.conf['my_font'], fontsize=self.conf['labeltext_size'], labelpad=self.conf['labelpad']) - self.ax_1eft.set_ylabel(self.y_label, fontproperties=self.conf['my_font'], fontsize=self.conf['labeltext_size'], labelpad=self.conf['labelpad']) - - self.plot_func(self.ax_1eft, self.x_col_name, self.y_col_name, self.legend_label, self.conf['sa_linecolor'], self.len_sac) - - if self.conf['inset'] == True: - self.plot_single_inset() - - ## presenting values on graph - if self.conf['present_linevalue'] == True: - if self.x_col_name[0] == 'index': - for i in range(0, len(self.y_col_name)): - for x,y in zip(self.data.index.values.tolist(),self.data[self.y_col_name[i]].values.tolist()): - plt.text(x, y+0.01, str(round(y,2)), color = self.color[i]) - - else: - for i in range(0, len(self.y_col_name)): - for x,y in zip(self.data[self.x_col_name[i]].values.tolist(),self.data[self.y_col_name[i]].values.tolist()): - plt.text(x, y+0.01, str(round(y,2)), color = self.color[i]) - else: - pass - - def plot_single_inset(self): - axins = zoomed_inset_axes(self.ax_1eft, 3, bbox_to_anchor=(0.43,0.7), bbox_transform=self.ax_1eft.transAxes) - - ## drawing lines of inset plot - # use the plot function - # linewidth: the line width, here set to 2 - # x column is index - self.plot_func(axins, self.x_col_name, self.y_col_name, self.legend_label, self.conf['sa_linecolor'], self.len_sac) - - ## inset plot x,y axis range limit - axins.set_xlim(0.5, 0.75) - axins.set_ylim(0, 5) - - mark_inset(self.ax_1eft, axins, loc1=2, loc2=4, fc="none", ec="0.5") - - # double axis line chart - def plot_double_axis(self): - ## x, y axis setting - # fontsize: x, y title size - # labelpad: scalar, optional, default: None - self.ax_1eft.set_xlabel(self.x_label, fontproperties=self.conf['my_font'], fontsize=self.conf['labeltext_size'], labelpad=self.conf['labelpad']) - self.ax_1eft.set_ylabel(self.y_label[0], fontproperties=self.conf['my_font'], fontsize=self.conf['labeltext_size'], labelpad=self.conf['labelpad']) - - - # left x,y columns and labels - self.x_col_name_l = self.x_col_name[0] - self.y_col_name_l = self.y_col_name[0] - self.legend_label_l = self.legend_label[0] - - # use the plot function - self.plot_func(self.ax_1eft, self.x_col_name_l, self.y_col_name_l, self.legend_label_l, self.conf['da_linecolor']['left'], self.len_dac_l) - - ## instantiate a left axis that shares the same x-axis - self.ax_right = self.ax_1eft.twinx() - - self.ax_right.set_ylabel(self.y_label[1], fontproperties=self.conf['my_font'], fontsize=self.conf['labeltext_size'], labelpad=self.conf['labelpad']) - - # already handled the x-label with ax_1eft - # alpha: transparency, soft color - # right x,y columns and labels - self.x_col_name_r = self.x_col_name[1] - self.y_col_name_r = self.y_col_name[1] - self.legend_label_r = self.legend_label[1] - - # use the plot function - self.plot_func(self.ax_right, self.x_col_name_r, self.y_col_name_r, self.legend_label_r, self.conf['da_linecolor']['right'], self.len_dac_r) - - - # plotting inset plot - if self.conf['inset'] == True: - self.plot_double_inset() - - ## presenting left_axis values on graph - if self.conf['present_linevalue'] == True: - if self.x_col_name_l[0] == 'index': - for i in range(0, len(self.y_col_name_l)): - for x,y in zip(self.data.index.values.tolist(),self.data[self.y_col_name_l[i]].values.tolist()): - plt.text(x, y+0.01, str(round(y,2)), color = self.color[i]) - - else: - for i in range(0, len(self.y_col_name_l)): - for x,y in zip(self.data[self.x_col_name_l[i]].values.tolist(),self.data[self.y_col_name_l[i]].values.tolist()): - plt.text(x, y+0.01, str(round(y,2)), color = self.color[i]) - else: - pass - - ## presenting right_axis values on graph - if self.conf['present_linevalue'] == True: - if self.x_col_name_r[0] == 'index': - for i in range(0, len(self.y_col_name_r)): - for x,y in zip(self.data.index.values.tolist(),self.data[self.y_col_name_r[i]].values.tolist()): - plt.text(x, y+0.01, str(round(y,2)), color = self.color[i]) - - else: - for i in range(0, len(self.y_col_name_r)): - for x,y in zip(self.data[self.x_col_name_r[i]].values.tolist(),self.data[self.y_col_name_r[i]].values.tolist()): - plt.text(x, y+0.01, str(round(y,2)), color = self.color[i]) - else: - pass - - - def plot_double_inset(self): - zoomed_left_axis = zoomed_inset_axes(self.ax_1eft, 1, bbox_to_anchor=(0.43,0.7), bbox_transform=self.ax_1eft.transAxes) - - ## drawing lines of inset plot - # use the plot function - # linewidth: the line width, here set to 2 - # x column is index - self.plot_func(zoomed_left_axis, self.x_col_name_l, self.y_col_name_l, self.legend_label_l, self.conf['da_linecolor']['left'], self.len_dac_l) - - - ## inset plot x,y axis range limit - zoomed_left_axis.set_xlim(self.conf['xin_start'], self.conf['xin_end']) - zoomed_left_axis.set_ylim(self.conf['yin_start'], self.conf['yin_end']) - - zoomed_right_axis = zoomed_left_axis.twinx() - - ## drawing lines of inset plot - # use the plot function - # linewidth: the line width, here set to 2 - # x column is index - self.plot_func(zoomed_right_axis, self.x_col_name_r, self.y_col_name_r, self.legend_label_r, self.conf['da_linecolor']['right'], self.len_dac_r) - - - def plot_shadow(self): - self.ax_1eft.set_xlabel(self.x_label, fontproperties=self.conf['my_font'], fontsize=self.conf['labeltext_size'], labelpad=self.conf['labelpad']) - self.ax_1eft.set_ylabel(self.y_label, fontproperties=self.conf['my_font'], fontsize=self.conf['labeltext_size'], labelpad=self.conf['labelpad']) - - y_data = [] - for i in range(len(self.y_col_name)): - y_tmp = [] - for j in range(len(self.y_col_name[i])): - y_tmp.append(self.data[self.y_col_name[i][j]]) - y_data.append(y_tmp) - - if self.x_col_name[0] == 'index': - # line with markers - if self.conf['markers'] == True: - for i in range(0, len(y_data)): - self.ax_1eft.plot(self.data.index, np.mean(y_data[i], axis=0), marker=self.conf['markers_shape'][i%self.len_mksh], markersize=self.conf['markersize'], - linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], label=self.legend_label[i], color=self.conf['sa_linecolor'][i%self.len_sac]) - self.ax_1eft.fill_between(self.data.index, np.max(y_data[i], axis=0),np.min(y_data[i], axis=0), facecolor=self.conf['bg_color'][i], alpha=0.45) - # line without markers - else: - for i in range(0, len(y_data)): - self.ax_1eft.plot(self.data.index, np.mean(y_data[i], axis=0), linestyle=self.conf['linestyle'][0], - linewidth=self.conf['linewidth'], label=self.legend_label[i], color=self.conf['sa_linecolor'][i%self.len_sac]) - self.ax_1eft.fill_between(self.data.index, np.max(y_data[i], axis=0),np.min(y_data[i], axis=0), facecolor=self.conf['bg_color'][i], alpha=0.45) - - # x column is not index - else: - # line with markers - if self.conf['markers'] == True: - for i in range(0, len(y_data)): - if len(self.x_col_name)==1: - self.ax_1eft.plot(self.data[self.x_col_name[0]], np.mean(y_data[i], axis=0), marker=self.conf['markers_shape'][i%self.len_mksh], markersize=self.conf['markersize'], - linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], label=self.legend_label[i], color=self.conf['sa_linecolor'][i%self.len_sac]) - self.ax_1eft.fill_between(self.data[self.x_col_name[0]], np.max(y_data[i], axis=0),np.min(y_data[i], axis=0), facecolor=self.conf['bg_color'][i], alpha=0.45) - else: - self.ax_1eft.plot(self.data[self.x_col_name[i]], np.mean(y_data[i], axis=0), marker=self.conf['markers_shape'][i%self.len_mksh], markersize=self.conf['markersize'], - linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], label=self.legend_label[i], color=self.conf['sa_linecolor'][i%self.len_sac]) - self.ax_1eft.fill_between(self.data[self.x_col_name[i]], np.max(y_data[i], axis=0),np.min(y_data[i], axis=0), facecolor=self.conf['bg_color'][i], alpha=0.45) - # line without markers - else: - for i in range(0, len(y_data)): - if len(self.x_col_name)==1: - self.ax_1eft.plot(self.data[self.x_col_name[0]], np.mean(y_data[i], axis=0), linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], - label=self.legend_label[i], color=self.conf['sa_linecolor'][i%self.len_sac]) - self.ax_1eft.fill_between(self.data[self.x_col_name[0]], np.max(y_data[i], axis=0),np.min(y_data[i], axis=0), facecolor=self.conf['bg_color'][i], alpha=0.45) - else: - self.ax_1eft.plot(self.data[self.x_col_name[i]], np.mean(y_data[i], axis=0), linestyle=self.conf['linestyle'][0], linewidth=self.conf['linewidth'], - label=self.legend_label[i], color=self.conf['sa_linecolor'][i%self.len_sac]) - self.ax_1eft.fill_between(self.data[self.x_col_name[i]], np.max(y_data[i], axis=0),np.min(y_data[i], axis=0),facecolor=self.conf['bg_color'][i],alpha=0.45)