Beispiel #1
0
def slope(data,
          kind='interval',
          marker='%0.f',
          color=None,
          title='',
          font_family='GillSans',
          font_size=12,
          width=12,
          height=8,
          ax=None,
          savename=None,
          dpi=150,
          wspace=None, ):
    """====
Slope
====

Definition: slope(data,kind=['interval','ordinal'],height,width,font_size,savename,color,title)

----

Plot Slope plot Tufte Style
:class:`matplotlib.figure.Figure object`. 

Parameters
----------
data : pandas dataFrame
    index indicate the categories
    columns indicate time / period

    
marker style : str, format
            Format to present the data
            default '%0.f'

label_position : str ['ordinal', 'interval']
            how to position labels.
            Interval will place them according to their values
            Ordinal will place them according to their rank

font_family     : font family name installed on your system
            
font_size : set the font size
            in case your data have more lines than you can have text lines of text
            in your figure height, data will be binned to fit 
            (default 12)

height    :   Figure height in inches (default 12)

with      :   Figure width in inches (default 8)

savename     :  file path to save your graph

color     : a dictionary {label:color} 
 
title      : a title at the bottom of the graph

Examples
--------

>>> data = pd.read_csv(os.path.join('Data','EU_GDP_2007_2013.csv'),index_col=0,na_values='-')
>>> f = slope(data/1000,kind='interval',height= 12,width=20,font_size=12,savename='EU_interval.png',title = u'title')  

    
    """
    font = FontProperties(font_family)
    font.set_size(font_size)
    bx = None

    df = data.copy()

    cols = df.columns
    df['__label__'] = df.index
    df['__order__'] = range(len(df.index))

    if kind == 'stack':
        f, axarr = plt.subplots(len(df), len(cols) - 1,
                                facecolor="w",
                                squeeze=False,
                                sharex=True)  #,sharey=True)
    else:
        #f, axarr = plt.subplots(2,len(cols)-1,facecolor="w",squeeze=True,figsize=(width,height),dpi=30)#,sharex=True)#,sharey=True)
        f = plt.figure(figsize=(width, height), dpi=30, facecolor="w")
        gs = gridspec.GridSpec(
            nrows=20,
            ncols=len(cols) - 1
        )  # the 20 rows are just there to provide enought space for the title
        axarr = []
        axarr_X = []

        for i in range(len(cols) - 1):
            axarr.append(plt.subplot(gs[:19, i]))
            axarr_X.append(plt.subplot(gs[19, i]))

    axarr = np.array(axarr)
    axarr_X = np.array(axarr_X)
    renderer = f.canvas.get_renderer()
    data_range = [data.min().min(), data.max().max()]
    fh = f.get_figheight()
    fw = f.get_figwidth()
    fdpi = f.get_dpi()

    nt = fh // (font.get_size() / 72) / 2
    res = np.diff(data_range)[0] / nt * 2

    if not hasattr(axarr, 'transpose'):
        axarr = [axarr]

    for i in range((len(cols) - 1)):
        ax = axarr[i]

        axarr_X[i].yaxis.set_tick_params(width=0)
        axarr_X[i].xaxis.set_tick_params(width=0)
        """
        from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker
        # orange label
        obox1 = TextArea("orange - ", textprops=dict(color="k", size=15))
        obox2 = TextArea("5 ", textprops=dict(color="b", size=15))
        obox3 = TextArea(": ", textprops=dict(color="k", size=15))
        obox4 = TextArea("10 ", textprops=dict(color="r", size=15))
        
        orangebox = HPacker(children=[obox1, obox2, obox3, obox4],
                            align="center", pad=0, sep=5)
                    """

        if kind == 'interval':
            labelsL = df.groupby(pd.cut(df[cols[i]], nt))['__label__'].agg(
                ', '.join).dropna()
            labelsR = df.groupby(pd.cut(df[cols[i + 1]], nt))['__label__'].agg(
                ', '.join).dropna()

            yPos_L = df.groupby(pd.cut(df[cols[i]],
                                       nt))[cols[i]].mean().dropna()
            yPos_R = df.groupby(pd.cut(df[cols[i + 1]],
                                       nt))[cols[i + 1]].mean().dropna()

            yMark_L = df.groupby(pd.cut(df[cols[i]],
                                        nt))[cols[i]].mean().dropna()
            yMark_R = df.groupby(pd.cut(df[cols[i + 1]],
                                        nt))[cols[i + 1]].mean().dropna()

            yPos_ = df[[cols[i], cols[i + 1]]]

        if kind == 'ordinal':

            yPos_L = df[[cols[i]]].rank(ascending=False).applymap(
                lambda el: round(el + 0.1))
            yPos_R = df[[cols[i + 1]]].rank(ascending=False).applymap(
                lambda el: round(el + 0.1))
            yMark_L = df.groupby(cols[i])[cols[i]].mean().dropna()
            yMark_R = df.groupby(cols[i + 1])[cols[i + 1]].mean().dropna()
            yMark_L.sort(ascending=False)
            yMark_R.sort(ascending=False)
            #print yMark_L

            labelsL = df.groupby(yPos_L[cols[i]].values)['__label__'].agg(
                ', '.join)
            labelsR = df.groupby(yPos_R[cols[i + 1]].values)['__label__'].agg(
                ', '.join)
            yPos_L.sort(cols[i], inplace=True)
            yPos_R.sort(cols[i + 1], inplace=True)

            yPos_ = yPos_L.join(yPos_R)  #.sort(cols[i],inplace=True)
#        if i == 1: 
#            #print yPos_.T
#            print labelsL
#            #yPos_   =  df[[cols[i],cols[i+1]]]
#

