Perfume preferences as a bipartite graph

import matplotlib.pyplot as plt names = ['Sonya', 'Marie', 'Selena', 'Johanna', 'Nena', 'Sarah', 'Yvonne', 'Lora', 'Jeanette'] perfumes = [ '"No. 3 L\'Imperatrice" by Dolce & Gabbana', '"Daisy Sparkle Edition" by Marc Jacobs', '"Brit Rhytm" by Burberry', '"Cheap & chic stars" by Moschino', '"Rio Glow" by Jennifer Lopez', '"Princess" by Vera Wang', '"Miracle" by Lancome', '"Agent Provocateur" by Agent Provocateur', '"Bright crystal" by Versace', '"Lady Million" by Paco Rabanne' ] preferences = [ (0, [3, 5, 9]), (1, [1, 4, 7]), (2, [4, 8]), (3, [0, 5, 7]), (4, [2, 5, 8]), (5, [5, 6, 9]), (6, [1, 7, 8]), (7, [2, 5, 8]), (8, [7, 9]), ] names_len = len(names) perfumes_len = len(perfumes) height = 400 left_point_x, right_point_x = -15, 10 point_text_offset = 2 point_size = 10 point_color = 'black' line_color = 'purple' line_width = 1 line_alpha = 0.5 left_text_shift, right_text_shift = -4, -5 lefty_step, righty_step = height / names_len, height / perfumes_len text_align_left, text_align_right = 'left', 'right' # Plot the points on the two sides for i in range(names_len): plt.scatter(left_point_x, i * lefty_step, s = point_size, color=point_color) plt.annotate(names[i], xy=(left_point_x, i * lefty_step), xytext=(left_point_x-point_text_offset, i * lefty_step + left_text_shift), horizontalalignment=text_align_right) for i in range(perfumes_len): plt.scatter(right_point_x, i * righty_step, s = point_size, color=point_color) plt.annotate(perfumes[i], xy=(right_point_x, i * righty_step), xytext=(right_point_x+point_text_offset, i * righty_step + right_text_shift), horizontalalignment=text_align_left) # Draw connections for name_idx, preference in preferences: xcoords = [left_point_x, right_point_x] for pref_idx in preference: ycoords = [name_idx * lefty_step, pref_idx * righty_step] plt.plot(xcoords, ycoords, '-', color=line_color, lw=line_width, alpha=line_alpha) plt.title('Perfume preferences as a bipartite graph') plt.xlim(-30, 70) plt.tight_layout() plt.axis('off') plt.show() Perfume preferences of some women as a bipartite graph