Matplotlib Pie Charts
Build clear pie, donut, and nested donut charts with Matplotlib — labels, percentages, explode, rotation, legends, and best practices.
Quiz progress
0 / 10 answered
Contents
Basics #
Minimal pie:
import matplotlib.pyplot as plt
sizes = [30, 45, 25]
labels = ["A", "B", "C"]
fig, ax = plt.subplots()
ax.pie(sizes, labels=labels) # values need not sum to 100
ax.axis("equal") # circle instead of ellipse
plt.show()
- Values are normalized internally:
[30,45,25]→ 30%, 45%, 25%. - Use
ax.axis("equal")to keep the pie circular.
“Pies are for parts of a whole. If you have many slices or the ranking matters, consider a bar chart.”
Quiz: Basics
1. In
ax.pie([30,70]), the wedges represent:2. To start the first wedge at the top (12 o’clock), use:
Labels & Percentages #
Show percentages with
autopct
fig, ax = plt.subplots()
sizes = [40, 35, 25]
labels = ["North", "East", "West"]
wedges, texts, autotexts = ax.pie(
sizes, labels=labels,
autopct="%1.1f%%", # format string
pctdistance=0.8, # position of % labels
textprops={"fontsize":10}
)
ax.axis("equal")
plt.show()
Custom percentage formatting
def fmt_pct(pct, allvals):
absolute = pct/100 * sum(allvals)
return f"{pct:.1f}%\n({absolute:.0f})"
fig, ax = plt.subplots()
sizes = [5, 15, 30, 50]
wedges, *_ = ax.pie(
sizes,
autopct=lambda pct: fmt_pct(pct, sizes), # pct is 0..100
startangle=90
)
ax.axis("equal"); plt.show()
Quiz: Labels & Percentages
3. Which
autopct string shows percentages with one decimal?4. In an
autopct callable, the argument pct is:Explode & Rotation #
Explode a slice; rotate and direction
fig, ax = plt.subplots()
sizes = [50, 25, 25]
labels = ["Core", "A", "B"]
explode = [0.05, 0.15, 0.0] # highlight the 2nd slice
ax.pie(
sizes, labels=labels, explode=explode,
startangle=90, # start at 12 o'clock
counterclock=False, # clockwise
autopct="%1.0f%%", shadow=True
)
ax.axis("equal"); plt.show()
Quiz: Explode & Rotation
5. To draw the wedges clockwise, use:
6. Explode only the second slice by 0.1:
Donut & Nested Donut #
Donut chart (ring) via
wedgeprops
fig, ax = plt.subplots()
sizes = [40, 35, 25]
wedges, _ = ax.pie(
sizes, startangle=90,
wedgeprops={"width":0.4, "edgecolor":"white"} # width < 1 → hole
)
ax.axis("equal")
plt.show()
Nested donut (two rings)
fig, ax = plt.subplots()
outer = [50, 30, 20]
inner = [30, 20, 10, 25, 10, 5] # e.g., sub-categories
ax.pie(outer, radius=1.0, wedgeprops={"width":0.3, "edgecolor":"white"}, labels=["A","B","C"])
ax.pie(inner, radius=0.7, wedgeprops={"width":0.3, "edgecolor":"white"})
ax.axis("equal"); plt.show()
Quiz: Donut & Nested
7. Easiest way to create a donut hole is to:
8. To make a nested donut, you typically… (choose all that apply)
Styling & Legends #
Colors, edges, legends
fig, ax = plt.subplots()
sizes = [25, 35, 40]
labels = ["Red", "Green", "Blue"]
colors = ["#ef476f", "#06d6a0", "#118ab2"]
wedges, texts, autotexts = ax.pie(
sizes, labels=labels, colors=colors,
autopct="%1.0f%%",
wedgeprops={"linewidth":1, "edgecolor":"#fff"},
textprops={"color":"#222"}
)
ax.axis("equal")
ax.legend(wedges, labels, title="Segments", loc="center left", bbox_to_anchor=(1,0.5))
plt.show()
Quiz: Styling & Legends
9. To ensure your pie is a circle (not an ellipse), use:
Pitfalls & Best Practices #
- Too many slices: group small categories into “Other”.
- Invalid data: negative values are not allowed; all zeros yields nothing to plot.
- Legibility: prefer few slices; use labels, legend, and contrasting edges.
- Accessibility: avoid using color alone; add labels/legend and consider patterns/annotations.
Quiz: Pitfalls
10. Which inputs are invalid or will fail for
ax.pie? (choose all that apply)Final Quiz & Summary #
Review your performance and revisit questions you missed.
Category: viz · Lesson: matplotlib-pie-charts
Learning by Examples
Runs three demos: basic pie, donut, and nested donut. If Matplotlib is available, images render below the console; otherwise, you’ll see a text fallback.
# Pie Charts Playground
# If Matplotlib is available, this script will print lines like
# "IMG64:<base64_png>" that the page will render as images.
def basic_pie():
import matplotlib
matplotlib.use("AGG")
import matplotlib.pyplot as plt
from io import BytesIO
import base64
sizes = [30, 45, 25]
labels = ["A", "B", "C"]
fig, ax = plt.subplots(figsize=(4,4), dpi=144)
ax.pie(sizes, labels=labels, autopct="%1.1f%%", startangle=90)
ax.axis("equal")
buf = BytesIO()
fig.savefig(buf, format="png", bbox_inches="tight")
plt.close(fig)
data = base64.b64encode(buf.getvalue()).decode("ascii")
print("Basic pie (A,B,C):")
print("IMG64:" + data)
def donut_pie():
import matplotlib
matplotlib.use("AGG")
import matplotlib.pyplot as plt
from io import BytesIO
import base64
sizes = [40, 35, 25]
fig, ax = plt.subplots(figsize=(4,4), dpi=144)
ax.pie(sizes, startangle=90, wedgeprops={"width":0.4, "edgecolor":"white"}, autopct="%1.0f%%")
ax.axis("equal")
buf = BytesIO()
fig.savefig(buf, format="png", bbox_inches="tight")
plt.close(fig)
data = base64.b64encode(buf.getvalue()).decode("ascii")
print("Donut chart:")
print("IMG64:" + data)
def nested_donut():
import matplotlib
matplotlib.use("AGG")
import matplotlib.pyplot as plt
from io import BytesIO
import base64
outer = [50, 30, 20]
inner = [30, 20, 10, 25, 10, 5]
fig, ax = plt.subplots(figsize=(4.8,4.8), dpi=144)
ax.pie(outer, radius=1.0, wedgeprops={"width":0.3, "edgecolor":"white"}, labels=["A","B","C"], startangle=90)
ax.pie(inner, radius=0.7, wedgeprops={"width":0.3, "edgecolor":"white"}, startangle=90)
ax.axis("equal")
buf = BytesIO()
fig.savefig(buf, format="png", bbox_inches="tight")
plt.close(fig)
data = base64.b64encode(buf.getvalue()).decode("ascii")
print("Nested donut:")
print("IMG64:" + data)
def text_fallback():
print("Matplotlib not available. Showing a small text demo:")
sizes = [12, 18, 30, 40]
total = sum(sizes)
pct = [round(s/total*100, 1) for s in sizes]
print("Sizes:", sizes)
print("Percentages:", pct)
try:
import matplotlib # noqa
basic_pie()
donut_pie()
nested_donut()
except Exception as e:
text_fallback()
print("(Install matplotlib locally or run in an environment with plotting support.)")