import matplotlib as mpl
import matplotlib.pyplot as plt
from pathlib import Path
import matplotlib.font_manager as fm
from matplotlib.colors import LinearSegmentedColormap
from mpl_toolkits.basemap import Basemap as Bp

#! UNSOLVE: subplots.colorbar() not working


global fontscale
fontscale = 0.6

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'


# 獲取當前檔案位址
currentfilepath = __file__

# 刪去__file__中最後面自"\"開始的字串(刪除檔名)
motherpath = currentfilepath[:-len(currentfilepath.split('\\')[-1])]
try:
    fontpath = Path(mpl.get_data_path(), motherpath+"\\futura medium bt.ttf")
    fontpath_bold = Path(mpl.get_data_path(), motherpath+"\Futura Heavy font.ttf")
    fontpath_black = Path(mpl.get_data_path(), motherpath+"\Futura Extra Black font.ttf")
except: # 未安裝字體
    try:
        # 退而求其次，使用預設字體
        fontpath = 'C:\Windows\Fonts\Arial.ttf'
        fontpath_bold = 'C:\Windows\Fonts\Arial Bold.ttf'
        fontpath_black = 'C:\Windows\Fonts\Arial Black.ttf'
        print(bcolors.WARNING+f'Please install Futura fonts in the same directory as this file.\ninstall font-packages: https://dwl.freefontsfamily.com/download/futura/;\n Moving the font file to installed module folder: {motherpath}.\n Currently using system default font: Arial'+bcolors.ENDC)
    except:
        print(bcolors.WARNING+f'[WARNING] Cannot find font files, please install Futura fonts in the same directory as this file.\ninstall font-packages: https://dwl.freefontsfamily.com/download/futura/;\n Moving the font file to installed module folder{motherpath}.'+bcolors.ENDC)

def redirectfontfolder(path):
    # 檢查是否需要刪除最後面自"\"開始的字串(刪除檔名)
    if path[-1] == '\\' or path[-1] == '/':
        path = path[:-1]
    global fontpath, fontpath_bold, fontpath_black
    try:
        fontpath = Path(mpl.get_data_path(), path+"\\futura medium bt.ttf")
        fontpath_bold = Path(mpl.get_data_path(), path+"\Futura Heavy font.ttf")
        fontpath_black = Path(mpl.get_data_path(), path+"\Futura Extra Black font.ttf")
        # print try to redirect font folder, but we recommend you to install Futura fonts to {motherpath} instead.
        print(bcolors.WARNING+f'Try to redirect font folder, but we recommend you to install Futura fonts to {motherpath} instead.'+bcolors.ENDC)
        print(f'[HINT] Make sure the font files are in the directory:\n\t 1. {path}\\futura medium bt.ttf\n\t 2. {path}\\Futura Heavy font.ttf\n\t 3. {path}\\Futura Extra Black font.ttf')
              
    except:
        print('[HINT] Proper redirected font folder path example: C:\\Users\\user\\Desktop\\font')
        raise Exception(bcolors.FAIL+f'[FATAL ERROR] Failed to redirect the font folder. \nPlease install Futura fonts in the same directory as this file.\ninstall font-packages: https://dwl.freefontsfamily.com/download/futura/;\n Moving the font file to installed module folder{motherpath}.'+bcolors.ENDC)



# 初始化
def initplot(style='default',figsize=(10,8),background=True):
    global theme
    if style == 'default'or style == 'light_background' or style == 'light' or style == 'l':
        theme = 'default'
        plt.style.use(theme)
    elif style == 'dark_background' or style == 'dark' or style == 'd':
        theme = 'dark_background'
        plt.style.use(theme)
    
    # size
    plt.rcParams['figure.figsize'] = figsize


    # 設定facecolor
    if background == True:
        plt.gca().set_facecolor(colorlist('bg'))
    else: pass



# 色票(顏色選用優先級)
def colorlist(index):
    if type(index) == list:
        # 判斷是否所有元素都in
        if all(i in ['bg', 'bg1', 'bg2', 'fg', '1', '2', '3', '4', 'rfg'] for i in index):
            return [colorseries[i] for i in index]
        else:
            return index
    else:
        str(index)
        if index in ['bg', 'bg1', 'bg2', 'fg', '1', '2', '3', '4', 'rfg']:
            try:    
                if theme == 'default':
                    colorseries = {'bg': '#D9EEFD',
                                'bg1': '#D9EEFD',
                                'bg2': '#F7DCD1',
                                'rfg': '#F5F5F5',
                                'fg': '#111111',
                                '1': '#0A9CCF',
                                '2': '#AC005A',
                                '3': '#A19253',
                                '4': '#A43713'}
                    return colorseries[index]
                                
                elif theme == 'dark_background':
                    colorseries = {'bg': '#122D64',
                                'bg1': '#122D64',
                                'bg2': '#122D64',
                                'rfg': '#080808',
                                'fg': '#EEEEEE',
                                '1': '#0A9CCF',
                                '2': '#AC005A',
                                '3': '#A19253',
                                '4': '#A43713'}
                    return colorseries[index]
            except: # NameError: name 'theme' is not defined
                raise Exception(bcolors.WARNING+'Please run initplot() first.'+bcolors.ENDC)
                
        else:
            return index
    
