0

I want to build two pie charts out of two sets of data which share some overlap in the labels, e.g. the labels are like this:

labels_a = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "Other"]
labels_b = ["one", "two", "four", "three", "six", "eleven", "twelve", "five", "eight", "nine", "Other"]

So six appears in both of them, but at different positions, also some labels appear only in one set. Both contain Other (but in my real case they might not).

I would now like to draw two pie charts with these labels and corresponding data, in which the same labels in each chart have the same color, i.e. I want the wedge corresponding to six to appear in both pie charts with the same color. Also I would like to have one legend with all entries for both pie charts.

This is my code:

import pandas as pd
import os
import matplotlib.pyplot as plt

# define two color sets that differ
colors = plt.get_cmap("Set1").colors + plt.get_cmap("Dark2").colors

alt_colors = plt.get_cmap("Set3").colors + plt.get_cmap("Set2").colors

labels_a = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "Other"]
labels_b = ["one", "two", "four", "three", "six", "eleven", "twelve", "five", "eight", "nine", "Other"]
values_a = [500, 300, 250.0, 221.0, 164.0, 135.0, 111, 110, 100.0, 91.8, 2200]
values_b = [440, 320, 250.0, 220.0, 164.0, 135.0, 120, 100, 90.0, 70, 2200]

fig, axs = plt.subplots(2,1)

cols_a = list(colors[:len(labels_a)]) # choose the first 11 colors for the a-labels
if "Other" in labels_a: # make sure that Other gets the right color
    cols_a[labels_a.index("Other")] = colors[-1]

# set a color map for the b-labels:
cols_b = []
for i in labels_b:
    if i in labels_a:
        cols_b.append(cols_a[labels_a.index(i)])
    else:
        cols_b.append(alt_colors[labels_b.index(i)])

if "Other" in labels_b: # make sure that Other gets the same color
    cols_b[labels_b.index("Other")] = colors[-1]

wedges_a, text_a = axs[0].pie(values_a, labels=labels_a, colors=cols_a, startangle=-90)

wedges_b, text_b = axs[1].pie(values_b, colors=cols_b, labels= labels_b, startangle=-90)

plt.legend(wedges_a, labels_a, loc="lower right")

It works well in that it assigns the right colors to each label. How can I achieve a legend that has all entries? And how can I place it outside the pie charts, i.e. to avoid this sort of overlap:

enter image description here

Till B
  • 1,248
  • 2
  • 15
  • 19

1 Answers1

0

The short answer is using bbox_to_anchor like this (values are my estimates, you should play with them and see what suits you best):

plt.legend(wedges_a, labels_a, loc="lower right", bbox_to_anchor=(2,0.5))

There is lots more information about bbox_to_anchor in this great answer.

By the way, I'd also recommend expanding your figsize - like this:

fig, axs = plt.subplots(2,1, figsize=(10, 10))
Josh Friedlander
  • 10,870
  • 5
  • 35
  • 75