Conditional Deletion of Tags in Matplotlib Pie Chart

I have the following code:

import matplotlib.pyplot as plt import numpy as np np.random.seed(123456) import pandas as pd df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] fig, axes = plt.subplots(nrows=2, ncols=3) for ax in axes.flat: ax.axis('off') for ax, col in zip(axes.flat, df.columns): ax.pie(df[col], labels=df.index, autopct='%.2f', colors=colors) ax.set(ylabel='', title=col, aspect='equal') axes[0, 0].legend(bbox_to_anchor=(0, 0.5)) fig.savefig('your_file.png') # Or whichever format you'd like plt.show() 

Which produce the following:

enter image description here

My question is how can I remove a label based on a condition. For example, I would like to display tags with only percentages> 20%. So that labels and values a,c,d not displayed in X, etc.

+6
source share
3 answers

The autopct argument of pie may be callable, which will receive the current percentage. Thus, you will need to provide a function that returns an empty string for the values ​​you want to omit the percentage.

 def my_autopct(pct): return ('%.2f' % pct) if pct > 20 else '' ax.pie(df[col], labels=df.index, autopct=my_autopct, colors=colors) 

If you need to parameterize the value in the autopct argument, you will need a function that returns a function, for example:

 def autopct_generator(limit): def inner_autopct(pct): return ('%.2f' % pct) if pct > limit else '' return inner_autopct ax.pie(df[col], labels=df.index, autopct=autopct_generator(20), colors=colors) 

For shortcuts, the best I can come up with is using a list:

 for ax, col in zip(axes.flat, df.columns): data = df[col] labels = [n if v > data.sum() * 0.2 else '' for n, v in zip(df.index, data)] ax.pie(data, autopct=my_autopct, colors=colors, labels=labels) 

Note, however, that the default legend is generated from the first labels passed, so you will need to pass all the values ​​explicitly in order to keep it intact.

 axes[0, 0].legend(df.index, bbox_to_anchor=(0, 0.5)) 
+13
source

For shortcuts, I used:

 def my_level_list(data): list = [] for i in range(len(data)): if (data[i]*100/np.sum(data)) > 2 : #2% list.append('Label '+str(i+1)) else: list.append('') return list patches, texts, autotexts = plt.pie(data, radius = 1, labels=my_level_list(data), autopct=my_autopct, shadow=True) 
0
source

You can make labels shorter using list comprehension:

 def my_autopct(pct): return ('%1.1f' % pct) if pct > 1 else '' def get_new_labels(sizes, labels): new_labels = [label if size > 1 else '' for size, label in zip(sizes, labels)] return new_labels fig, ax = plt.subplots() _,_,_ = ax.pie(sizes, labels=get_new_labels(sizes, labels), colors=colors, autopct=my_autopct, startangle=90, rotatelabels=False) 
0
source

All Articles