1
votes

I have generated a pandas dataframe and I want to use pd.DataFrame().style to highlight some cells.

    v1  v2  v3  v4  v5
v1  0   1   1   1   0
v2  0   0   1   1   1
v3  0   0   0   0   0
v4  0   0   0   0   0
v5  0   0   0   0   0

I want to color its upper and lower triangular, as well as its diagonal. To do so I'm doing the following:

  1. Compute lower and upper triangular, and diagonal.

    def triang(df):
        temp=df.copy()
        ut=np.triu(np.ones(df.shape),1).astype(np.bool)
        lt=np.tril(np.ones(df.shape),-1).astype(np.bool)
    
        temp=temp.where(ut==False, 'up')
        temp=temp.where(lt==False, 'lt')
        np.fill_diagonal(temp.values,'dg')
        return(temp)
    
    triang(mymat)
    

returns

    v1  v2  v3  v4  v5
v1  dg  up  up  up  up
v2  lt  dg  up  up  up
v3  lt  lt  dg  up  up
v4  lt  lt  lt  dg  up
v5  lt  lt  lt  lt  dg
  1. Define the color function

    def color_vals(value):
         if value == 'up':
             color='orange'
         elif value=='lt':
             color='blue'
         else:
             color='black'
         return(color)
    color_vals('up')
    #'orange'
    
  2. Style the dataframe

    triang(mymat).style.applymap(color_vals)
    #returns the same as triang(mymat)
    

I am stuck in the style part (step 3). I'd like to see the very first matrix (mymat, the one with 0 and 1) stylized according to the colors per section (upper, lower triangular and diagonal).

How can I do the last step?

Thanks a lot in advance.

2

2 Answers

3
votes

IIUC, try this:

where df_vals:

    v1  v2  v3  v4  v5
v1   0   1   1   1   0
v2   0   0   1   1   1
v3   0   0   0   0   0
v4   0   0   0   0   0
v5   0   0   0   0   0

def triang(df):
    temp=df.copy()
    ut=np.triu(np.ones(df.shape),1).astype(np.bool)
    lt=np.tril(np.ones(df.shape),-1).astype(np.bool)

    temp=temp.where(ut==False, 'up')
    temp=temp.where(lt==False, 'lt')
    np.fill_diagonal(temp.values,'dg')
    return(temp)

def color_vals(val):
    """
    Color dataframe using values
    """
    d = {'up' : 'orange',
         'dg' : 'black',
         'lt' : 'blue'}
    return [f'color : {i}' for i in triang(df_vals).loc[val.name, val.index].map(d).tolist()] 

df_vals.style.apply(color_vals)

Output:

enter image description here

2
votes

I'd like to see the very first matrix (mymat, the one with 0 and 1) stylized according to the colors per section (upper, lower triangular and diagonal)

Okay so you can modify the function like below:

def myfunc(x):
    c1=np.triu(np.ones(df.shape),1).astype(np.bool)
    c2=np.tril(np.ones(df.shape),-1).astype(np.bool)
    col1='color:orange'
    col2='color:blue'
    col3='color:black'
    df1 = pd.DataFrame(np.select([c1,c2],[col1,col2],col3),columns=x.columns,index=x.index)
    return df1

df.style.apply(myfunc,axis=None) # mymat.style.apply(myfunc,axis=None)

enter image description here