How to Create a Pie Chart in Matplotlib
Matplotlib's `pyplot.pie()` function provides a straightforward API for creating pie charts, but knowing when *not* to use them is equally important. Pie charts excel at showing proportions when you...
Key Insights
- Pie charts work best for displaying proportions of 3-7 categories that sum to a meaningful whole—avoid them for time series or data that doesn’t represent parts of a total
- The
autopctparameter automatically formats percentage labels, whileexplodedraws attention to specific slices by separating them from the chart - Use
wedgeprops={'width': 0.5}to convert any pie chart into a donut chart, which reduces visual distortion and improves readability
Introduction and Setup
Matplotlib’s pyplot.pie() function provides a straightforward API for creating pie charts, but knowing when not to use them is equally important. Pie charts excel at showing proportions when you have a small number of categories (ideally 3-7) that represent parts of a meaningful whole. They fail spectacularly when comparing values across multiple datasets, showing trends over time, or displaying more than 7-8 categories where the human eye struggles to distinguish slice sizes.
Before diving in, install Matplotlib if you haven’t already:
pip install matplotlib numpy
Here are the essential imports you’ll need:
import matplotlib.pyplot as plt
import numpy as np
That’s it. Unlike some visualization libraries, Matplotlib doesn’t require extensive setup for basic pie charts.
Creating a Basic Pie Chart
The plt.pie() function requires at minimum a list or array of values. Labels are optional but recommended unless you’re creating an abstract visualization. The function automatically calculates percentages based on the sum of all values.
import matplotlib.pyplot as plt
# Market share data for cloud providers
values = [32, 24, 11, 6, 27]
labels = ['AWS', 'Azure', 'Google Cloud', 'Alibaba Cloud', 'Others']
# Create the pie chart
plt.figure(figsize=(8, 8))
plt.pie(values, labels=labels)
plt.title('Cloud Infrastructure Market Share 2024')
plt.show()
This produces a functional pie chart, but it’s visually basic. The slices are colored with Matplotlib’s default color cycle, and there’s no indication of actual percentages. Notice we don’t need to normalize values to 100—Matplotlib handles that calculation internally.
The figsize parameter creates a square canvas, which prevents the pie from appearing elliptical. Always use equal width and height for pie charts unless you have a specific design reason not to.
Customizing Appearance
Real-world pie charts need visual polish. Let’s add colors, percentage labels, explode a slice for emphasis, and include shadows for depth.
import matplotlib.pyplot as plt
values = [32, 24, 11, 6, 27]
labels = ['AWS', 'Azure', 'Google Cloud', 'Alibaba Cloud', 'Others']
# Custom colors using hex codes
colors = ['#FF9900', '#0078D4', '#4285F4', '#FF6A00', '#95A5A6']
# Explode the first slice (AWS) by 0.1 units
explode = (0.1, 0, 0, 0, 0)
plt.figure(figsize=(10, 8))
plt.pie(values,
labels=labels,
colors=colors,
explode=explode,
autopct='%1.1f%%', # Format percentages to 1 decimal place
shadow=True,
startangle=90) # Start from top instead of right
plt.title('Cloud Infrastructure Market Share 2024', fontsize=16, fontweight='bold')
plt.axis('equal') # Ensure circular shape
plt.show()
Key parameters explained:
autopct='%1.1f%%': Formats percentages with one decimal place. The format string follows Python’s string formatting conventions.explode: A tuple matching the length of your data. Non-zero values separate slices from the center.startangle: Rotates the entire chart. 90 degrees starts the first slice at 12 o’clock.shadow=True: Adds a subtle drop shadow. Use sparingly—it can look dated.
The autopct parameter accepts either a format string or a callable function, giving you complete control over label formatting. For example, autopct=lambda pct: f'{pct:.1f}%\n({pct*sum(values)/100:.0f})' would show both percentage and absolute values.
Advanced Formatting
For professional visualizations, you’ll often need legends, custom fonts, and specialized chart types like donuts. The wedgeprops parameter controls the appearance of individual slices.
import matplotlib.pyplot as plt
values = [35, 25, 20, 15, 5]
labels = ['Product A', 'Product B', 'Product C', 'Product D', 'Product E']
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8']
fig, ax = plt.subplots(figsize=(10, 8))
# Create a donut chart by setting wedge width
wedges, texts, autotexts = ax.pie(values,
labels=labels,
colors=colors,
autopct='%1.1f%%',
startangle=45,
wedgeprops={'width': 0.5, 'edgecolor': 'white', 'linewidth': 2},
textprops={'fontsize': 11})
# Customize percentage text
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
# Add a legend positioned outside the plot
ax.legend(wedges, labels,
title="Products",
loc="center left",
bbox_to_anchor=(1, 0, 0.5, 1))
plt.title('Q4 Revenue Distribution', fontsize=16, fontweight='bold', pad=20)
plt.tight_layout()
plt.show()
The wedgeprops={'width': 0.5} parameter creates a donut chart by leaving the center hollow. A width of 0.5 means each wedge spans from 50% to 100% of the radius. This design reduces the visual distortion inherent in pie charts since our eyes judge arc length more accurately than area.
The pie() function returns three lists: wedge objects, label text objects, and percentage text objects. This allows post-creation customization, which is cleaner than cramming everything into the initial function call.
Practical Example: Multi-Chart Comparison
Comparing multiple pie charts side-by-side helps visualize changes over time or differences between categories. Subplots keep related charts organized.
import matplotlib.pyplot as plt
import numpy as np
# Quarterly sales data for four regions
regions = ['North America', 'Europe', 'Asia Pacific', 'Latin America']
q1_sales = [45, 25, 20, 10]
q2_sales = [42, 27, 22, 9]
q3_sales = [40, 28, 24, 8]
q4_sales = [38, 30, 25, 7]
quarters_data = [q1_sales, q2_sales, q3_sales, q4_sales]
quarters_labels = ['Q1 2024', 'Q2 2024', 'Q3 2024', 'Q4 2024']
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A']
fig, axes = plt.subplots(2, 2, figsize=(14, 12))
fig.suptitle('Regional Sales Distribution by Quarter', fontsize=18, fontweight='bold')
for idx, (ax, data, label) in enumerate(zip(axes.flat, quarters_data, quarters_labels)):
ax.pie(data,
labels=regions,
colors=colors,
autopct='%1.1f%%',
startangle=90,
wedgeprops={'edgecolor': 'white', 'linewidth': 1.5})
ax.set_title(label, fontsize=14, fontweight='bold', pad=10)
plt.tight_layout()
plt.show()
This 2x2 grid reveals trends that single charts miss. You can immediately see Europe’s growing share and Latin America’s decline across quarters. When creating subplot grids, maintain consistent colors across charts—each region should always have the same color.
The axes.flat iterator simplifies looping through subplot axes regardless of grid shape. This pattern works for any m×n subplot configuration.
Best Practices and Common Pitfalls
When to use pie charts: Use them exclusively for showing parts of a whole with 3-7 categories. The classic example is budget allocation or market share. If your data doesn’t sum to something meaningful (like “100% of market” or “total budget”), use a bar chart instead.
When to avoid pie charts: Never use pie charts for time series data, comparing values that don’t form a whole, or displaying more than 7 categories. Human perception struggles with comparing angles and areas, making bar charts objectively better for most comparisons.
Here’s a before/after showing poor versus good design:
import matplotlib.pyplot as plt
# Poor example: Too many categories with similar values
poor_values = [12, 11, 10, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 2]
poor_labels = [f'Cat {i+1}' for i in range(len(poor_values))]
# Good example: Consolidated into meaningful groups
good_values = [44, 30, 16, 10]
good_labels = ['Top Tier (12-11)', 'Mid Tier (10-8)', 'Lower Tier (7-5)', 'Others']
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))
# Poor design
ax1.pie(poor_values, labels=poor_labels, autopct='%1.0f%%', textprops={'fontsize': 7})
ax1.set_title('❌ Poor: Too Many Categories', fontsize=14, fontweight='bold', color='red')
# Good design
colors = ['#2ECC71', '#3498DB', '#F39C12', '#95A5A6']
ax2.pie(good_values, labels=good_labels, colors=colors, autopct='%1.1f%%',
startangle=90, wedgeprops={'edgecolor': 'white', 'linewidth': 2})
ax2.set_title('✓ Good: Consolidated Groups', fontsize=14, fontweight='bold', color='green')
plt.tight_layout()
plt.show()
Accessibility considerations: Choose colors with sufficient contrast and avoid relying solely on color to distinguish categories. Add patterns or textures for colorblind users, or use labels and legends. Test your colors using a colorblind simulator.
Color selection: Use a consistent color palette. Tools like ColorBrewer or Matplotlib’s built-in colormaps (plt.cm.Set3, plt.cm.Pastel1) provide perceptually distinct colors. Avoid rainbow gradients—they imply ordering that doesn’t exist in categorical data.
Performance: Pie charts render quickly even with complex styling. If you’re generating hundreds of charts programmatically, consider using plt.savefig() with dpi=100 instead of displaying them interactively. Close figures with plt.close() to free memory.
The bottom line: Pie charts are the most misused visualization in data science. Master the technical implementation, but more importantly, master knowing when to use something else. When used appropriately with clean design, they communicate proportions instantly and effectively.