# go over every cell in dataframe to get all guesses data = collections . defaultdict ( list ) movies_scores = [] # to sort movies by score so colors won't overlap for movie in movies_with_rt : movie_name = ' ' . join ( movie . split ( '_' )[: - 1 ]) rt_score = int ( movie . split ( '_' )[ - 1 ]) movies_scores . append (( movie_name , rt_score )) for index , row in df . iterrows (): user = row . user guess = row [ movie ] # access in dict-like way since movie is variable if not math . isnan ( guess ): data [ 'user' ] . append ( user ) data [ 'guess' ] . append ( guess ) data [ 'movie' ] . append ( movie_name ) data [ 'rt_score' ] . append ( rt_score ) points = pd . DataFrame . from_dict ( data ) # get list of movies sorted by rt_value so can color them differently sorted_movies = [ i [ 0 ] for i in sorted ( movies_scores , key = operator . itemgetter ( 1 ))] # get a color for each movie, cycling through a list of colors colors = list ( itertools . islice ( itertools . cycle ( bp . d3 [ 'Category10' ][ 10 ]), 0 , len ( movies_scores ))) movie_to_color = { movie : color for movie , color in zip ( sorted_movies , colors )} # apply movie_to_color dict to get new column in dataframe points [ 'color' ] = points [ 'movie' ] . map ( movie_to_color ) points [ 'line_width' ] = 1 # later on user can change line_width by selection