356 lines
11 KiB
Markdown
356 lines
11 KiB
Markdown
---
|
|
name: matplotlib
|
|
description: "Foundational plotting library. Create line plots, scatter, bar, histograms, heatmaps, 3D, subplots, export PNG/PDF/SVG, for scientific visualization and publication figures."
|
|
---
|
|
|
|
# Matplotlib
|
|
|
|
## Overview
|
|
|
|
Matplotlib is Python's foundational visualization library for creating static, animated, and interactive plots. This skill provides guidance on using matplotlib effectively, covering both the pyplot interface (MATLAB-style) and the object-oriented API (Figure/Axes), along with best practices for creating publication-quality visualizations.
|
|
|
|
## When to Use This Skill
|
|
|
|
This skill should be used when:
|
|
- Creating any type of plot or chart (line, scatter, bar, histogram, heatmap, contour, etc.)
|
|
- Generating scientific or statistical visualizations
|
|
- Customizing plot appearance (colors, styles, labels, legends)
|
|
- Creating multi-panel figures with subplots
|
|
- Exporting visualizations to various formats (PNG, PDF, SVG, etc.)
|
|
- Building interactive plots or animations
|
|
- Working with 3D visualizations
|
|
- Integrating plots into Jupyter notebooks or GUI applications
|
|
|
|
## Core Concepts
|
|
|
|
### The Matplotlib Hierarchy
|
|
|
|
Matplotlib uses a hierarchical structure of objects:
|
|
|
|
1. **Figure** - The top-level container for all plot elements
|
|
2. **Axes** - The actual plotting area where data is displayed (one Figure can contain multiple Axes)
|
|
3. **Artist** - Everything visible on the figure (lines, text, ticks, etc.)
|
|
4. **Axis** - The number line objects (x-axis, y-axis) that handle ticks and labels
|
|
|
|
### Two Interfaces
|
|
|
|
**1. pyplot Interface (Implicit, MATLAB-style)**
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
|
|
plt.plot([1, 2, 3, 4])
|
|
plt.ylabel('some numbers')
|
|
plt.show()
|
|
```
|
|
- Convenient for quick, simple plots
|
|
- Maintains state automatically
|
|
- Good for interactive work and simple scripts
|
|
|
|
**2. Object-Oriented Interface (Explicit)**
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.plot([1, 2, 3, 4])
|
|
ax.set_ylabel('some numbers')
|
|
plt.show()
|
|
```
|
|
- **Recommended for most use cases**
|
|
- More explicit control over figure and axes
|
|
- Better for complex figures with multiple subplots
|
|
- Easier to maintain and debug
|
|
|
|
## Common Workflows
|
|
|
|
### 1. Basic Plot Creation
|
|
|
|
**Single plot workflow:**
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
# Create figure and axes (OO interface - RECOMMENDED)
|
|
fig, ax = plt.subplots(figsize=(10, 6))
|
|
|
|
# Generate and plot data
|
|
x = np.linspace(0, 2*np.pi, 100)
|
|
ax.plot(x, np.sin(x), label='sin(x)')
|
|
ax.plot(x, np.cos(x), label='cos(x)')
|
|
|
|
# Customize
|
|
ax.set_xlabel('x')
|
|
ax.set_ylabel('y')
|
|
ax.set_title('Trigonometric Functions')
|
|
ax.legend()
|
|
ax.grid(True, alpha=0.3)
|
|
|
|
# Save and/or display
|
|
plt.savefig('plot.png', dpi=300, bbox_inches='tight')
|
|
plt.show()
|
|
```
|
|
|
|
### 2. Multiple Subplots
|
|
|
|
**Creating subplot layouts:**
|
|
```python
|
|
# Method 1: Regular grid
|
|
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
|
|
axes[0, 0].plot(x, y1)
|
|
axes[0, 1].scatter(x, y2)
|
|
axes[1, 0].bar(categories, values)
|
|
axes[1, 1].hist(data, bins=30)
|
|
|
|
# Method 2: Mosaic layout (more flexible)
|
|
fig, axes = plt.subplot_mosaic([['left', 'right_top'],
|
|
['left', 'right_bottom']],
|
|
figsize=(10, 8))
|
|
axes['left'].plot(x, y)
|
|
axes['right_top'].scatter(x, y)
|
|
axes['right_bottom'].hist(data)
|
|
|
|
# Method 3: GridSpec (maximum control)
|
|
from matplotlib.gridspec import GridSpec
|
|
fig = plt.figure(figsize=(12, 8))
|
|
gs = GridSpec(3, 3, figure=fig)
|
|
ax1 = fig.add_subplot(gs[0, :]) # Top row, all columns
|
|
ax2 = fig.add_subplot(gs[1:, 0]) # Bottom two rows, first column
|
|
ax3 = fig.add_subplot(gs[1:, 1:]) # Bottom two rows, last two columns
|
|
```
|
|
|
|
### 3. Plot Types and Use Cases
|
|
|
|
**Line plots** - Time series, continuous data, trends
|
|
```python
|
|
ax.plot(x, y, linewidth=2, linestyle='--', marker='o', color='blue')
|
|
```
|
|
|
|
**Scatter plots** - Relationships between variables, correlations
|
|
```python
|
|
ax.scatter(x, y, s=sizes, c=colors, alpha=0.6, cmap='viridis')
|
|
```
|
|
|
|
**Bar charts** - Categorical comparisons
|
|
```python
|
|
ax.bar(categories, values, color='steelblue', edgecolor='black')
|
|
# For horizontal bars:
|
|
ax.barh(categories, values)
|
|
```
|
|
|
|
**Histograms** - Distributions
|
|
```python
|
|
ax.hist(data, bins=30, edgecolor='black', alpha=0.7)
|
|
```
|
|
|
|
**Heatmaps** - Matrix data, correlations
|
|
```python
|
|
im = ax.imshow(matrix, cmap='coolwarm', aspect='auto')
|
|
plt.colorbar(im, ax=ax)
|
|
```
|
|
|
|
**Contour plots** - 3D data on 2D plane
|
|
```python
|
|
contour = ax.contour(X, Y, Z, levels=10)
|
|
ax.clabel(contour, inline=True, fontsize=8)
|
|
```
|
|
|
|
**Box plots** - Statistical distributions
|
|
```python
|
|
ax.boxplot([data1, data2, data3], labels=['A', 'B', 'C'])
|
|
```
|
|
|
|
**Violin plots** - Distribution densities
|
|
```python
|
|
ax.violinplot([data1, data2, data3], positions=[1, 2, 3])
|
|
```
|
|
|
|
For comprehensive plot type examples and variations, refer to `references/plot_types.md`.
|
|
|
|
### 4. Styling and Customization
|
|
|
|
**Color specification methods:**
|
|
- Named colors: `'red'`, `'blue'`, `'steelblue'`
|
|
- Hex codes: `'#FF5733'`
|
|
- RGB tuples: `(0.1, 0.2, 0.3)`
|
|
- Colormaps: `cmap='viridis'`, `cmap='plasma'`, `cmap='coolwarm'`
|
|
|
|
**Using style sheets:**
|
|
```python
|
|
plt.style.use('seaborn-v0_8-darkgrid') # Apply predefined style
|
|
# Available styles: 'ggplot', 'bmh', 'fivethirtyeight', etc.
|
|
print(plt.style.available) # List all available styles
|
|
```
|
|
|
|
**Customizing with rcParams:**
|
|
```python
|
|
plt.rcParams['font.size'] = 12
|
|
plt.rcParams['axes.labelsize'] = 14
|
|
plt.rcParams['axes.titlesize'] = 16
|
|
plt.rcParams['xtick.labelsize'] = 10
|
|
plt.rcParams['ytick.labelsize'] = 10
|
|
plt.rcParams['legend.fontsize'] = 12
|
|
plt.rcParams['figure.titlesize'] = 18
|
|
```
|
|
|
|
**Text and annotations:**
|
|
```python
|
|
ax.text(x, y, 'annotation', fontsize=12, ha='center')
|
|
ax.annotate('important point', xy=(x, y), xytext=(x+1, y+1),
|
|
arrowprops=dict(arrowstyle='->', color='red'))
|
|
```
|
|
|
|
For detailed styling options and colormap guidelines, see `references/styling_guide.md`.
|
|
|
|
### 5. Saving Figures
|
|
|
|
**Export to various formats:**
|
|
```python
|
|
# High-resolution PNG for presentations/papers
|
|
plt.savefig('figure.png', dpi=300, bbox_inches='tight', facecolor='white')
|
|
|
|
# Vector format for publications (scalable)
|
|
plt.savefig('figure.pdf', bbox_inches='tight')
|
|
plt.savefig('figure.svg', bbox_inches='tight')
|
|
|
|
# Transparent background
|
|
plt.savefig('figure.png', dpi=300, bbox_inches='tight', transparent=True)
|
|
```
|
|
|
|
**Important parameters:**
|
|
- `dpi`: Resolution (300 for publications, 150 for web, 72 for screen)
|
|
- `bbox_inches='tight'`: Removes excess whitespace
|
|
- `facecolor='white'`: Ensures white background (useful for transparent themes)
|
|
- `transparent=True`: Transparent background
|
|
|
|
### 6. Working with 3D Plots
|
|
|
|
```python
|
|
from mpl_toolkits.mplot3d import Axes3D
|
|
|
|
fig = plt.figure(figsize=(10, 8))
|
|
ax = fig.add_subplot(111, projection='3d')
|
|
|
|
# Surface plot
|
|
ax.plot_surface(X, Y, Z, cmap='viridis')
|
|
|
|
# 3D scatter
|
|
ax.scatter(x, y, z, c=colors, marker='o')
|
|
|
|
# 3D line plot
|
|
ax.plot(x, y, z, linewidth=2)
|
|
|
|
# Labels
|
|
ax.set_xlabel('X Label')
|
|
ax.set_ylabel('Y Label')
|
|
ax.set_zlabel('Z Label')
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Interface Selection
|
|
- **Use the object-oriented interface** (fig, ax = plt.subplots()) for production code
|
|
- Reserve pyplot interface for quick interactive exploration only
|
|
- Always create figures explicitly rather than relying on implicit state
|
|
|
|
### 2. Figure Size and DPI
|
|
- Set figsize at creation: `fig, ax = plt.subplots(figsize=(10, 6))`
|
|
- Use appropriate DPI for output medium:
|
|
- Screen/notebook: 72-100 dpi
|
|
- Web: 150 dpi
|
|
- Print/publications: 300 dpi
|
|
|
|
### 3. Layout Management
|
|
- Use `constrained_layout=True` or `tight_layout()` to prevent overlapping elements
|
|
- `fig, ax = plt.subplots(constrained_layout=True)` is recommended for automatic spacing
|
|
|
|
### 4. Colormap Selection
|
|
- **Sequential** (viridis, plasma, inferno): Ordered data with consistent progression
|
|
- **Diverging** (coolwarm, RdBu): Data with meaningful center point (e.g., zero)
|
|
- **Qualitative** (tab10, Set3): Categorical/nominal data
|
|
- Avoid rainbow colormaps (jet) - they are not perceptually uniform
|
|
|
|
### 5. Accessibility
|
|
- Use colorblind-friendly colormaps (viridis, cividis)
|
|
- Add patterns/hatching for bar charts in addition to colors
|
|
- Ensure sufficient contrast between elements
|
|
- Include descriptive labels and legends
|
|
|
|
### 6. Performance
|
|
- For large datasets, use `rasterized=True` in plot calls to reduce file size
|
|
- Use appropriate data reduction before plotting (e.g., downsample dense time series)
|
|
- For animations, use blitting for better performance
|
|
|
|
### 7. Code Organization
|
|
```python
|
|
# Good practice: Clear structure
|
|
def create_analysis_plot(data, title):
|
|
"""Create standardized analysis plot."""
|
|
fig, ax = plt.subplots(figsize=(10, 6), constrained_layout=True)
|
|
|
|
# Plot data
|
|
ax.plot(data['x'], data['y'], linewidth=2)
|
|
|
|
# Customize
|
|
ax.set_xlabel('X Axis Label', fontsize=12)
|
|
ax.set_ylabel('Y Axis Label', fontsize=12)
|
|
ax.set_title(title, fontsize=14, fontweight='bold')
|
|
ax.grid(True, alpha=0.3)
|
|
|
|
return fig, ax
|
|
|
|
# Use the function
|
|
fig, ax = create_analysis_plot(my_data, 'My Analysis')
|
|
plt.savefig('analysis.png', dpi=300, bbox_inches='tight')
|
|
```
|
|
|
|
## Quick Reference Scripts
|
|
|
|
This skill includes helper scripts in the `scripts/` directory:
|
|
|
|
### `plot_template.py`
|
|
Template script demonstrating various plot types with best practices. Use this as a starting point for creating new visualizations.
|
|
|
|
**Usage:**
|
|
```bash
|
|
python scripts/plot_template.py
|
|
```
|
|
|
|
### `style_configurator.py`
|
|
Interactive utility to configure matplotlib style preferences and generate custom style sheets.
|
|
|
|
**Usage:**
|
|
```bash
|
|
python scripts/style_configurator.py
|
|
```
|
|
|
|
## Detailed References
|
|
|
|
For comprehensive information, consult the reference documents:
|
|
|
|
- **`references/plot_types.md`** - Complete catalog of plot types with code examples and use cases
|
|
- **`references/styling_guide.md`** - Detailed styling options, colormaps, and customization
|
|
- **`references/api_reference.md`** - Core classes and methods reference
|
|
- **`references/common_issues.md`** - Troubleshooting guide for common problems
|
|
|
|
## Integration with Other Tools
|
|
|
|
Matplotlib integrates well with:
|
|
- **NumPy/Pandas** - Direct plotting from arrays and DataFrames
|
|
- **Seaborn** - High-level statistical visualizations built on matplotlib
|
|
- **Jupyter** - Interactive plotting with `%matplotlib inline` or `%matplotlib widget`
|
|
- **GUI frameworks** - Embedding in Tkinter, Qt, wxPython applications
|
|
|
|
## Common Gotchas
|
|
|
|
1. **Overlapping elements**: Use `constrained_layout=True` or `tight_layout()`
|
|
2. **State confusion**: Use OO interface to avoid pyplot state machine issues
|
|
3. **Memory issues with many figures**: Close figures explicitly with `plt.close(fig)`
|
|
4. **Font warnings**: Install fonts or suppress warnings with `plt.rcParams['font.sans-serif']`
|
|
5. **DPI confusion**: Remember that figsize is in inches, not pixels: `pixels = dpi * inches`
|
|
|
|
## Additional Resources
|
|
|
|
- Official documentation: https://matplotlib.org/
|
|
- Gallery: https://matplotlib.org/stable/gallery/index.html
|
|
- Cheatsheets: https://matplotlib.org/cheatsheets/
|
|
- Tutorials: https://matplotlib.org/stable/tutorials/index.html
|