#        if kind=='stack' : 
#            
#            yPos_L = df[cols[i]].rank()
#            yPos_R = df[cols[i+1]].rank()
#            
#            labelsL = df.groupby(yPos_L)['__label__'].agg(', '.join) 
#            labelsR = df.groupby(yPos_R)['__label__'].agg(', '.join) 
#            
#            yPos_ = yPos_L.join(yPos_R)            
#            
#            yPos_L  =  labelsL.index.values
#            yPos_R  =  labelsR.index.values

        if kind == "stack":
            ax.plot([0, 1], [0, 1], color='k', alpha=0.4)
        else:
            #print yPos_
            lines = ax.plot(yPos_.T, color='k', alpha=0.4)
            ax.spines['bottom'].set_visible(False)
            ax.xaxis.set_ticks_position('bottom')

            if kind == "ordinal":
                ax.set_ybound(lower=1, upper=len(yPos_))
            if kind == "interval":
                ax.set_ybound(lower=data.min().min(), upper=data.max().max())

                #ax.set_xbound(lower=0,upper=1)

            ax.set_xticklabels([])
            #print cols[i]
            axarr_X[i].set_yticks([1])
            axarr_X[i].set_xticklabels([])
            axarr_X[i].set_yticklabels([str(cols[i])], fontproperties=font)
            #ax.set_xticklabels([str(cols[i])],horizontalalignment='center',fontproperties=font)
            #            ax.spines['top'].set_visible(False)
            #            ax.spines['right'].set_visible(False)
            #            ax.spines['left'].set_visible(False)

            if marker:
                labelsL_str = [item[1] + (marker % item[0]).rjust(6)
                               for item in zip(yMark_L.values, labelsL.values)]
                labelsR_str = [(marker % item[0]).ljust(6) + item[1]
                               for item in zip(yMark_R.values, labelsR.values)]
                ylabelsL_str = map(lambda el: marker % el, yMark_L.values)
                ylabelsR_str = map(lambda el: marker % el, yMark_R.values)
            else:
                labelsL_str = labelsL.values
                labelsR_str = labelsR.values
                ylabelsL_str = map(lambda el: u'', yPos_L.values)
                ylabelsR_str = map(lambda el: u'', yPos_R.values)

            if i == 0:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels(labelsL_str, fontproperties=font)
            elif marker:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels(ylabelsL_str,
                                   fontproperties=font,
                                   ha='right'
                                   )  #ha='center')#,backgroundcolor='w')
            else:
                plt.setp(ax.get_yticklabels(), visible=False)
                wspace = 0

            if i == len(cols) - 2:
                bx = ax.twinx()

                bx.set_ybound(ax.get_ybound())
                bx.set_yticks(yPos_R.values)
                bx.set_yticklabels(labelsR_str, fontproperties=font)
                bx.yaxis.set_tick_params(width=0)

                bx_X = axarr_X[i].twinx()
                bx_X.set_xticklabels([])
                bx_X.set_yticks([1])
                bx_X.yaxis.set_tick_params(width=0)
                bx_X.set_yticklabels([str(cols[i + 1])], fontproperties=font)

            if kind == 'ordinal':
                ax.invert_yaxis()
                if bx:
                    bx.invert_yaxis()

            if color:

                for tl in ax.yaxis.get_ticklabels():
                    try:
                        for kw, c in color.items():

                            if kw in tl.get_text():
                                tl.set_color(c)

                    except:
                        print('fail')
                        pass
                if bx:
                    for tl in bx.yaxis.get_ticklabels():
                        try:
                            for kw, c in color.items():

                                if kw in tl.get_text():
                                    tl.set_color(c)
                        except:
                            pass

            if color:
                for kw, c in color.items():
                    for j, lab__ in enumerate(yPos_.index):
                        if kw in lab__:
                            lines[j].set_color(c)
                            lines[j].set_linewidth(2)
                            lines[j].set_alpha(0.6)

                            for kk, tic_pos in enumerate(
                                ax.yaxis.get_ticklocs()):

                                if yPos_.values[j][0] == tic_pos:

                                    ax.yaxis.get_ticklabels()[kk].set_color(c)

            ax.yaxis.set_tick_params(width=0)
            ax.xaxis.set_tick_params(width=0)

            ax.xaxis.grid(False)

    f.suptitle(title, x=0.5, y=0.02, fontproperties=font)
    plt.tight_layout()

    for ax in f.axes:
        ax.spines['top'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['left'].set_visible(False)

    tw = ax.yaxis.get_text_widths(renderer)[0]
    #dpi = f.properties()['dpi']
    if wspace == 0:
        pass
    else:
        #wspace = tw/dpi
        aw = ax.get_tightbbox(renderer).width
        wspace = tw / aw * 1.4

    #f.subplots_adjust(wspace=wspace)
    f.subplots_adjust(wspace=wspace)

    if kind == "stack":
        f.subplots_adjust(wspace=wspace, hspace=0)
    else:
        pass

    if savename:
        f.savefig(os.path.join('Output', savename), dpi=dpi)
        #os.system("start " + savename)

    return f
Beispiel #2
0
def slope(
    data,
    kind='interval',
    marker='%0.f',
    color=None,
    title='',
    font_family='GillSans',
    font_size=12,
    width=12,
    height=8,
    ax=None,
    savename=None,
    dpi=150,
    wspace=None,
):
    """====
Slope
====

Definition: slope(data,kind=['interval','ordinal'],height,width,font_size,savename,color,title)

----

Plot Slope plot Tufte Style
:class:`matplotlib.figure.Figure object`. 

Parameters
----------
data : pandas dataFrame
    index indicate the categories
    columns indicate time / period

    
marker style : str, format
            Format to present the data
            default '%0.f'

label_position : str ['ordinal', 'interval']
            how to position labels.
            Interval will place them according to their values
            Ordinal will place them according to their rank

font_family     : font family name installed on your system
            
font_size : set the font size
            in case your data have more lines than you can have text lines of text
            in your figure height, data will be binned to fit 
            (default 12)

height    :   Figure height in inches (default 12)

with      :   Figure width in inches (default 8)

savename     :  file path to save your graph

color     : a dictionary {label:color} 
 
title      : a title at the bottom of the graph

Examples
--------

>>> data = pd.read_csv(os.path.join('Data','EU_GDP_2007_2013.csv'),index_col=0,na_values='-')
>>> f = slope(data/1000,kind='interval',height= 12,width=20,font_size=12,savename='EU_interval.png',title = u'title')  

    
    """
    font = FontProperties(font_family)
    font.set_size(font_size)
    bx = None

    df = data.copy()

    cols = df.columns
    df['__label__'] = df.index
    df['__order__'] = range(len(df.index))

    if kind == 'stack':
        f, axarr = plt.subplots(len(df),
                                len(cols) - 1,
                                facecolor="w",
                                squeeze=False,
                                sharex=True)  #,sharey=True)
    else:
        #f, axarr = plt.subplots(2,len(cols)-1,facecolor="w",squeeze=True,figsize=(width,height),dpi=30)#,sharex=True)#,sharey=True)
        f = plt.figure(figsize=(width, height), dpi=30, facecolor="w")
        gs = gridspec.GridSpec(
            nrows=20, ncols=len(cols) - 1
        )  # the 20 rows are just there to provide enought space for the title
        axarr = []
        axarr_X = []

        for i in range(len(cols) - 1):
            axarr.append(plt.subplot(gs[:19, i]))
            axarr_X.append(plt.subplot(gs[19, i]))

    axarr = np.array(axarr)
    axarr_X = np.array(axarr_X)
    renderer = f.canvas.get_renderer()
    data_range = [data.min().min(), data.max().max()]
    fh = f.get_figheight()
    fw = f.get_figwidth()
    fdpi = f.get_dpi()

    nt = fh // (font.get_size() / 72) / 2
    res = np.diff(data_range)[0] / nt * 2

    if not hasattr(axarr, 'transpose'):
        axarr = [axarr]

    for i in range((len(cols) - 1)):
        ax = axarr[i]

        axarr_X[i].yaxis.set_tick_params(width=0)
        axarr_X[i].xaxis.set_tick_params(width=0)
        """
        from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker
        # orange label
        obox1 = TextArea("orange - ", textprops=dict(color="k", size=15))
        obox2 = TextArea("5 ", textprops=dict(color="b", size=15))
        obox3 = TextArea(": ", textprops=dict(color="k", size=15))
        obox4 = TextArea("10 ", textprops=dict(color="r", size=15))
        
        orangebox = HPacker(children=[obox1, obox2, obox3, obox4],
                            align="center", pad=0, sep=5)
                    """

        if kind == 'interval':
            labelsL = df.groupby(pd.cut(df[cols[i]], nt))['__label__'].agg(
                ', '.join).dropna()
            labelsR = df.groupby(pd.cut(df[cols[i + 1]], nt))['__label__'].agg(
                ', '.join).dropna()

            yPos_L = df.groupby(pd.cut(df[cols[i]],
                                       nt))[cols[i]].mean().dropna()
            yPos_R = df.groupby(pd.cut(df[cols[i + 1]],
                                       nt))[cols[i + 1]].mean().dropna()

            yMark_L = df.groupby(pd.cut(df[cols[i]],
                                        nt))[cols[i]].mean().dropna()
            yMark_R = df.groupby(pd.cut(df[cols[i + 1]],
                                        nt))[cols[i + 1]].mean().dropna()

            yPos_ = df[[cols[i], cols[i + 1]]]

        if kind == 'ordinal':

            yPos_L = df[[
                cols[i]
            ]].rank(ascending=False).applymap(lambda el: round(el + 0.1))
            yPos_R = df[[
                cols[i + 1]
            ]].rank(ascending=False).applymap(lambda el: round(el + 0.1))
            yMark_L = df.groupby(cols[i])[cols[i]].mean().dropna()
            yMark_R = df.groupby(cols[i + 1])[cols[i + 1]].mean().dropna()
            yMark_L.sort(ascending=False)
            yMark_R.sort(ascending=False)
            #print yMark_L

            labelsL = df.groupby(yPos_L[cols[i]].values)['__label__'].agg(
                ', '.join)
            labelsR = df.groupby(yPos_R[cols[i + 1]].values)['__label__'].agg(
                ', '.join)
            yPos_L.sort(cols[i], inplace=True)
            yPos_R.sort(cols[i + 1], inplace=True)

            yPos_ = yPos_L.join(yPos_R)  #.sort(cols[i],inplace=True)


#        if i == 1:
#            #print yPos_.T
#            print labelsL
#            #yPos_   =  df[[cols[i],cols[i+1]]]
#

#        if kind=='stack' :
#
#            yPos_L = df[cols[i]].rank()
#            yPos_R = df[cols[i+1]].rank()
#
#            labelsL = df.groupby(yPos_L)['__label__'].agg(', '.join)
#            labelsR = df.groupby(yPos_R)['__label__'].agg(', '.join)
#
#            yPos_ = yPos_L.join(yPos_R)
#
#            yPos_L  =  labelsL.index.values
#            yPos_R  =  labelsR.index.values

        if kind == "stack":
            ax.plot([0, 1], [0, 1], color='k', alpha=0.4)
        else:
            #print yPos_
            lines = ax.plot(yPos_.T, color='k', alpha=0.4)
            ax.spines['bottom'].set_visible(False)
            ax.xaxis.set_ticks_position('bottom')

            if kind == "ordinal":
                ax.set_ybound(lower=1, upper=len(yPos_))
            if kind == "interval":
                ax.set_ybound(lower=data.min().min(), upper=data.max().max())

                #ax.set_xbound(lower=0,upper=1)

            ax.set_xticklabels([])
            #print cols[i]
            axarr_X[i].set_yticks([1])
            axarr_X[i].set_xticklabels([])
            axarr_X[i].set_yticklabels([str(cols[i])], fontproperties=font)
            #ax.set_xticklabels([str(cols[i])],horizontalalignment='center',fontproperties=font)
            #            ax.spines['top'].set_visible(False)
            #            ax.spines['right'].set_visible(False)
            #            ax.spines['left'].set_visible(False)

            if marker:
                labelsL_str = [
                    item[1] + (marker % item[0]).rjust(6)
                    for item in zip(yMark_L.values, labelsL.values)
                ]
                labelsR_str = [(marker % item[0]).ljust(6) + item[1]
                               for item in zip(yMark_R.values, labelsR.values)]
                ylabelsL_str = map(lambda el: marker % el, yMark_L.values)
                ylabelsR_str = map(lambda el: marker % el, yMark_R.values)
            else:
                labelsL_str = labelsL.values
                labelsR_str = labelsR.values
                ylabelsL_str = map(lambda el: u'', yPos_L.values)
                ylabelsR_str = map(lambda el: u'', yPos_R.values)

            if i == 0:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels(labelsL_str, fontproperties=font)
            elif marker:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels(
                    ylabelsL_str, fontproperties=font,
                    ha='right')  #ha='center')#,backgroundcolor='w')
            else:
                plt.setp(ax.get_yticklabels(), visible=False)
                wspace = 0

            if i == len(cols) - 2:
                bx = ax.twinx()

                bx.set_ybound(ax.get_ybound())
                bx.set_yticks(yPos_R.values)
                bx.set_yticklabels(labelsR_str, fontproperties=font)
                bx.yaxis.set_tick_params(width=0)

                bx_X = axarr_X[i].twinx()
                bx_X.set_xticklabels([])
                bx_X.set_yticks([1])
                bx_X.yaxis.set_tick_params(width=0)
                bx_X.set_yticklabels([str(cols[i + 1])], fontproperties=font)

            if kind == 'ordinal':
                ax.invert_yaxis()
                if bx:
                    bx.invert_yaxis()

            if color:

                for tl in ax.yaxis.get_ticklabels():
                    try:
                        for kw, c in color.items():

                            if kw in tl.get_text():
                                tl.set_color(c)

                    except:
                        print('fail')
                        pass
                if bx:
                    for tl in bx.yaxis.get_ticklabels():
                        try:
                            for kw, c in color.items():

                                if kw in tl.get_text():
                                    tl.set_color(c)
                        except:
                            pass

            if color:
                for kw, c in color.items():
                    for j, lab__ in enumerate(yPos_.index):
                        if kw in lab__:
                            lines[j].set_color(c)
                            lines[j].set_linewidth(2)
                            lines[j].set_alpha(0.6)

                            for kk, tic_pos in enumerate(
                                    ax.yaxis.get_ticklocs()):

                                if yPos_.values[j][0] == tic_pos:

                                    ax.yaxis.get_ticklabels()[kk].set_color(c)

            ax.yaxis.set_tick_params(width=0)
            ax.xaxis.set_tick_params(width=0)

            ax.xaxis.grid(False)

    f.suptitle(title, x=0.5, y=0.02, fontproperties=font)
    plt.tight_layout()

    for ax in f.axes:
        ax.spines['top'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['left'].set_visible(False)

    tw = ax.yaxis.get_text_widths(renderer)[0]
    #dpi = f.properties()['dpi']
    if wspace == 0:
        pass
    else:
        #wspace = tw/dpi
        aw = ax.get_tightbbox(renderer).width
        wspace = tw / aw * 1.4

    #f.subplots_adjust(wspace=wspace)
    f.subplots_adjust(wspace=wspace)

    if kind == "stack":
        f.subplots_adjust(wspace=wspace, hspace=0)
    else:
        pass

    if savename:
        f.savefig(os.path.join('Output', savename), dpi=dpi)
        #os.system("start " + savename)

    return f
Beispiel #3
0
def slope(data,
          kind='interval',
          marker='%0.f',
          color=None,
          title='',
          font_family='GillSans',
          font_size=12,
          width=12,
          height=8,
          ax=None,
          savename=None,
          dpi=150,
          wspace=None, ):

    font = FontProperties(font_family)
    font.set_size(font_size)
    bx = None

    df = data.copy()

    cols = df.columns
    df['__label__'] = df.index
    df['__order__'] = range(len(df.index))

    if kind == 'stack':
        f, axarr = plt.subplots(len(df), len(cols) - 1,
                                facecolor="w",
                                squeeze=False,
                                sharex=True)  #,sharey=True)
    else:
        f = plt.figure(figsize=(width, height), dpi=30, facecolor="w")
        gs = gridspec.GridSpec(
            nrows=20,
            ncols=len(cols) - 1
        )  # the 20 rows are just there to provide enought space for the title
        axarr = []
        axarr_X = []

        for i in range(len(cols) - 1):
            axarr.append(plt.subplot(gs[:19, i]))
            axarr_X.append(plt.subplot(gs[19, i]))

    axarr = np.array(axarr)
    axarr_X = np.array(axarr_X)
    renderer = f.canvas.get_renderer()
    data_range = [data.min().min(), data.max().max()]
    fh = f.get_figheight()
    fw = f.get_figwidth()
    fdpi = f.get_dpi()

    nt = fh // (font.get_size() / 72) / 2
    res = np.diff(data_range)[0] / nt * 2

    if not hasattr(axarr, 'transpose'):
        axarr = [axarr]

    for i in range((len(cols) - 1)):
        ax = axarr[i]

        axarr_X[i].yaxis.set_tick_params(width=0)
        axarr_X[i].xaxis.set_tick_params(width=0)
        """
        from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker
        # orange label
        obox1 = TextArea("orange - ", textprops=dict(color="k", size=15))
        obox2 = TextArea("5 ", textprops=dict(color="b", size=15))
        obox3 = TextArea(": ", textprops=dict(color="k", size=15))
        obox4 = TextArea("10 ", textprops=dict(color="r", size=15))
        
        orangebox = HPacker(children=[obox1, obox2, obox3, obox4],
                            align="center", pad=0, sep=5)
                    """

        if kind == 'interval':
            labelsL = df.groupby(pd.cut(df[cols[i]], nt))['__label__'].agg(
                ', '.join).dropna()
            labelsR = df.groupby(pd.cut(df[cols[i + 1]], nt))['__label__'].agg(
                ', '.join).dropna()

            yPos_L = df.groupby(pd.cut(df[cols[i]],
                                       nt))[cols[i]].mean().dropna()
            yPos_R = df.groupby(pd.cut(df[cols[i + 1]],
                                       nt))[cols[i + 1]].mean().dropna()

            yMark_L = df.groupby(pd.cut(df[cols[i]],
                                        nt))[cols[i]].mean().dropna()
            yMark_R = df.groupby(pd.cut(df[cols[i + 1]],
                                        nt))[cols[i + 1]].mean().dropna()

            yPos_ = df[[cols[i], cols[i + 1]]]

        if kind == 'ordinal':

            yPos_L = df[[cols[i]]].rank(ascending=False).applymap(
                lambda el: round(el + 0.1))
            yPos_R = df[[cols[i + 1]]].rank(ascending=False).applymap(
                lambda el: round(el + 0.1))
            yMark_L = df.groupby(cols[i])[cols[i]].mean().dropna()
            yMark_R = df.groupby(cols[i + 1])[cols[i + 1]].mean().dropna()
            yMark_L.sort(ascending=False)
            yMark_R.sort(ascending=False)
            #print yMark_L

            labelsL = df.groupby(yPos_L[cols[i]].values)['__label__'].agg(
                ', '.join)
            labelsR = df.groupby(yPos_R[cols[i + 1]].values)['__label__'].agg(
                ', '.join)
            yPos_L.sort(cols[i], inplace=True)
            yPos_R.sort(cols[i + 1], inplace=True)

            yPos_ = yPos_L.join(yPos_R)  #.sort(cols[i],inplace=True)
#        if i == 1: 
#            #print yPos_.T
#            print labelsL
#            #yPos_   =  df[[cols[i],cols[i+1]]]
#

#        if kind=='stack' : 
#            
#            yPos_L = df[cols[i]].rank()
#            yPos_R = df[cols[i+1]].rank()
#            
#            labelsL = df.groupby(yPos_L)['__label__'].agg(', '.join) 
#            labelsR = df.groupby(yPos_R)['__label__'].agg(', '.join) 
#            
#            yPos_ = yPos_L.join(yPos_R)            
#            
#            yPos_L  =  labelsL.index.values
#            yPos_R  =  labelsR.index.values

        if kind == "stack":
            ax.plot([0, 1], [0, 1], color='k', alpha=0.4)
        else:
            #print yPos_
            lines = ax.plot(yPos_.T, color='k', alpha=0.4)
            ax.spines['bottom'].set_visible(False)
            ax.xaxis.set_ticks_position('bottom')

            if kind == "ordinal":
                ax.set_ybound(lower=1, upper=len(yPos_))
            if kind == "interval":
                ax.set_ybound(lower=data.min().min(), upper=data.max().max())

                #ax.set_xbound(lower=0,upper=1)

            ax.set_xticklabels([])
            #print cols[i]
            axarr_X[i].set_yticks([1])
            axarr_X[i].set_xticklabels([])
            axarr_X[i].set_yticklabels([str(cols[i])], fontproperties=font)


            if marker:
                labelsL_str = [item[1] + (marker % item[0]).rjust(6)
                               for item in zip(yMark_L.values, labelsL.values)]
                labelsR_str = [(marker % item[0]).ljust(6) + item[1]
                               for item in zip(yMark_R.values, labelsR.values)]
                ylabelsL_str = map(lambda el: marker % el, yMark_L.values)
                ylabelsR_str = map(lambda el: marker % el, yMark_R.values)
            else:
                labelsL_str = labelsL.values
                labelsR_str = labelsR.values
                ylabelsL_str = map(lambda el: u'', yPos_L.values)
                ylabelsR_str = map(lambda el: u'', yPos_R.values)

            if i == 0:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels(labelsL_str, fontproperties=font)
            elif marker:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels([el for el in  ylabelsL_str],
                                   fontproperties=font,
                                   ha='right'
                                   )  #ha='center')#,backgroundcolor='w')
            else:
                plt.setp(ax.get_yticklabels(), visible=False)
                wspace = 0

            if i == len(cols) - 2:
                bx = ax.twinx()

                bx.set_ybound(ax.get_ybound())
                bx.set_yticks(yPos_R.values)
                bx.set_yticklabels(labelsR_str, fontproperties=font)
                bx.yaxis.set_tick_params(width=0)

                bx_X = axarr_X[i].twinx()
                bx_X.set_xticklabels([])
                bx_X.set_yticks([1])
                bx_X.yaxis.set_tick_params(width=0)
                bx_X.set_yticklabels([str(cols[i + 1])], fontproperties=font)

            if kind == 'ordinal':
                ax.invert_yaxis()
                if bx:
                    bx.invert_yaxis()

            if color:

                for tl in ax.yaxis.get_ticklabels():
                    try:
                        for kw, c in color.items():

                            if kw in tl.get_text():
                                tl.set_color(c)

                    except:
                        print('fail')
                        pass
                if bx:
                    for tl in bx.yaxis.get_ticklabels():
                        try:
                            for kw, c in color.items():

                                if kw in tl.get_text():
                                    tl.set_color(c)
                        except:
                            pass

            if color:
                for kw, c in color.items():
                    for j, lab__ in enumerate(yPos_.index):
                        if kw in lab__:
                            lines[j].set_color(c)
                            lines[j].set_linewidth(2)
                            lines[j].set_alpha(0.6)

                            for kk, tic_pos in enumerate(
                                ax.yaxis.get_ticklocs()):

                                if yPos_.values[j][0] == tic_pos:

                                    ax.yaxis.get_ticklabels()[kk].set_color(c)

            ax.yaxis.set_tick_params(width=0)
            ax.xaxis.set_tick_params(width=0)

            ax.xaxis.grid(False)

    f.suptitle(title, x=0.5, y=0.02, fontproperties=font)
    plt.tight_layout()

    for ax in f.axes:
        ax.spines['top'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['left'].set_visible(False)

    tw = ax.yaxis.get_text_widths(renderer)[0]
    if wspace == 0:
        pass
    else:
        #wspace = tw/dpi
        aw = ax.get_tightbbox(renderer).width
        wspace = tw / aw * 1.4

    f.subplots_adjust(wspace=wspace)

    if kind == "stack":
        f.subplots_adjust(wspace=wspace, hspace=0)
    else:
        pass

    if savename:
        f.savefig( savename, dpi=dpi)

    return f
Beispiel #4
0
def slope(
    data,
    kind='interval',
    marker='%0.f',
    color=None,
    title='',
    font_family='GillSans',
    font_size=12,
    width=12,
    height=8,
    ax=None,
    savename=None,
    dpi=150,
    wspace=None,
):

    font = FontProperties(font_family)
    font.set_size(font_size)
    bx = None

    df = data.copy()

    cols = df.columns
    df['__label__'] = df.index
    df['__order__'] = range(len(df.index))

    if kind == 'stack':
        f, axarr = plt.subplots(len(df),
                                len(cols) - 1,
                                facecolor="w",
                                squeeze=False,
                                sharex=True)  #,sharey=True)
    else:
        f = plt.figure(figsize=(width, height), dpi=30, facecolor="w")
        gs = gridspec.GridSpec(
            nrows=20, ncols=len(cols) - 1
        )  # the 20 rows are just there to provide enought space for the title
        axarr = []
        axarr_X = []

        for i in range(len(cols) - 1):
            axarr.append(plt.subplot(gs[:19, i]))
            axarr_X.append(plt.subplot(gs[19, i]))

    axarr = np.array(axarr)
    axarr_X = np.array(axarr_X)
    renderer = f.canvas.get_renderer()
    data_range = [data.min().min(), data.max().max()]
    fh = f.get_figheight()
    fw = f.get_figwidth()
    fdpi = f.get_dpi()

    nt = fh // (font.get_size() / 72) / 2
    res = np.diff(data_range)[0] / nt * 2

    if not hasattr(axarr, 'transpose'):
        axarr = [axarr]

    for i in range((len(cols) - 1)):
        ax = axarr[i]

        axarr_X[i].yaxis.set_tick_params(width=0)
        axarr_X[i].xaxis.set_tick_params(width=0)
        """
        from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker
        # orange label
        obox1 = TextArea("orange - ", textprops=dict(color="k", size=15))
        obox2 = TextArea("5 ", textprops=dict(color="b", size=15))
        obox3 = TextArea(": ", textprops=dict(color="k", size=15))
        obox4 = TextArea("10 ", textprops=dict(color="r", size=15))
        
        orangebox = HPacker(children=[obox1, obox2, obox3, obox4],
                            align="center", pad=0, sep=5)
                    """

        if kind == 'interval':
            labelsL = df.groupby(pd.cut(df[cols[i]], nt))['__label__'].agg(
                ', '.join).dropna()
            labelsR = df.groupby(pd.cut(df[cols[i + 1]], nt))['__label__'].agg(
                ', '.join).dropna()

            yPos_L = df.groupby(pd.cut(df[cols[i]],
                                       nt))[cols[i]].mean().dropna()
            yPos_R = df.groupby(pd.cut(df[cols[i + 1]],
                                       nt))[cols[i + 1]].mean().dropna()

            yMark_L = df.groupby(pd.cut(df[cols[i]],
                                        nt))[cols[i]].mean().dropna()
            yMark_R = df.groupby(pd.cut(df[cols[i + 1]],
                                        nt))[cols[i + 1]].mean().dropna()

            yPos_ = df[[cols[i], cols[i + 1]]]

        if kind == 'ordinal':

            yPos_L = df[[
                cols[i]
            ]].rank(ascending=False).applymap(lambda el: round(el + 0.1))
            yPos_R = df[[
                cols[i + 1]
            ]].rank(ascending=False).applymap(lambda el: round(el + 0.1))
            yMark_L = df.groupby(cols[i])[cols[i]].mean().dropna()
            yMark_R = df.groupby(cols[i + 1])[cols[i + 1]].mean().dropna()
            yMark_L.sort(ascending=False)
            yMark_R.sort(ascending=False)
            #print yMark_L

            labelsL = df.groupby(yPos_L[cols[i]].values)['__label__'].agg(
                ', '.join)
            labelsR = df.groupby(yPos_R[cols[i + 1]].values)['__label__'].agg(
                ', '.join)
            yPos_L.sort(cols[i], inplace=True)
            yPos_R.sort(cols[i + 1], inplace=True)

            yPos_ = yPos_L.join(yPos_R)  #.sort(cols[i],inplace=True)


#        if i == 1:
#            #print yPos_.T
#            print labelsL
#            #yPos_   =  df[[cols[i],cols[i+1]]]
#

#        if kind=='stack' :
#
#            yPos_L = df[cols[i]].rank()
#            yPos_R = df[cols[i+1]].rank()
#
#            labelsL = df.groupby(yPos_L)['__label__'].agg(', '.join)
#            labelsR = df.groupby(yPos_R)['__label__'].agg(', '.join)
#
#            yPos_ = yPos_L.join(yPos_R)
#
#            yPos_L  =  labelsL.index.values
#            yPos_R  =  labelsR.index.values

        if kind == "stack":
            ax.plot([0, 1], [0, 1], color='k', alpha=0.4)
        else:
            #print yPos_
            lines = ax.plot(yPos_.T, color='k', alpha=0.4)
            ax.spines['bottom'].set_visible(False)
            ax.xaxis.set_ticks_position('bottom')

            if kind == "ordinal":
                ax.set_ybound(lower=1, upper=len(yPos_))
            if kind == "interval":
                ax.set_ybound(lower=data.min().min(), upper=data.max().max())

                #ax.set_xbound(lower=0,upper=1)

            ax.set_xticklabels([])
            #print cols[i]
            axarr_X[i].set_yticks([1])
            axarr_X[i].set_xticklabels([])
            axarr_X[i].set_yticklabels([str(cols[i])], fontproperties=font)

            if marker:
                labelsL_str = [
                    item[1] + (marker % item[0]).rjust(6)
                    for item in zip(yMark_L.values, labelsL.values)
                ]
                labelsR_str = [(marker % item[0]).ljust(6) + item[1]
                               for item in zip(yMark_R.values, labelsR.values)]
                ylabelsL_str = map(lambda el: marker % el, yMark_L.values)
                ylabelsR_str = map(lambda el: marker % el, yMark_R.values)
            else:
                labelsL_str = labelsL.values
                labelsR_str = labelsR.values
                ylabelsL_str = map(lambda el: u'', yPos_L.values)
                ylabelsR_str = map(lambda el: u'', yPos_R.values)

            if i == 0:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels(labelsL_str, fontproperties=font)
            elif marker:
                ax.set_yticks(yPos_L.values)
                ax.set_yticklabels(
                    [el for el in ylabelsL_str],
                    fontproperties=font,
                    ha='right')  #ha='center')#,backgroundcolor='w')
            else:
                plt.setp(ax.get_yticklabels(), visible=False)
                wspace = 0

            if i == len(cols) - 2:
                bx = ax.twinx()

                bx.set_ybound(ax.get_ybound())
                bx.set_yticks(yPos_R.values)
                bx.set_yticklabels(labelsR_str, fontproperties=font)
                bx.yaxis.set_tick_params(width=0)

                bx_X = axarr_X[i].twinx()
                bx_X.set_xticklabels([])
                bx_X.set_yticks([1])
                bx_X.yaxis.set_tick_params(width=0)
                bx_X.set_yticklabels([str(cols[i + 1])], fontproperties=font)

            if kind == 'ordinal':
                ax.invert_yaxis()
                if bx:
                    bx.invert_yaxis()

            if color:

                for tl in ax.yaxis.get_ticklabels():
                    try:
                        for kw, c in color.items():

                            if kw in tl.get_text():
                                tl.set_color(c)

                    except:
                        print('fail')
                        pass
                if bx:
                    for tl in bx.yaxis.get_ticklabels():
                        try:
                            for kw, c in color.items():

                                if kw in tl.get_text():
                                    tl.set_color(c)
                        except:
                            pass

            if color:
                for kw, c in color.items():
                    for j, lab__ in enumerate(yPos_.index):
                        if kw in lab__:
                            lines[j].set_color(c)
                            lines[j].set_linewidth(2)
                            lines[j].set_alpha(0.6)

                            for kk, tic_pos in enumerate(
                                    ax.yaxis.get_ticklocs()):

                                if yPos_.values[j][0] == tic_pos:

                                    ax.yaxis.get_ticklabels()[kk].set_color(c)

            ax.yaxis.set_tick_params(width=0)
            ax.xaxis.set_tick_params(width=0)

            ax.xaxis.grid(False)

    f.suptitle(title, x=0.5, y=0.02, fontproperties=font)
    plt.tight_layout()

    for ax in f.axes:
        ax.spines['top'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['left'].set_visible(False)

    tw = ax.yaxis.get_text_widths(renderer)[0]
    if wspace == 0:
        pass
    else:
        #wspace = tw/dpi
        aw = ax.get_tightbbox(renderer).width
        wspace = tw / aw * 1.4

    f.subplots_adjust(wspace=wspace)

    if kind == "stack":
        f.subplots_adjust(wspace=wspace, hspace=0)
    else:
        pass

    if savename:
        f.savefig(savename, dpi=dpi)

    return f
Beispiel #5
0
class Chart:
  def __init__(self, props, subdefaults):
    self.file = None
    self.filename = None
    self.props = {
      "imageType":	  "png",	# Output image type.
      "dpi":		  72,		# Image DPI resolution.
      "width":		  800,		# Output image width in pixels (vs. DPI).
      "height":		  600,		# Output image height in pixels (vs. DPI).
      "padding":	  50,		# Padding around the figure edge, in pixels.
      "textPadding":	  3,		# Padding around text, in pixels.
      "fontFamily":	  "sans-serif",	# Font family.
      "fontName":	  "Luxi Sans",	# Font name.
      "fontSize":	  12,		# Size of non-title text, in pixels.
      "titleFontName":	  "Bitstream Vera Sans",
      "titleFontSize":	  18,		# Size of title text, in pixels.
      "subtitleFontSize": 14,		# Size of subtitle text, in pixels.
      "axtitleFontSize":  16,		# Size of axis title text, in pixels.
      "xAxisScale":	  "lin",	# X axis scale, lin or log.
      "yAxisScale":	  "lin",	# Y axis scale, lin or log.
      "square":		  False,		# Force square layout.
      "integral":   False, #force integral display on legend
      "notitle": False, #suppress title
      "nolabels": False, #suppress axis labels
      "sort":False, #sort items and legend entries by value
      "max_legend":100 #maximum items in the legend
    }
    for (k, v) in subdefaults.iteritems():
      self.props[k] = v
    for (k, v) in props.iteritems():
      self.props[k] = v

    self.font = FontProperties()
    self.font.set_family(self.get('fontFamily'))
    self.font.set_name(self.get('fontName'))
    self.font.set_size(float(self.get('fontSize')))
    self.tfont = FontProperties()
    self.tfont.set_family(self.get('titleFontFamily', self.font.get_family()[-1]))
    self.tfont.set_name(self.get('titleFontName', self.font.get_name()))
    self.tfont.set_size(self.get('titleFontSize', self.font.get_size()))
    self.tfont.set_weight('bold')
    self.sfont = FontProperties()
    self.sfont.set_family(self.get('subtitleFontFamily', self.tfont.get_family()[-1]))
    self.sfont.set_name(self.get('subtitleFontName', self.tfont.get_name()))
    self.sfont.set_size(self.get('subtitleFontSize', self.tfont.get_size()))
    self.afont = FontProperties()
    self.afont.set_family(self.get('axtitleFontFamily', self.tfont.get_family()[-1]))
    self.afont.set_name(self.get('axtitleFontName', self.tfont.get_name()))
    self.afont.set_size(self.get('axtitleFontSize', self.tfont.get_size()))
    self.afont.set_weight('bold')

  def __del__(self):
    if self.file != None:
      os.close(self.file)

  def get(self, key, default=None):
    return getattr(self, key, self.props.get(key, default))

  def draw(self):
    (fig, canvas, w, h) = self.canvas()
    fig.text(.5, .5, "No data.", horizontalalignment='center', fontproperties=self.font)
    return self.save(fig, canvas)

  def legend(self):
    (fig, canvas, w, h) = self.canvas()
    fig.text(.5, .5, "No legend.", horizontalalignment='center', fontproperties=self.font)
    return self.save(fig, canvas)

  def details(self):
    return {}

  def canvas(self):
    type = self.get("imageType", "png")
    fig = Figure()
    if type == "png":
      canvas = FigureCanvasAgg(fig)
      (self.file, self.filename) = mkstemp(".%s" % type)
    elif type == "svg":
      canvas = FigureCanvasSVG(fig)
      (self.file, self.filename) = mkstemp(".%s" % type)
    elif type == "pdf":
      canvas = FigureCanvasPdf(fig)
      (self.file, self.filename) = mkstemp(".%s" % type)
    elif type == "ps" or type == "eps":
      canvas = FigureCanvasPS(fig)
      (self.file, self.filename) = mkstemp(".%s" % type)
    else:
      raise "Invalid render target requested"

    # Set basic figure parameters
    dpi = float(self.get('dpi'))
    (w, h) = (float(self.get('width')), float(self.get('height')))
    (win, hin) = (w/dpi, h/dpi)
    fig.set_size_inches(win, hin)
    fig.set_dpi(dpi)
    fig.set_facecolor('white')
    return (fig, canvas, w, h)

  def save(self, fig, canvas):
    canvas.draw()
    if not self.filename:
      canvas.print_figure(self.file, dpi=float(self.get('dpi')))
      return self.file
    else:
      canvas.print_figure(self.filename, dpi=float(self.get('dpi')))
      f = file(self.filename, "r") # PS backend writes over the file
      os.remove(self.filename)     #    return os.fdopen(self.file)
      os.close(self.file)
      self.file = None
      self.filename = None
      return f

  def prepare(self):
    # Create canvas and determine figure parameters
    (fig, canvas, w, h) = self.canvas()
    dpif = float(self.get('dpi')) / 72
    padding = float(self.get('padding')) * dpif / h
    textPadding = float(self.get('textPadding')) * dpif
    titleFontSize = float(self.get('titleFontSize'))
    axFontSize = float(self.get('axtitleFontSize'))
    subFontSize = float(self.get('subtitleFontSize'))
    title = self.get("title", "").split("\n")
    if not self.get("notitle",False):
      hsub = (len(title)-1) * (subFontSize * dpif + 4) + textPadding
      htitle = hsub + titleFontSize * dpif + textPadding * 2
    else:
      hsub = 0
      htitle = 0
    if self.get("nolabels",False):
      padding = 0

    # Configure axes
    if self.get('square'):
      minsize = 1 - 2*padding
      axrect = (.5 - minsize/2 * h/w, padding, h/w * minsize, minsize)
    else:
      axrect = (padding, padding, 1 - 1.25*padding, 1 - htitle/h - padding)
    ax = fig.add_axes(axrect)
    #frame = ax.get_frame()
    #frame.set_fill(False)

    xlog = (str(self.get('xAxisScale', "lin")) == 'log')
    ylog = (str(self.get('yAxisScale', "lin")) == 'log')
    if xlog:
      ax.semilogx()
    if ylog:
      ax.semilogy()

    setp(ax.get_xticklabels(), fontproperties=self.font)
    setp(ax.get_yticklabels(), fontproperties=self.font)
    setp(ax.get_xticklines(), markeredgewidth=2.0, zorder=4.0)
    setp(ax.get_yticklines(), markeredgewidth=2.0)
    ax.grid(True, alpha=0.25, color='#000000', linewidth=0.1)

    # Set titles
    if not self.get("notitle",False):
      ax.title = ax.text(.5, 1+(hsub+textPadding)/(axrect[-1]*h), title[0],
                      verticalalignment='bottom',
                      horizontalalignment='center',
                      transform=ax.transAxes,
                      clip_box=None,
                      fontproperties=self.tfont)
      ax._set_artist_props(ax.title)
      if len(title) > 1:
        ax.subtitle = ax.text(.5, 1+textPadding/(axrect[-1]*h), "\n".join(title[1:]),
                           verticalalignment='bottom',
                           horizontalalignment='center',
                           transform=ax.transAxes,
                           clip_box=None,
                           fontproperties=self.sfont)

    if not self.get("nolabels",False):
      ax.set_xlabel(self.get("xAxisTitle", ""), fontproperties=self.afont)
      ax.set_ylabel(self.get("yAxisTitle", ""), fontproperties=self.afont)
    return (fig, canvas, ax)

  def map(self):
    return ''

  def make(self):
    img = self.draw().read()
    legend = self.legend().read()
    map = self.map()
    return img,legend,map