0

I am trying to style a very large dataframe with many different color combinations for cell fill and font. I experimented using lambda functions, but seemed like a very inefficient way of doing the styling. I'm looking for a solution similar to the example shown at the bottom of the post, labeled "Desired Approach".

My specific case involves a dictionary of lists. Here is an example dataset...i'd like to color all the names of males blue/orange and all the names of females pink/red:

# raw data
df = pd.DataFrame({'Freshman':['Mike', 'Bill', 'Maria'],
                   'Junior':['Lauren','Tom','Jessica'],
                   'Senior':['Sandy','Michelle','Mike']
                   })

my_dict = {'Male':['Mike','Bill','Tom'],
          'Female':['Maria','Lauren','Jessica','Sandy','Michelle']} 

Desired Approach:

I tried tweaking this approach for my use-case, but cant get it to work.

# raw data
df = pd.DataFrame({'Name':['name1', 'name2', 'name3', 'name1', 'name2', 'name3', 'name1', 'name2', 'name3' ],  
                   'Rotation':['ER','PEDI','MAM','PEDI', 'ERJD','PEDI','JMAM','ERSN','ABD']})

def where(x):
  bg = ['blue', 'pink']
  fg = ['orange', 'red']
  ls = ['ER', 'MAM']
  for i, y in enumerate(ls):
    if y in x:
      return f"background-color: {bg[i]}; color: {fg[i]}"
  return ''

df.style.applymap(where)

this code returns the following:

enter image description here

Steve
  • 135
  • 1
  • 10

2 Answers2

0

I don't understand why you have that second dataframe with name and rotation columns.

Let me use your first dataframe and dictinary.

df = pd.DataFrame({'Freshman':['Mike', 'Bill', 'Maria'],
               'Junior':['Lauren','Tom','Jessica'],
               'Senior':['Sandy','Michelle','Mike']
               })

my_dict = {'Male':['Mike','Bill','Tom'],
      'Female':['Maria','Lauren','Jessica','Sandy','Michelle']} 

So you want males have blue background and the text is orange. And females have pink background and red-colored text.

def colorit(val):
    color = 'orange' if val in my_dict['Male'] else 'red'
    bgcolor = 'blue' if val in my_dict['Male'] else 'pink'
    return 'background-color: %s ; color: %s'% (bgcolor,color)

df.style.applymap(colorit)

The output will look like:

enter image description here

ipramusinto
  • 2,310
  • 2
  • 14
  • 24
  • To clarify, the second dataframe is from an example i was trying to replicate, showing all the color combinations in lists for cell fill and font. The actual dataframe i am trying to use will have atleast 10 different color combinations of cell fill and text, so using the list approach seemed like the best way to go. The actual dictionary i will use will have 10 separate keys with different lists values. Dont think your approach will be an efficient solution in my actual use case, but it does work for the example male/female dataset i used in the post.. – Steve Sep 20 '18 at 01:35
  • Then you might give sample of your data, and how your desired approach didn't work on your case. – ipramusinto Sep 20 '18 at 01:58
0

Was able to solve using the desired approach:

def where(val):
  bg = ['blue', 'pink']
  fg = ['orange', 'red']
  ls = ['Male', 'Female']
  for i, y in enumerate(ls):
    if val in my_dict[y]:
      return f"background-color: {bg[i]}; color: {fg[i]}"
  return ''

df = df.style.applymap(where)
Steve
  • 135
  • 1
  • 10