Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib - Move labels into middle of pie chart

I've got my pie chart working but I noticed that the text boxes for the actual chart doesn't seem to be working correctly. They are just clustered so I was wondering is there any way for me to move the labels into the middle where the white circle is and have the matching colour beside it or not?

crimeTypes = dict(crimeData["Crime type"].value_counts())

crimeType = []
totalAmount = []
numberOfCrimes = 14

for key in sorted(crimeTypes, key=crimeTypes.get, reverse=True):
    crimeType.append(key)
    totalAmount.append(crimeTypes.get(key))

crimeType_sample = crimeType[0:numberOfCrimes]
totalAmount_sample = totalAmount[0:numberOfCrimes]

fig1, ax1 = plt.subplots()
ax1.pie(totalAmount_sample, labels=crimeType_sample, autopct='%1.1f%%', shadow=False, startangle=90)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
fig1 = plt.gcf()
fig1.set_size_inches(10,10)
circle = plt.Circle(xy=(0,0), radius=0.75, facecolor='white')
plt.gca().add_artist(circle)
plt.show();

enter image description here

like image 767
ComSci Student Avatar asked Nov 10 '18 14:11

ComSci Student


People also ask

How do you avoid overlapping of labels and Autopct in a MatPlotLib pie chart?

Use legend() method to avoid overlapping of labels and autopct. To display the figure, use show() method.

How do you rotate labels in a pie chart in Python?

rotate labels matplotlibxticks(rotation=45) # rotate x-axis labels by 45 degrees. yticks(rotation=90) # rotate y-axis labels by 90 degrees.


1 Answers

Here's some sample data to reproduce your problem:

Sample Data:

import pandas as pd

data = (['Burglary']*50 + ['Arson', 'Theft', 'Violence'] + ['Drugs']*10 + ['Other'] + 
        ['Shoplifting']*4 + ['Harassment']*17 + ['Murder', 'Vehicle Crime']*3 + 
        ['Some other Crimes']*12 + ['Even More Crime', 'And Crime', 'And More Crime']*10)
crimeData = pd.DataFrame(data, columns=['Crime type'])

Which will result in this plot:

enter image description here


Use a legend

Do not plot the percentages or labels when you plot, and then create a legend which is placed off to the side:

fig1, ax1 = plt.subplots()

ax1.pie(totalAmount_sample, shadow=False, startangle=90)  # No labels or %s
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
fig1 = plt.gcf()
fig1.set_size_inches(5,5)
circle = plt.Circle(xy=(0,0), radius=0.75, facecolor='white')
plt.gca().add_artist(circle)

plt.legend(labels=[f'{x} {np.round(y/sum(totalAmount_sample)*100,1)}%' for x,y in crimeTypes.items()], 
           bbox_to_anchor=(1,1))

plt.show();

enter image description here

Rotate the labels:

Create your labels and use rotatelabels=True. Though this may still appear cramped in many cases.

fig1, ax1 = plt.subplots()

labels=[f'{x} {np.round(y/sum(totalAmount_sample)*100,1)}%' for x,y in crimeTypes.items()]
ax1.pie(totalAmount_sample, labels=labels, shadow=False, startangle=90,
        rotatelabels=True)  # No %

ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
fig1 = plt.gcf()
fig1.set_size_inches(7,7)
circle = plt.Circle(xy=(0,0), radius=0.75, facecolor='white')
plt.gca().add_artist(circle)

plt.show();

enter image description here

like image 57
ALollz Avatar answered Oct 13 '22 01:10

ALollz