def cmaplist(index):
    str(index)
    if index in ['-28','28','-27','-26','-25','-24','-23','-22','22','23','24','25','26','27','12','13','14','15','-12','-13','-14','-15']:
        try:
            if theme == 'default':
                if index == '15':
                    return LinearSegmentedColormap.from_list('mycmap', ['#454FB4','#47A7DE','#D5EDD5','#E08A16','#AB503B'])
                if index == '14':
                    return LinearSegmentedColormap.from_list('mycmap', ['#454FB4','#47A7DE','#E08A16','#AB503B'])
                if index == '13':
                    return LinearSegmentedColormap.from_list('mycmap', ['#454FB4','#D5EDD5','#AB503B'])
                if index == '12':
                    return LinearSegmentedColormap.from_list('mycmap', ['#47A7DE','#E08A16'])

                if index == '-15': # reversed 1
                    return LinearSegmentedColormap.from_list('mycmap', ['#AB503B','#E08A16','#D5EDD5','#47A7DE','#454FB4'])
                if index == '-14': # reversed 1 but 4 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#AB503B','#E08A16','#47A7DE','#454FB4'])
                if index == '-13': # reversed 1 but 3 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#AB503B','#D5EDD5','#454FB4'])
                if index == '-12': # reversed 1 but 2 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#E08A16','#47A7DE'])

                if index == '28':
                    return LinearSegmentedColormap.from_list('mycmap', ['#D9EEFD','#FFFFFF','#FFFFFF','#F2CABF','#F1C9B4','#DCB29A','#DB997F','#CF725E','#BB8263'])        
                if index == '27':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#EEEEEE','#F2CABF','#F1C9B4','#DCB29A','#DB997F','#CF725E','#BB8263'])
                if index == '26':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4','#DCB29A','#DB997F','#CF725E'])
                if index == '25':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4','#DCB29A','#DB997F'])
                if index == '24':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4','#DCB29A'])
                if index == '23':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4'])
                if index == '22':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF'])

                if index == '-28': # reversed 2
                    return LinearSegmentedColormap.from_list('mycmap', ['#BB8263','#CF725E','#DB997F','#DCB29A','#F1C9B4','#F2CABF','#FFFFFF','#FFFFFF','#D9EEFD']) 
                if index == '-27': # reversed 2
                    return LinearSegmentedColormap.from_list('mycmap', ['#BB8263','#CF725E','#DB997F','#DCB29A','#F1C9B4','#F2CABF','#EEEEEE','#EEEEEE'])
                if index == '-26': # reversed 2 but 6 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#CF725E','#DB997F','#DCB29A','#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-25':
                    return LinearSegmentedColormap.from_list('mycmap', ['#DB997F','#DCB29A','#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-24':
                    return LinearSegmentedColormap.from_list('mycmap', ['#DCB29A','#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-23':
                    return LinearSegmentedColormap.from_list('mycmap', ['#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-22':
                    return LinearSegmentedColormap.from_list('mycmap', ['#F2CABF','#EEEEEE'])
            
            
            elif theme == 'dark_background':
                if index == '15':
                    return LinearSegmentedColormap.from_list('mycmap', ['#454FB4','#47A7DE','#D5EDD5','#E08A16','#AB503B'])
                if index == '14':
                    return LinearSegmentedColormap.from_list('mycmap', ['#454FB4','#47A7DE','#E08A16','#AB503B'])
                if index == '13':
                    return LinearSegmentedColormap.from_list('mycmap', ['#454FB4','#D5EDD5','#AB503B'])
                if index == '12':
                    return LinearSegmentedColormap.from_list('mycmap', ['#47A7DE','#E08A16'])

                if index == '-15': # reversed 1
                    return LinearSegmentedColormap.from_list('mycmap', ['#AB503B','#E08A16','#D5EDD5','#47A7DE','#454FB4'])
                if index == '-14': # reversed 1 but 4 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#AB503B','#E08A16','#47A7DE','#454FB4'])
                if index == '-13': # reversed 1 but 3 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#AB503B','#D5EDD5','#454FB4'])
                if index == '-12': # reversed 1 but 2 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#E08A16','#47A7DE'])
                        
                if index == '28':
                    return LinearSegmentedColormap.from_list('mycmap', ['#D9EEFD','#FFFFFF','#FFFFFF','#F2CABF','#F1C9B4','#DCB29A','#DB997F','#CF725E','#BB8263'])        
                if index == '27':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4','#DCB29A','#DB997F','#CF725E','#BB8263'])
                if index == '26':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4','#DCB29A','#DB997F','#CF725E'])
                if index == '25':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4','#DCB29A','#DB997F'])
                if index == '24':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4','#DCB29A'])
                if index == '23':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF','#F1C9B4'])
                if index == '22':
                    return LinearSegmentedColormap.from_list('mycmap', ['#EEEEEE','#F2CABF'])
                
                if index == '-28': # reversed 2
                    return LinearSegmentedColormap.from_list('mycmap', ['#BB8263','#CF725E','#DB997F','#DCB29A','#F1C9B4','#F2CABF','#FFFFFF','#FFFFFF','#D9EEFD']) 
                if index == '-27': # reversed 2
                    return LinearSegmentedColormap.from_list('mycmap', ['#BB8263','#CF725E','#DB997F','#DCB29A','#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-26': # reversed 2 but 6 colors
                    return LinearSegmentedColormap.from_list('mycmap', ['#CF725E','#DB997F','#DCB29A','#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-25':
                    return LinearSegmentedColormap.from_list('mycmap', ['#DB997F','#DCB29A','#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-24':
                    return LinearSegmentedColormap.from_list('mycmap', ['#DCB29A','#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-23':
                    return LinearSegmentedColormap.from_list('mycmap', ['#F1C9B4','#F2CABF','#EEEEEE'])
                if index == '-22':
                    return LinearSegmentedColormap.from_list('mycmap', ['#F2CABF','#EEEEEE'])
        except: # NameError: name 'theme' is not defined
            raise Exception(bcolors.WARNING+'Please run initplot() first.'+bcolors.ENDC)
    else: 
        return index

# LABEL設定
'''
默認下系統會在使用者繪製不同種類的圖形添加LABEL計數，依種類分開計數，無法在圖例中顯示出來的LABEL不用計數；使用者依然可以手動為LABEL賦值進行覆蓋
'''
# 點狀圖
SCATTERNO = 0
# 折線圖
PLOTNO = 0
# 直方圖
HISTNO = 0
# 橫向長條圖
BARHNO = 0
# 縱向長條圖
BARNO = 0

def getSCATTERNO():
    global SCATTERNO
    SCATTERNO += 1
    label = 'SCATTER'+str(SCATTERNO)
    return label

def getPLOTNO():
    global PLOTNO
    PLOTNO += 1
    label = 'PLOT'+str(PLOTNO)
    return label

def getHISTNO():
    global HISTNO
    HISTNO += 1
    label = 'HIST'+str(HISTNO)
    return label

def getBARHNO():
    global BARHNO
    BARHNO += 1
    label = 'BARH'+str(BARHNO)
    return label

def getBARNO():
    global BARNO
    BARNO += 1
    label = 'BAR'+str(BARNO)
    return label


# 存檔
def savefig(filename, dpi=300, bbox_inches='tight', pad_inches=0.1, transparent=False):
    plt.savefig(filename, dpi=dpi, bbox_inches=bbox_inches, pad_inches=pad_inches,transparent=transparent)

# 標題
def title(title, color='fg', font=fontpath_bold, fontsize=30):
    plt.suptitle(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize))

def lefttitle(title, loc='left', color='1', font=fontpath_bold, fontsize=24):
    plt.title(title, loc=loc, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize))

def righttitle(title, loc='right', color='2', font=fontpath_bold, fontsize=24):
    plt.title(title, loc=loc, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize))

# scatter繪圖
def scatter(x, y, color='fg', size=3, marker='o', linewidth=None, label=getSCATTERNO(), linestyle='-', **kwargs):
    plt.scatter(x, y, color=colorlist(color), s=size, marker=marker, linewidth=linewidth, label=label, linestyle=linestyle, **kwargs)

# plot繪圖
def plot(x, y, color='fg', linewidth=2, linestyle='-', label=getPLOTNO(),**kwargs):
    plt.plot(x, y, color=colorlist(color), linewidth=linewidth, label=label,linestyle=linestyle, **kwargs)

# boxplot繪圖
def boxplot(x, vert=True, patch_artist=True, showmeans = True, showcaps = True, showbox = True, widths = 0.5, boxfacecolor='1', boxcolor='fg', boxlinewidth=3, capcolor='fg', caplinewidth=3, whiskercolor='fg', whiskerlinewidth=3, fliercolor='fg', fliermarkeredgecolor='fg', flierlinewidth=3, mediancolor='fg', medianlinewidth=3, meancolor='fg', meanmarker='D', meanmarkeredgecolor='fg', meanmarkerfacecolor='2', meansize=20, meanmarkeredgewidth=3, **kwargs):
    plt.boxplot(x, vert=vert, patch_artist=patch_artist, showmeans = showmeans, showcaps = showcaps, showbox = showbox, widths = widths, boxprops=dict(facecolor=colorlist(boxfacecolor), color=colorlist(boxcolor), linewidth = boxlinewidth), capprops=dict(color=colorlist(capcolor), linewidth = caplinewidth), whiskerprops=dict(color=colorlist(whiskercolor), linewidth = whiskerlinewidth), flierprops=dict(color=colorlist(fliercolor), markeredgecolor=colorlist(fliermarkeredgecolor), linewidth = flierlinewidth), medianprops=dict(color=colorlist(mediancolor), linewidth = medianlinewidth), meanprops=dict(marker=meanmarker, markeredgecolor=colorlist(meanmarkeredgecolor), markerfacecolor=colorlist(meanmarkerfacecolor), markersize=meansize, markeredgewidth = meanmarkeredgewidth), **kwargs)

# polar繪圖
def polar(theta, r, color='fg', linewidth=2, linestyle='-', label=getPLOTNO(),**kwargs):
    plt.polar(theta, r, color=colorlist(color), linewidth=linewidth, label=label,linestyle=linestyle, **kwargs)

# contour繪圖
def contour(x, y, z, colors='fg', levels=10, linewidths=2, clabel=True, fontsize=12, color='fg', **kwargs):
    CS = plt.contour(x, y, z, colors=colorlist(colors), levels=levels, linewidths=linewidths, **kwargs)
    if clabel == True:
        CL = CS.clabel(fontsize=fontsize, colors=colorlist(color), inline=True, levels=levels, **kwargs)


# contourf繪圖
def contourf(x, y, z, levels=10, cmap='28', contour=True, clabel=True,linewidths=1.5, color='fg', vmin='auto', vmax='auto',**kwargs):
    import numpy as np
    # 傳出Z值和levels值
    global contour_vmin, contour_vmax, contour_levels
    contour_levels = levels
    if vmin == 'auto':
        vmin = np.floor(z.min()/10**(len(str(int(z.min())))-2))*10**(len(str(int(z.min())))-2)
        contour_vmin = vmin
    else:
        contour_vmin = vmin
    if vmax == 'auto':
        vmax = np.ceil(z.max()/10**(len(str(int(z.max())))-2))*10**(len(str(int(z.max())))-2)
        contour_vmax = vmax
    else:
        contour_vmax = vmax
    
    if contour == True:
        CS = plt.contour(x, y, z, colors=colorlist(color), levels=levels, linewidths=linewidths)
    if clabel == True:
        CL = CS.clabel(fontsize=8, colors=colorlist(color), inline=True)
    plt.contourf(x, y, z, cmap=cmaplist(cmap), vmin=vmin, vmax=vmax, levels=levels, **kwargs)



# colorbar顯示
def colorbar(ticks='auto',label=' ', orientation='vertical',shrink=0.95, aspect=20, fraction=0.046, pad=0.04, labelfontsize=16, font=fontpath, color='fg', extend='neither',**kwargs):
    if orientation == 'v' or 'V':
        orientation = 'vertical'
    elif orientation == 'h' or 'H':
        orientation = 'horizontal'
    if ticks == 'auto':
        import numpy as np
        ticks = []
        for i in range(contour_levels):
            ticks.append(contour_vmin+(contour_vmax-contour_vmin)/(contour_levels-1)*i)
        extend = 'both'
        CB = plt.colorbar(ticks=ticks, orientation=orientation, shrink=shrink, aspect=aspect, label=label, fraction=fraction, pad=pad, extend=extend, **kwargs)
        plt.clim(contour_vmin, contour_vmax)
        
    else:
        CB = plt.colorbar(ticks=ticks, orientation=orientation, shrink=shrink, aspect=aspect, label=label, fraction=fraction, pad=pad, extend=extend, **kwargs)
    CB.ax.tick_params(labelsize=labelfontsize, labelcolor=colorlist(color), color=colorlist(color))
    CB.ax.set_ylabel(label, fontproperties=fm.FontProperties(fname=font, size=labelfontsize), color=colorlist(color))
    CB.ax.set_yticks(ticks,ticks, fontproperties=fm.FontProperties(fname=font, size=labelfontsize))
    CB.ax.yaxis.set_tick_params(color=colorlist(color), labelcolor=colorlist(color))
    CB.outline.set_color(colorlist(color))
    CB.outline.set_linewidth(2)

def clim(vmin, vmax):
    plt.clim(vmin, vmax)

# 直方圖
def hist(x, bins=5, color='1', edgecolor='fg', linewidth=3, label=getHISTNO(), **kwargs):
    plt.hist(x, bins=bins, color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label,**kwargs)

def hist2d(x, y, bins=5, cmap='2', **kwargs):
    plt.hist2d(x, y, bins=bins, cmap=cmaplist(cmap), **kwargs)

# 橫向長條圖
def barh(x, y, width=0.8, color='1', edgecolor='fg', linewidth=3, label=getBARHNO(), **kwargs):
    plt.barh(x, y, height=width, color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label, **kwargs)

# 縱向長條圖
def bar(x, y, width=0.8, color='1', edgecolor='fg', linewidth=3, label=getBARNO(), **kwargs):
    plt.bar(x, y, width=width,color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label, **kwargs)

# 圓餅圖
def pie(x, labels=None, colors=None, explode=None, autopct=None, shadow=False, startangle=90, pctdistance=0.6, labeldistance=1.1, radius=1, labelfontsize=16, labelfontcolor='fg', widgefontsize=16, widgefontcolor='fg', counterclock=True, edgecolor='fg',linewidth=3, linestyle='-', antialiased=False,textprops=None, center=(0, 0), frame=False, rotatelabels=False, **kwargs):
    PW, PT, PA = plt.pie(x, labels=labels, colors=colorlist(colors), explode=explode, autopct=autopct, shadow=shadow, startangle=startangle, pctdistance=pctdistance, labeldistance=labeldistance, radius=radius, counterclock=counterclock, wedgeprops={"edgecolor":colorlist(edgecolor),'linewidth': linewidth, 'linestyle': linestyle, 'antialiased': antialiased}, textprops=textprops, center=center, frame=frame, rotatelabels=rotatelabels, **kwargs)
    # PW: Widges, PT: Texts, PA: Autopct
    # 設定圓餅圖文字
    for t in PT:
        t.set_fontproperties(fm.FontProperties(fname=fontpath, size=labelfontsize))
        t.color = colorlist(labelfontcolor)
    # 設定圓餅圖百分比
    for t in PA:
        t.set_fontproperties(fm.FontProperties(fname=fontpath, size=widgefontsize))
        t.color = colorlist(widgefontcolor)

# 表格
def table(cellText, rowLabels=None, colLabels=None, rowcolor='rfg', colcolor='rfg', rowLoc='right', colLoc='center', loc='center', cellLoc='center', cellcolor='rfg', cellFontsize=16, cellFontcolor='fg', rowLabelsFontsize=16, rowLabelsFontcolor='fg', colLabelsFontsize=16, colLabelsFontcolor='fg', edgecolor='fg', **kwargs):
    # set cellcolors (must have 1 row at least)
    if type(cellcolor) == list:
        if len(cellcolor) == 1:
            cellcolors = [[colorlist(cellcolor[0]) for i in range(len(cellText[0]))]]
        else:
            cellcolors = [[colorlist(cellcolor[i]) for i in range(len(cellText[0]))]]
    else:
        cellcolors = [[colorlist(cellcolor) for i in range(len(cellText[0]))]]
    colcolors = [colorlist(colcolor) for i in range(len(cellText[0]))]
    rowcolors = [colorlist(rowcolor) for i in range(len(cellText))]
    TB = plt.table(cellText, rowLabels=rowLabels, colLabels=colLabels, rowColours=rowcolors, colColours=colcolors, rowLoc=rowLoc, colLoc=colLoc, loc=loc, cellLoc=cellLoc, cellColours=cellcolors,**kwargs)
    TB.auto_set_font_size(False)
    TB.set_fontsize(cellFontsize)
    TB.auto_set_column_width(col=list(range(len(cellText[0]))))
    for k, cell in TB.get_celld().items():
        cell.set_edgecolor(colorlist(edgecolor))
        cell.set_text_props(fontproperties=fm.FontProperties(fname=fontpath_bold, size=cellFontsize), color=colorlist(cellFontcolor))
        if k[0] == 0:
            cell.set_text_props(fontproperties=fm.FontProperties(fname=fontpath_bold, size=rowLabelsFontsize))
            cell.set_text_props(color=colorlist(rowLabelsFontcolor))
        if k[1] == -1: #
            cell.set_text_props(fontproperties=fm.FontProperties(fname=fontpath_bold, size=colLabelsFontsize))
            cell.set_text_props(color=colorlist(colLabelsFontcolor))    
        print(k,cell)

    TB.scale(2, 2.5)
    plt.axis('off')

# 標籤
def xlabel(xlabel, color='fg', font=fontpath, fontsize=24, **kwargs):
    plt.xlabel(xlabel, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
def ylabel(ylabel, color='fg', font=fontpath, fontsize=24, **kwargs):
    plt.ylabel(ylabel, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)

# 刻度
def xticks(ticks, labels, color='fg', font=fontpath, fontsize=18, **kwargs):
    plt.xticks(ticks, labels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
def yticks(ticks, labels, color='fg', font=fontpath, fontsize=18, **kwargs):
    plt.yticks(ticks, labels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
def xyticks(xticks, xlabels, yticks, ylabels, color='fg', font=fontpath, fontsize=18, **kwargs):
    plt.xticks(xticks, xlabels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    plt.yticks(yticks, ylabels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)

# 限制
def xlim(xmin=None, xmax=None, **kwargs):
    plt.xlim(xmin, xmax, **kwargs)
def ylim(ymin=None, ymax=None, **kwargs):
    plt.ylim(ymin, ymax, **kwargs)
def xylim(xmin=None, xmax=None, ymin=None, ymax=None, **kwargs):
    plt.xlim(xmin, xmax, **kwargs)
    plt.ylim(ymin, ymax, **kwargs)

# 畫指數
def xscale(scale, **kwargs):
    plt.xscale(scale, **kwargs)
def yscale(scale, **kwargs):
    plt.yscale(scale, **kwargs)

def xlog(base=10, **kwargs):
    plt.xscale('log', base=base, **kwargs)
def ylog(base=10, **kwargs):
    plt.yscale('log', base=base, **kwargs)

# 畫網格
def grid(b=None, which='major', axis='both', color='fg', linestyle=':', linewidth=0.5, **kwargs):
    plt.grid(b, which=which, axis=axis, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)

# spines
def spines(top=True, right=True, bottom=True, left=True, color='fg', linewidth=3, **kwargs):
    if top: plt.gca().spines['top'].set_visible(top)
    if right: plt.gca().spines['right'].set_visible(right)
    if bottom: plt.gca().spines['bottom'].set_visible(bottom)
    if left: plt.gca().spines['left'].set_visible(left)
    if top: plt.gca().spines['top'].set_color(colorlist(color))
    if right: plt.gca().spines['right'].set_color(colorlist(color))
    if bottom: plt.gca().spines['bottom'].set_color(colorlist(color))
    if left: plt.gca().spines['left'].set_color(colorlist(color))
    if top: plt.gca().spines['top'].set_linewidth(linewidth)
    if right: plt.gca().spines['right'].set_linewidth(linewidth)
    if bottom: plt.gca().spines['bottom'].set_linewidth(linewidth)
    if left: plt.gca().spines['left'].set_linewidth(linewidth)

# hide spines
def hidespines(top=True, right=True, bottom=True, left=True):
    if top: plt.gca().spines['top'].set_color('none')
    if right: plt.gca().spines['right'].set_color('none')
    if bottom: plt.gca().spines['bottom'].set_color('none')
    if left: plt.gca().spines['left'].set_color('none')

# 挪動坐標軸
def xaxisposition(yposition, xaxis='bottom', **kwargs):
    plt.gca().xaxis.set_ticks_position(xaxis)
    plt.gca().spines[xaxis].set_position(('data', yposition))

def yaxisposition(xposition, yaxis='left', **kwargs):
    plt.gca().yaxis.set_ticks_position(yaxis)
    plt.gca().spines[yaxis].set_position(('data', xposition))

# 開啟所有坐標軸
def ticksall(labeltop=True, labelright=True, labelleft=True, labelbottom=True):
    if labeltop: plt.tick_params(top=True, labeltop=True)
    if labelright: plt.tick_params(right=True, labelright=True)
    if labelleft: plt.tick_params(left=True, labelleft=True)
    if labelbottom: plt.tick_params(bottom=True, labelbottom=True)

# axhline 水平線
def axhline(y=0, color='fg', linestyle='dashed', linewidth=3, **kwargs):
    plt.axhline(y=y, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)

# axvline 垂直線
def axvline(x=0, color='fg', linestyle='dashed', linewidth=3, **kwargs):
    plt.axvline(x=x, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)

# 圖例legend
def legend(loc='best', fontsize=18, labelcolor='fg', frameon=True, framealpha=1, facecolor='rfg', edgecolor='fg', edgewidth=2 ,roundedge=False, **kwargs):
    LG = plt.gca().legend(loc=loc, fontsize=fontsize, labelcolor=colorlist(labelcolor), frameon=frameon, framealpha=framealpha, prop=fm.FontProperties(fname=fontpath, size=fontsize), facecolor=colorlist(facecolor), edgecolor=colorlist(edgecolor), **kwargs)
    if roundedge == False:
        LG.get_frame().set_boxstyle('Round', pad=0.2, rounding_size=-0.01)
    LG.get_frame().set_linewidth(edgewidth)

# 文字
def text(x, y, text, color='fg', font=fontpath, fontsize=20, **kwargs):
    plt.text(x, y, text, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)

# 帶有標籤的文字
'''
標籤為反白的文字，背景需為鋪色矩形
'''
def labeltext(x, y, w, h,label='LABEL TEXT', text='NORMAL TEXT', color='2', font=fontpath, fontsize=19, **kwargs):
    # 先繪製label的矩形背景
    plt.gca().add_patch(plt.Rectangle((x-0.05*w, y-0.1*h), width=w, height=h, color=colorlist(color), alpha=1))
    # 再繪製label文字於矩形中
    plt.text(x, y, label, color='#EEEEEE', fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    # 在label之後繪製text文字
    plt.text(x+w, y, text, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)

def annotate(text, xy, xytext, arrowcolor='fg', color='fg', font=fontpath, fontsize=20, **kwargs):
    plt.annotate(text, xy, xytext, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), arrowprops=dict(arrowstyle="->", color=colorlist(arrowcolor), connectionstyle="arc3,rad=.2"), **kwargs)

def fill_between(x, y1, y2, color='3', alpha=0.5, **kwargs):
    plt.fill_between(x, y1, y2, color=colorlist(color), alpha=alpha, **kwargs)

def fill_betweenx(y, x1, x2, color='3', alpha=0.5, **kwargs):
    plt.fill_betweenx(y, x1, x2, color=colorlist(color), alpha=alpha, **kwargs)

def invert_xaxis():
    plt.gca().invert_xaxis()

def invert_yaxis():
    plt.gca().invert_yaxis()

def twinx(**kwargs):
    # print the cautions of twinx and twiny
    print(bcolors.WARNING+'[WARNING] Some bugs have been reported when using twinx() or twiny().'+bcolors.ENDC)
    plt.twinx(**kwargs)

def twiny(**kwargs):
    # print the cautions of twinx and twiny
    print(bcolors.WARNING+'[WARNING] Some bugs have been reported when using twinx() or twiny().'+bcolors.ENDC)
    plt.twiny(**kwargs)

def tight_layout(**kwargs):
    plt.tight_layout(**kwargs)


# 設定尺寸
def figsize(width, height):
    plt.rcParams['figure.figsize'] = width, height

# 顯示
def show():
    plt.show()

# 清除
def clf():
    plt.clf()

# 關閉
def close():
    plt.close()

def figure():
    plt.figure()

# 圖像處理
def imread(filename, format=None):
    return plt.imread(filename, format=format)

def imshow(X, cmap='28', vmin=None, vmax=None, interpolation='nearest', alpha=None, aspect=None, **kwargs):
    plt.imshow(X, cmap=cmaplist(cmap), vmin=vmin, vmax=vmax, interpolation=interpolation, alpha=alpha, aspect=aspect, **kwargs)

def imsave(filename, arr, vmin=None, vmax=None, cmap='2', format=None, origin=None, dpi=300, **kwargs):
    plt.imsave(filename, arr, vmin=vmin, vmax=vmax, cmap=cmaplist(cmap), format=format, origin=origin, dpi=dpi, **kwargs)

# 重設值
def set_xydata(x=None, y=None):
    if x != None:
        plt.gca().set_xdata(x)
    if y != None:
        plt.gca().set_ydata(y)



# Basemap系列
class Basemap():
    import numpy as np
    def __init__(self,projection='cyl', llcrnrlon=0, llcrnrlat=0, urcrnrlon=0, urcrnrlat=0, resolution='l', area_thresh=1000, zone=None,**kwargs):
        self.projection = projection # merc:麥卡托, cyl:等距圓柱, mill:米勒, cea:等距圓錐, gall:加爾-彼得, lcc:蘭伯特等角, tmerc:橫麥卡托, stere:極射, npstere:北極極射, spstere:南極極射, aeqd:等距方位, poly:多邊形, nsper:自然地球
        if zone == 'taiwan':
            self.llcrnrlat = 21.5
            self.llcrnrlon = 118
            self.urcrnrlat = 26.5
            self.urcrnrlon = 123
        elif zone == 'china':
            self.llcrnrlat = 18
            self.llcrnrlon = 73
            self.urcrnrlat = 54
            self.urcrnrlon = 135
        elif zone == 'japan':
            self.llcrnrlat = 20
            self.llcrnrlon = 120
            self.urcrnrlat = 50
            self.urcrnrlon = 150
        elif zone == 'korea':
            self.llcrnrlat = 30
            self.llcrnrlon = 115
            self.urcrnrlat = 45
            self.urcrnrlon = 135
        elif zone == 'usa':
            self.llcrnrlat = 20
            self.llcrnrlon = -130
            self.urcrnrlat = 50
            self.urcrnrlon = -60
        elif zone == 'europe':
            self.llcrnrlat = 30
            self.llcrnrlon = -15
            self.urcrnrlat = 70
            self.urcrnrlon = 45
        elif zone == 'world':
            self.llcrnrlat = -90
            self.llcrnrlon = -180
            self.urcrnrlat = 90
            self.urcrnrlon = 180
        elif zone == 'africa':
            self.llcrnrlat = -40
            self.llcrnrlon = -20
            self.urcrnrlat = 40
            self.urcrnrlon = 60
        elif zone == 'australia':
            self.llcrnrlat = -50
            self.llcrnrlon = 100
            self.urcrnrlat = -10
            self.urcrnrlon = 160
        elif zone == 'russia':
            self.llcrnrlat = 40
            self.llcrnrlon = 20
            self.urcrnrlat = 80
            self.urcrnrlon = 180
        elif zone == 'india':
            self.llcrnrlat = 5
            self.llcrnrlon = 65
            self.urcrnrlat = 40
            self.urcrnrlon = 100
        elif zone == 'arabian':
            self.llcrnrlat = 10
            self.llcrnrlon = 20
            self.urcrnrlat = 40
            self.urcrnrlon = 70
        elif zone == 'oceania':
            self.llcrnrlat = -50
            self.llcrnrlon = 100
            self.urcrnrlat = 10
            self.urcrnrlon = 180
        elif zone == 'southamerica':
            self.llcrnrlat = -60
            self.llcrnrlon = -100
            self.urcrnrlat = 20
            self.urcrnrlon = -30
        elif zone == 'northamerica':
            self.llcrnrlat = 10
            self.llcrnrlon = -180
            self.urcrnrlat = 80
            self.urcrnrlon = -30
        elif zone == 'southeastasia':
            self.llcrnrlat = -10
            self.llcrnrlon = 90
            self.urcrnrlat = 30
            self.urcrnrlon = 160
        elif zone == 'eastasia':
            self.llcrnrlat = 10
            self.llcrnrlon = 100
            self.urcrnrlat = 60
            self.urcrnrlon = 160
        elif zone == 'maritimecontinent':
            self.llcrnrlat = -20
            self.llcrnrlon = 80
            self.urcrnrlat = 20
            self.urcrnrlon = 160
        elif zone == 'pacific':
            self.llcrnrlat = -60
            self.llcrnrlon = 100
            self.urcrnrlat = 60
            self.urcrnrlon = 280
        elif zone == 'atlantic':
            self.llcrnrlat = -60
            self.llcrnrlon = -100
            self.urcrnrlat = 60
            self.urcrnrlon = 20
        elif zone == 'indian':
            self.llcrnrlat = -60
            self.llcrnrlon = 20
            self.urcrnrlat = 30
            self.urcrnrlon = 120
        elif zone == 'arctic':
            self.llcrnrlat = 50
            self.llcrnrlon = -180
            self.urcrnrlat = 90
            self.urcrnrlon = 180
        elif zone == 'antarctic':
            self.llcrnrlat = -90
            self.llcrnrlon = -180
            self.urcrnrlat = -50
            self.urcrnrlon = 180
        elif zone == 'equitoralpacific':
            self.llcrnrlat = -20
            self.llcrnrlon = 120
            self.urcrnrlat = 20
            self.urcrnrlon = 280
        elif zone == 'nino34':
            self.llcrnrlat = -5
            self.llcrnrlon = 190
            self.urcrnrlat = 5
            self.urcrnrlon = 240
        elif zone == 'amazon':
            self.llcrnrlat = -20
            self.llcrnrlon = -80
            self.urcrnrlat = 10
            self.urcrnrlon = -40

        else:
            self.llcrnrlon = llcrnrlon
            self.llcrnrlat = llcrnrlat
            self.urcrnrlon = urcrnrlon
            self.urcrnrlat = urcrnrlat
        self.resolution = resolution # c>l>i>h>f
        self.area_thresh = area_thresh
        self.kwargs = kwargs
        self.basemap = Bp(projection=self.projection, llcrnrlon=self.llcrnrlon, llcrnrlat=self.llcrnrlat, urcrnrlon=self.urcrnrlon, urcrnrlat=self.urcrnrlat, resolution=self.resolution, area_thresh=self.area_thresh, **self.kwargs)


    # convert to projection coordinates
    def convert(self, lon, lat, inverse=False):
        x, y = self.basemap(lon, lat, inverse=inverse)


    # 繪製經緯線
    def drawparallels(self, parallels = np.arange(-90.,90,30.), labels=[1,0,0,0], fontsize=16, color='fg', linewidth=1.5, **kwargs):
        DP = self.basemap.drawparallels(parallels, labels=labels, fontsize=fontsize, color=colorlist(color), linewidth=linewidth, **kwargs)
    def drawmeridians(self, meridians = np.arange(-180.,180.,60.), labels=[0,0,0,1], fontsize=16, color='fg', linewidth=1.5, **kwargs):
        self.basemap.drawmeridians(meridians, labels=labels, fontsize=fontsize, color=colorlist(color), linewidth=linewidth, **kwargs)
    # 根據指定地區自動繪製經緯線
    def drawparallelsmeridians(self, zone='world', latinterval=15, loninterval=15, fontsize=16, color='fg', linewidth=1.5, **kwargs):
        import numpy as np
        if zone == 'taiwan':
            parallels = np.arange(21.5,26.5,latinterval)
            meridians = np.arange(118,123,loninterval)
        elif zone == 'china':
            parallels = np.arange(18,54,latinterval)
            meridians = np.arange(73,135,loninterval)
        elif zone == 'japan':
            parallels == np.arange(20,50,latinterval)
            meridians == np.arange(120,150,loninterval)
        elif zone == 'korea':
            parallels == np.arange(30,45,latinterval)
            meridians == np.arange(115,135,loninterval)
        elif zone == 'usa':
            parallels == np.arange(20,50,latinterval)
            meridians == np.arange(-130,-60,loninterval)
        elif zone == 'europe':
            parallels == np.arange(30,70,latinterval)
            meridians == np.arange(-15,45,loninterval)
        elif zone == 'world':
            parallels == np.arange(-90,90,latinterval)
            meridians == np.arange(-180,180,loninterval)
        elif zone == 'africa':
            parallels == np.arange(-40,40,latinterval)
            meridians == np.arange(-20,60,loninterval)
        elif zone == 'australia':
            parallels == np.arange(-50 ,-10,latinterval)
            meridians == np.arange(100,160,loninterval)
        elif zone == 'russia':
            parallels == np.arange(40,80,latinterval)
            meridians == np.arange(20,180,loninterval)
        elif zone == 'india':
            parallels == np.arange(5,40,latinterval)
            meridians == np.arange(65,100,loninterval)
        elif zone == 'arabian':
            parallels == np.arange(10,40,latinterval)
            meridians == np.arange(20,70,loninterval)
        elif zone == 'oceania':
            parallels == np.arange(-50,10,latinterval)
            meridians == np.arange(100,180,loninterval)
        elif zone == 'southamerica':
            parallels == np.arange(-60,20,latinterval)
            meridians == np.arange(-100,-30,loninterval)
        elif zone == 'northamerica':
            parallels == np.arange(10,80,latinterval)
            meridians == np.arange(-180,-30,loninterval)
        elif zone == 'southeastasia':
            parallels == np.arange(-10,30,latinterval)
            meridians == np.arange(90,160,loninterval)
        elif zone == 'eastasia':
            parallels == np.arange(10,60,latinterval)
            meridians == np.arange(100,160,loninterval)
        elif zone == 'maritimecontinent':
            parallels == np.arange(-20,20,latinterval)
            meridians == np.arange(80,160,loninterval)
        elif zone == 'pacific':
            parallels == np.arange(-60,60,latinterval)
            meridians == np.arange(100,280,loninterval)
        elif zone == 'atlantic':
            parallels == np.arange(-60,60,latinterval)
            meridians == np.arange(-100,20,loninterval)
        elif zone == 'indian':
            parallels == np.arange(-60,30,1,latinterval)
            meridians == np.arange(20,120,loninterval)
        elif zone == 'arctic':
            parallels == np.arange(50,90,latinterval)
            meridians == np.arange(-180,180,loninterval)
        elif zone == 'antarctic':
            parallels == np.arange(-90,-50,latinterval)
            meridians == np.arange(-180,180,loninterval)
        elif zone == 'equitoralpacific':
            parallels == np.arange(-20,20,latinterval)
            meridians == np.arange(120,280,loninterval)
        elif zone == 'nino34':
            parallels == np.arange(-5,5,latinterval)
            meridians == np.arange(190,240,loninterval)
        elif zone == 'amazon':
            parallels == np.arange(-20,10,latinterval)
            meridians == np.arange(-80,-40,loninterval)
            

        self.basemap.drawparallels(parallels, fontsize=fontsize, color=colorlist(color), linewidth=linewidth, **kwargs)
        self.basemap.drawmeridians(meridians, fontsize=fontsize, color=colorlist(color), linewidth=linewidth, **kwargs)





    # 繪製海岸線
    def drawcoastlines(self, linewidth=3, color='fg', **kwargs):
        self.basemap.drawcoastlines(linewidth=linewidth, color=colorlist(color), **kwargs)
    # 繪製國家
    def drawcountries(self, linewidth=2, color='fg', **kwargs):
        self.basemap.drawcountries(linewidth=linewidth, color=colorlist(color), **kwargs)
    # 繪製州界
    def drawstates(self, linewidth=1, color='fg', **kwargs):
        self.basemap.drawstates(linewidth=linewidth, color=colorlist(color), **kwargs)
    # 繪製河流
    def drawrivers(self, linewidth=1, color='bg', **kwargs):
        self.basemap.drawrivers(linewidth=linewidth, color=colorlist(color), **kwargs)
    # 繪製海陸mask
    def drawlsmask(self, land_color='rfg', ocean_color='bg', lakes=True, resolution='l', grid=5, **kwargs):
        self.basemap.drawlsmask(land_color=colorlist(land_color), ocean_color=colorlist(ocean_color), lakes=lakes, resolution=resolution, grid=grid, **kwargs)
    # 繪製陰影浮雕
    def shadedrelief(self, alpha=1, **kwargs):
        self.basemap.shadedrelief(alpha=alpha, **kwargs)
    # 繪製NASA海陸地形圖
    def etopo(self, alpha=1, **kwargs):
        self.basemap.etopo(alpha=alpha, **kwargs)
    # 繪製NASA海陸衛星圖
    def bluemarble(self, alpha=1, **kwargs):
        self.basemap.bluemarble(alpha=alpha, **kwargs)
    # 繪製陸地
    def fillcontinents(self, color='rfg', lake_color='bg', **kwargs):
        self.basemap.fillcontinents(color=colorlist(color), lake_color=colorlist(lake_color), **kwargs)
    # 繪製地圖邊界
    def drawmapboundary(self, fill_color='bg', color='fg', linewidth=3, **kwargs):
        self.basemap.drawmapboundary(fill_color=colorlist(fill_color), color=colorlist(color), linewidth=linewidth, **kwargs)
    # 轉換經緯度座標
    def transform(self, x, y):
        return self.basemap(x, y) 

        
    
    
    
    
    # 繪製點圖
    def plot(self, x, y, color='fg', linewidth=2, linestyle='-', label=getPLOTNO(), **kwargs):
        self.basemap.plot(x, y, color=colorlist(color), linewidth=linewidth, label=label, linestyle=linestyle, **kwargs)
    # 繪製等值線
    def contour(self, x, y, z, colors='fg', levels=10, linewidths=2, clabel=True, fontsize=12, color='fg', **kwargs):
        CS = self.basemap.contour(x, y, z, colors=colorlist(colors), levels=levels, linewidths=linewidths, **kwargs)
        if clabel == True:
            CL = CS.clabel(fontsize=fontsize, colors=colorlist(color), inline=True)
    # 繪製等值線填色圖
    def contourf(self, x, y, z, levels=10, cmap='2', contour=True, clabel=True,linewidths=1.5, color='fg', **kwargs):
        if contour == True:
            CS = self.basemap.contour(x, y, z, colors=colorlist(color), levels=levels, linewidths=linewidths)
        if clabel == True:
            CL = CS.clabel(fontsize=8, colors=colorlist(color), inline=True)
        self.basemap.contourf(x, y, z, cmap=cmaplist(cmap), **kwargs)
    # 繪製散點圖
    def scatter(self, x, y, color='fg', size=3, marker='o', linewidth=None, label=getSCATTERNO(), linestyle='-', **kwargs):
        self.basemap.scatter(x, y, color=colorlist(color), s=size, marker=marker, linewidth=linewidth, label=label, linestyle=linestyle, **kwargs)
    # 繪製colorbar
    def colorbar(self, ticks,label=' ', orientation='vertical',shrink=0.95, aspect=20, labelfontsize=16, font=fontpath, color='fg',**kwargs):
        CB = self.basemap.colorbar(orientation=orientation, shrink=shrink, aspect=aspect, label=label, **kwargs)
        CB.ax.tick_params(labelsize=labelfontsize, labelcolor=colorlist(color), color=colorlist(color))
        CB.ax.set_ylabel(label, fontproperties=fm.FontProperties(fname=font, size=labelfontsize), color=colorlist(color))
        CB.ax.set_yticks(ticks,ticks, fontproperties=fm.FontProperties(fname=font, size=labelfontsize))
        CB.ax.yaxis.set_tick_params(color=colorlist(color), labelcolor=colorlist(color))
        CB.outline.set_color(colorlist(color))
        CB.outline.set_linewidth(2)
    # 繪製圖例
    def legend(self, loc='best', fontsize=18, labelcolor='fg', frameon=True, framealpha=1, facecolor='rfg', edgecolor='fg', edgewidth=2 ,roundedge=False, **kwargs):
        LG = self.basemap.legend(loc=loc, fontsize=fontsize, labelcolor=colorlist(labelcolor), frameon=frameon, framealpha=framealpha, prop=fm.FontProperties(fname=fontpath, size=fontsize), facecolor=colorlist(facecolor), edgecolor=colorlist(edgecolor), **kwargs)
        if roundedge == False:
            LG.get_frame().set_boxstyle('Round', pad=0.2, rounding_size=-0.01)
        LG.get_frame().set_linewidth(edgewidth)
    # 繪製文字
    def text(self, x, y, text, color='fg', font=fontpath, fontsize=20, **kwargs):
        self.basemap.text(x, y, text, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)

    


# subplot系列
class initsubplots():
    def __init__(self, nrows=1, ncols=1, figsize=(8,10), style='default', background=True, **kwargs):
        self.row = 0 # 標示子圖的目標列
        self.col = 0 # 標示子圖的目標行
        self.ndim = 1 # 標示子圖的維度
        self.nrows = nrows
        self.ncols = ncols
        self.figsize = figsize
        self.kwargs = kwargs
        self.fig, self.ax = plt.subplots(nrows=self.nrows, ncols=self.ncols, figsize=self.figsize, **self.kwargs)
        global theme
        if style == 'default'or style == 'light_background' or style == 'light' or style == 'l':
            theme = 'default'
            plt.style.use(theme)
        elif style == 'dark_background' or style == 'dark' or style == 'd':
            theme = 'dark_background'
            plt.style.use(theme)
            self.fig.patch.set_facecolor(colorlist('#000000'))

        # 設定facecolor
        if background == True:
            if ncols == 1 and nrows == 1:
                self.ax.set_facecolor(colorlist('bg'))
            elif ncols == 1 and nrows != 1:
                self.ax[0].set_facecolor(colorlist('bg'))
                for row in range(1,nrows):
                    self.ax[row].set_facecolor(colorlist('bg'))
            elif ncols != 1 and nrows == 1:
                self.ax[0].set_facecolor(colorlist('bg'))
                for col in range(1,ncols):
                    self.ax[col].set_facecolor(colorlist('bg'))
            else:
                for row in range(nrows):
                    for col in range(ncols):
                        self.ax[row,col].set_facecolor(colorlist('bg'))
    
        

        else: pass
    
    def __getitem__(self, rowcol):
        if type(rowcol) == int: # 只有一個值時，預設為row
            self.ndim = 1
            self.row = rowcol
            self.col = 0
        else:
            self.ndim = 2
            self.row = rowcol[0]
            self.col = rowcol[1]
        return self

    def get_figure_and_axes(self):
        return self.fig, self.ax    
    def get_figure(self):
        return self.fig
    def get_axes(self):
        return self.ax
    
    # 排版
    def tight_layout(self, pad=1.08, h_pad=None, w_pad=None, rect=None):
        plt.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

    def subplot_tool(self):
        plt.subplot_tool()

    # 繪製折線圖
    def plot(self, x, y, color='fg', linewidth=2, linestyle='-', label=getPLOTNO(),**kwargs):
        if self.ndim == 1:
            self.ax[self.row].plot(x, y, color=colorlist(color), linewidth=linewidth, label=label,linestyle=linestyle, **kwargs)
        else:
            self.ax[self.row,self.col].plot(x, y, color=colorlist(color), linewidth=linewidth, label=label,linestyle=linestyle, **kwargs)
    # 繪製點圖
    def scatter(self, x, y, color='fg', size=3, marker='o', linewidth=None, label=getSCATTERNO(), linestyle='-', **kwargs):
        if self.ndim == 1:
            self.ax[self.row].scatter(x, y, color=colorlist(color), s=size, marker=marker, linewidth=linewidth, label=label, linestyle=linestyle, **kwargs)
        else:
            self.ax[self.row,self.col].scatter(x, y, color=colorlist(color), s=size, marker=marker, linewidth=linewidth, label=label, linestyle=linestyle, **kwargs)
    # 繪製長條圖
    def bar(self, x, y, width=0.8, color='1', edgecolor='fg', linewidth=3, label=getBARNO(), **kwargs):
        if self.ndim == 1:
            self.ax[self.row].bar(x, y, width=width,color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label, **kwargs)
        else:
            self.ax[self.row,self.col].bar(x, y, width=width,color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label, **kwargs)
    # 繪製橫向長條圖
    def barh(self, x, y, width=0.8, color='1', edgecolor='fg', linewidth=3, label=getBARHNO(), **kwargs):
        if self.ndim == 1:
            self.ax[self.row].barh(x, y, height=width, color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label, **kwargs)
        else:
            self.ax[self.row,self.col].barh(x, y, height=width, color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label, **kwargs)
    # 繪製直方圖
    def hist(self, x, bins=5, color='1', edgecolor='fg', linewidth=3, label=getHISTNO(), **kwargs):
        if self.ndim == 1:
            self.ax[self.row].hist(x, bins=bins, color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label,**kwargs)
        else:
            self.ax[self.row,self.col].hist(x, bins=bins, color=colorlist(color), edgecolor=colorlist(edgecolor), linewidth=linewidth, label=label,**kwargs)
    # 繪製散點圖
    def scatter(self, x, y, color='fg', size=3, marker='o', linewidth=None, label=getSCATTERNO(), linestyle='-', **kwargs):
        if self.ndim == 1:
            self.ax[self.row].scatter(x, y, color=colorlist(color), s=size, marker=marker, linewidth=linewidth, label=label, linestyle=linestyle, **kwargs)
        else:
            self.ax[self.row,self.col].scatter(x, y, color=colorlist(color), s=size, marker=marker, linewidth=linewidth, label=label, linestyle=linestyle, **kwargs)
    # 繪製polar圖
    def polar(self, theta, r, color='fg', linewidth=2, linestyle='-', **kwargs):
        if self.ndim == 1:
            self.ax[self.row].polar(theta, r, color=colorlist(color), linewidth=linewidth, linestyle=linestyle, **kwargs)
        else:
            self.ax[self.row,self.col].polar(theta, r, color=colorlist(color), linewidth=linewidth, linestyle=linestyle, **kwargs)
    
    # 繪製等值線
    def contour(self, x, y, z, colors='fg', levels=10, linewidths=2, clabel=True, fontsize=12*fontscale, color='fg', **kwargs):
        if self.ndim == 1:
            CS = self.ax[self.row].contour(x, y, z, colors=colorlist(colors), levels=levels, linewidths=linewidths, **kwargs)
            if clabel == True:
                CL = CS.clabel(fontsize=fontsize, colors=colorlist(color), inline=True)
            self.z = z
            self.levels = levels
        else:
            CS = self.ax[self.row,self.col].contour(x, y, z, colors=colorlist(colors), levels=levels, linewidths=linewidths, **kwargs)
            if clabel == True:
                CL = CS.clabel(fontsize=fontsize, colors=colorlist(color), inline=True)
            self.z = z
            self.levels = levels
    # 繪製等值線填色圖
    def contourf(self, x, y, z, levels=10, cmap='28', contour=True, clabel=True,linewidths=1.5, color='fg', vmin='auto', vmax='auto', **kwargs):
        import numpy as np
        # 傳出Z值和levels值
        global subcontour_vmin, subcontour_vmax, subcontour_levels, CS
        subcontour_levels = levels
        if vmin == 'auto':
            vmin = np.floor(z.min()/10**(len(str(int(z.min())))-2))*10**(len(str(int(z.min())))-2)
            subcontour_vmin = vmin
        else:
            subcontour_vmin = vmin
        if vmax == 'auto':
            vmax = np.ceil(z.max()/10**(len(str(int(z.max())))-2))*10**(len(str(int(z.max())))-2)
            subcontour_vmax = vmax
        else:
            subcontour_vmax = vmax
        if contour == True:
            if self.ndim == 1:
                CS = self.ax[self.row].contour(x, y, z, colors=colorlist(color), levels=levels, linewidths=linewidths)
            else:
                CS = self.ax[self.row,self.col].contour(x, y, z, colors=colorlist(color), levels=levels, linewidths=linewidths)
        if clabel == True:
            CL = CS.clabel(fontsize=8*fontscale, colors=colorlist(color), inline=True)
        if self.ndim == 1:
            self.ax[self.row].contourf(x, y, z, cmap=cmaplist(cmap), vmin=vmin, vmax=vmax, **kwargs)
        else:
            self.ax[self.row,self.col].contourf(x, y, z, cmap=cmaplist(cmap), **kwargs)
    # 繪製圖例
    def legend(self, loc='best', fontsize=18*fontscale, labelcolor='fg', frameon=True, framealpha=1, facecolor='rfg', edgecolor='fg', edgewidth=2 ,roundedge=False, **kwargs):
        if self.ndim == 1:
            LG = self.ax[self.row].legend(loc=loc, fontsize=fontsize, labelcolor=colorlist(labelcolor), frameon=frameon, framealpha=framealpha, prop=fm.FontProperties(fname=fontpath, size=fontsize), facecolor=colorlist(facecolor), edgecolor=colorlist(edgecolor), **kwargs)
        else:
            LG = self.ax[self.row,self.col].legend(loc=loc, fontsize=fontsize, labelcolor=colorlist(labelcolor), frameon=frameon, framealpha=framealpha, prop=fm.FontProperties(fname=fontpath, size=fontsize), facecolor=colorlist(facecolor), edgecolor=colorlist(edgecolor), **kwargs)
        if roundedge == False:
            LG.get_frame().set_boxstyle('Round', pad=0.2, rounding_size=-0.01)
        LG.get_frame().set_linewidth(edgewidth)
    # 繪製文字
    def text(self, x, y, text, color='fg', font=fontpath, fontsize=20*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].text(x, y, text, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
        else:
            self.ax[self.row,self.col].text(x, y, text, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    # 繪製colorbar
    def colorbar(self, ticks='auto',label=' ', orientation='vertical',shrink=0.95, aspect=20, labelfontsize=16*fontscale, font=fontpath, extend='neither',color='fg',**kwargs):
        if ticks == 'auto':
            import numpy as np
            # 獲取z,levels，並計算ticks
            ticks = []
            for i in range(subcontour_levels):
                ticks.append(subcontour_vmin + (subcontour_vmax-subcontour_vmin)/subcontour_levels*i)
            if self.ndim == 1:
                CS.set_clim(subcontour_vmin, subcontour_vmax)
            else:
                CS.set_clim(subcontour_vmin, subcontour_vmax)
            extend = 'both'
        else:
            ticks = ticks
        
        print('\033[33m'+'[WARNING] Some bugs have been reported when using colorbar in subplots.'+'\033[0m')
        if self.ndim == 1:
            CB = self.ax[self.row].colorbar(orientation=orientation, shrink=shrink, aspect=aspect, label=label, extend=extend, **kwargs)
            CB.ax[self.row].tick_params(labelsize=labelfontsize, labelcolor=colorlist(color), color=colorlist(color))
            CB.ax[self.row].set_ylabel(label, fontproperties=fm.FontProperties(fname=font, size=labelfontsize), color=colorlist(color))
            CB.ax[self.row].set_yticks(ticks,ticks, fontproperties=fm.FontProperties(fname=font, size=labelfontsize))
            CB.ax[self.row].yaxis.set_tick_params(color=colorlist(color), labelcolor=colorlist(color))
            CB.outline.set_color(colorlist(color))
            CB.outline.set_linewidth(2)
        else:
            CB = self.ax[self.row,self.col].colorbar(orientation=orientation, shrink=shrink, aspect=aspect, label=label, extend=extend, **kwargs)
            CB.ax[self.row,self.col].tick_params(labelsize=labelfontsize, labelcolor=colorlist(color), color=colorlist(color))
            CB.ax[self.row,self.col].set_ylabel(label, fontproperties=fm.FontProperties(fname=font, size=labelfontsize), color=colorlist(color))
            CB.ax[self.row,self.col].set_yticks(ticks,ticks, fontproperties=fm.FontProperties(fname=font, size=labelfontsize))
            CB.ax[self.row,self.col].yaxis.set_tick_params(color=colorlist(color), labelcolor=colorlist(color))
            CB.outline.set_color(colorlist(color))
            CB.outline.set_linewidth(2)

    def clim(self, vmin=None, vmax=None):
        if self.ndim == 1:
            self.ax[self.row].set_clim(vmin, vmax)
        else:
            self.ax[self.row,self.col].set_clim(vmin, vmax)
    
    # 繪製xticks、yticks
    def xticks(self, ticks, labels, color='fg', font=fontpath, fontsize=18*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_xticks(ticks, labels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
        else:
            self.ax[self.row,self.col].set_xticks(ticks, labels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    def yticks(self, ticks, labels, color='fg', font=fontpath, fontsize=18*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_yticks(ticks, labels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
        else:
            self.ax[self.row,self.col].set_yticks(ticks, labels, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    def xlabel(self, xlabel, color='fg', font=fontpath, fontsize=24*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_xlabel(xlabel, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
        else:
            self.ax[self.row,self.col].set_xlabel(xlabel, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    def ylabel(self, ylabel, color='fg', font=fontpath, fontsize=24*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_ylabel(ylabel, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
        else:
            self.ax[self.row,self.col].set_ylabel(ylabel, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    def spines(self, top=True, right=True, bottom=True, left=True, color='fg', linewidth=3, **kwargs):
        if self.ndim == 1:
            if top: self.ax[self.row].spines['top'].set_visible(top)
            if right: self.ax[self.row].spines['right'].set_visible(right)
            if bottom: self.ax[self.row].spines['bottom'].set_visible(bottom)
            if left: self.ax[self.row].spines['left'].set_visible(left)
            if top: self.ax[self.row].spines['top'].set_color(colorlist(color))
            if right: self.ax[self.row].spines['right'].set_color(colorlist(color))
            if bottom: self.ax[self.row].spines['bottom'].set_color(colorlist(color))
            if left: self.ax[self.row].spines['left'].set_color(colorlist(color))
            if top: self.ax[self.row].spines['top'].set_linewidth(linewidth)
            if right: self.ax[self.row].spines['right'].set_linewidth(linewidth)
            if bottom: self.ax[self.row].spines['bottom'].set_linewidth(linewidth)
            if left: self.ax[self.row].spines['left'].set_linewidth(linewidth)
        else:
            if top: self.ax[self.row,self.col].spines['top'].set_visible(top)
            if right: self.ax[self.row,self.col].spines['right'].set_visible(right)
            if bottom: self.ax[self.row,self.col].spines['bottom'].set_visible(bottom)
            if left: self.ax[self.row,self.col].spines['left'].set_visible(left)
            if top: self.ax[self.row,self.col].spines['top'].set_color(colorlist(color))
            if right: self.ax[self.row,self.col].spines['right'].set_color(colorlist(color))
            if bottom: self.ax[self.row,self.col].spines['bottom'].set_color(colorlist(color))
            if left: self.ax[self.row,self.col].spines['left'].set_color(colorlist(color))
            if top: self.ax[self.row,self.col].spines['top'].set_linewidth(linewidth)
            if right: self.ax[self.row,self.col].spines['right'].set_linewidth(linewidth)
            if bottom: self.ax[self.row,self.col].spines['bottom'].set_linewidth(linewidth)
            if left: self.ax[self.row,self.col].spines['left'].set_linewidth(linewidth)
    # 繪製標題
    def title(self, title, color='fg', font=fontpath_bold, fontsize=24*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_title(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
        else:
            self.ax[self.row,self.col].set_title(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    def lefttitle(self, title, color='1', font=fontpath_bold, fontsize=24*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_title(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs, loc='left')
        else:
            self.ax[self.row,self.col].set_title(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs, loc='left')
    def righttitle(self, title, color='2', font=fontpath_bold, fontsize=24*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_title(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs, loc='right')
        else:
            self.ax[self.row,self.col].set_title(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs, loc='right')
    # 其他
    def grid(self, b=None, which='major', axis='both', color='fg', linestyle=':', linewidth=0.5, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].grid(b, which=which, axis=axis, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)
        else:
            self.ax[self.row,self.col].grid(b, which=which, axis=axis, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)
    def xlim(self, xmin=None, xmax=None, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_xlim(xmin, xmax, **kwargs)
        else:    
            self.ax[self.row,self.col].set_xlim(xmin, xmax, **kwargs)
    def ylim(self, ymin=None, ymax=None, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].set_ylim(ymin, ymax, **kwargs)
        else:
            self.ax[self.row,self.col].set_ylim(ymin, ymax, **kwargs)
    def hidespines(self, top=True, right=True, bottom=True, left=True):
        if self.ndim == 1:
            if top: self.ax[self.row].spines['top'].set_visible(False)
            if right: self.ax[self.row].spines['right'].set_visible(False)
            if bottom: self.ax[self.row].spines['bottom'].set_visible(False)
            if left: self.ax[self.row].spines['left'].set_visible(False)
        else:
            if top: self.ax[self.row,self.col].spines['top'].set_visible(False)
            if right: self.ax[self.row,self.col].spines['right'].set_visible(False)
            if bottom: self.ax[self.row,self.col].spines['bottom'].set_visible(False)
            if left: self.ax[self.row,self.col].spines['left'].set_visible(False)
    def xaxisposition(self, yposition, xaxis='bottom',**kwargs):
        if self.ndim == 1:
            self.ax[self.row].xaxis.set_ticks_position(xaxis)
            self.ax[self.row].xaxis.set_label_position(yposition)
        else:
            self.ax[self.row,self.col].xaxis.set_ticks_position(xaxis)
            self.ax[self.row,self.col].xaxis.set_label_position(yposition)
    def yaxisposition(self, xposition, yaxis='left',**kwargs):
        if self.ndim == 1:
            self.ax[self.row].yaxis.set_ticks_position(yaxis)
            self.ax[self.row].yaxis.set_label_position(xposition)
        else:
            self.ax[self.row,self.col].yaxis.set_ticks_position(yaxis)
            self.ax[self.row,self.col].yaxis.set_label_position(xposition)
    def axhline(self, y=0, color='fg', linestyle='dashed', linewidth=3, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].axhline(y=y, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)
        else:
            self.ax[self.row,self.col].axhline(y=y, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)
    def axvline(self, x=0, color='fg', linestyle='dashed', linewidth=3, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].axvline(x=x, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)
        else:
            self.ax[self.row,self.col].axvline(x=x, color=colorlist(color), linestyle=linestyle, linewidth=linewidth, **kwargs)
    def annotate(self, text, xy, xytext, arrowprops=dict(facecolor='black', shrink=0.05), color='fg', font=fontpath, fontsize=20*fontscale, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].annotate(text, xy=xy, xytext=xytext, arrowprops=arrowprops, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
        else:
            self.ax[self.row,self.col].annotate(text, xy=xy, xytext=xytext, arrowprops=arrowprops, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)
    def fill_between(self, x, y1, y2=0, where=None, interpolate=False, step=None, color='fg', alpha=0.5, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].fill_between(x, y1, y2=y2, where=where, interpolate=interpolate, step=step, color=colorlist(color), alpha=alpha, **kwargs)
        else:
            self.ax[self.row,self.col].fill_between(x, y1, y2=y2, where=where, interpolate=interpolate, step=step, color=colorlist(color), alpha=alpha, **kwargs)
    def fill_betweenx(self, y, x1, x2=0, where=None, interpolate=False, step=None, color='fg', alpha=0.5, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].fill_betweenx(y, x1, x2=x2, where=where, interpolate=interpolate, step=step, color=colorlist(color), alpha=alpha, **kwargs)
        else:
            self.ax[self.row,self.col].fill_betweenx(y, x1, x2=x2, where=where, interpolate=interpolate, step=step, color=colorlist(color), alpha=alpha, **kwargs)
    def ticksall(self, labeltop=True, labelbottom=True, labelleft=True, labelright=True, **kwargs):
        if self.ndim == 1:
            if labeltop: self.ax[self.row].tick_params(labeltop=labeltop, **kwargs)
            if labelbottom: self.ax[self.row].tick_params(labelbottom=labelbottom, **kwargs)
            if labelleft: self.ax[self.row].tick_params(labelleft=labelleft, **kwargs)
            if labelright: self.ax[self.row].tick_params(labelright=labelright, **kwargs)
        else:
            if labeltop: self.ax[self.row,self.col].tick_params(labeltop=labeltop, **kwargs)
            if labelbottom: self.ax[self.row,self.col].tick_params(labelbottom=labelbottom, **kwargs)
            if labelleft: self.ax[self.row,self.col].tick_params(labelleft=labelleft, **kwargs)
            if labelright: self.ax[self.row,self.col].tick_params(labelright=labelright, **kwargs)

    def invert_xaxis(self):
        if self.ndim == 1:
            self.ax[self.row].invert_xaxis()
        else:
            self.ax[self.row,self.col].invert_xaxis()
    
    def invert_yaxis(self):
        if self.ndim == 1:
            self.ax[self.row].invert_yaxis()
        else:
            self.ax[self.row,self.col].invert_yaxis()

    # 共用軸
    def twinx(self):
        # print the cautions that some bugs have been reported when using twinx() and twiny(), using yellow color
        print('\033[33m'+'[WARNING] Some bugs have been reported when using twinx() or twiny().'+'\033[0m')
        if self.ndim == 1:
            self.ax[self.row].twinx()
        else:
            self.ax[self.row,self.col].twinx()
    
    def twiny(self):
        print('\033[33m'+'[WARNING] Some bugs have been reported when using twinx() or twiny().'+'\033[0m')
        if self.ndim == 1:
            self.ax[self.row].twiny()
        else:
            self.ax[self.row,self.col].twiny()

    # 大標題
    def suptitle(self, title, color='fg', font=fontpath_bold,fontsize=30, **kwargs):
        self.fig.suptitle(title, color=colorlist(color), fontproperties=fm.FontProperties(fname=font, size=fontsize), **kwargs)

    # 挪出額外空間
    def adjust(self, left=None, bottom=None, right=None, top=None, wspace=None, hspace=None):
        plt.subplots_adjust(left=left, bottom=bottom, right=right, top=top, wspace=wspace, hspace=hspace)
    # 新增軸
    def addaxes(self, position, **kwargs):
        if self.ndim == 1:
            self.ax[self.row].add_axes(position, **kwargs)
        else:
            self.ax[self.row,self.col].add_axes(position, **kwargs)

    # 重設值
    def set_xydata(self, x=None, y=None):
        if self.ndim == 1:
            if x != None: self.ax[self.row].set_xdata(x)
            if y != None: self.ax[self.row].set_ydata(y)
        else:
            if x != None: self.ax[self.row,self.col].set_xdata(x)
            if y != None: self.ax[self.row,self.col].set_ydata(y)
    
    
# 動畫
from matplotlib.widgets import Slider, Button, RadioButtons
def pause(interval=0.01):
    plt.pause(interval)

def normalize(data, vmin=None, vmax=None):
    plt.Normalize(data, vmin=vmin, vmax=vmax)

def slider(ax, label, valmin, valmax, valinit=0, valfmt='%1.2f', valstep=None, orientation='horizontal', **kwargs):
    return Slider(ax, label, valmin, valmax, valinit=valinit, valfmt=valfmt, valstep=valstep, orientation=orientation, **kwargs)


# https://matplotlib.org/stable/gallery/widgets/slider_demo.html




    


