How can I draw arrows around Matplotlib pie to point each label to their respective section in the circle?

Viewed 1668

I've been drawing some charts with Matplotlib, I have a pie chart and want to draw arrows around the chart that makes every label points to the chart, I've got an example:

enter image description here

This is my current code:

import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Arial'
labels = ['Section 1', 'Section 2', 'Section 3', 'Section 4', 'Section 5']
sizes = [20, 20, 20, 20, 20]

fig1, ax1 = plt.subplots()
fig1.set_size_inches(3,3)
ax1.pie(sizes, explode=None, labels=labels, autopct='',
        shadow=False, startangle=0)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.


plt.savefig('real.png', bbox_inches = 'tight',
    pad_inches = 0)
plt.show()

The current code produces this chart:

enter image description here

How can I achieve the above (first) image result?

1 Answers

You could use annotations based on the wedges' angles. See the tutorial for many examples with options for the arrows and a bounding box around the text.

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'Arial'
labels = ['Section 1', 'Section 2', 'Section 3', 'Section 4', 'Section 5']
sizes = [20, 20, 20, 20, 20]

fig, ax = plt.subplots(figsize=(3, 3), subplot_kw=dict(aspect="equal"))

wedges, texts = ax.pie(sizes, wedgeprops=dict(width=0.5), startangle=-40)

kw = dict(arrowprops=dict(arrowstyle="->"), va="center")
for p, label in zip(wedges, labels):
    ang = np.deg2rad((p.theta1 + p.theta2)/2)
    y = np.sin(ang)
    x = np.cos(ang)
    horizontalalignment = "center" if abs(x) < abs(y) else "right" if x < 0 else "left"
    ax.annotate(label, xy=(0.75*x, 0.75*y), xytext=(1.3*x, 1.3*y),
                horizontalalignment=horizontalalignment, **kw)
plt.tight_layout()
plt.show()

pie plot with arrows

Related