| name | matplotlib |
| description | Matplotlib API patterns for creating publication-quality visualizations. Use when /ds:eda needs distribution plots, correlation heatmaps, or relationship visualizations, or when /ds:experiment needs result plots (learning curves, confusion matrices, forecast visualizations). For standard ML diagnostic plots use scikit-learn display utilities; for statsmodels diagnostic plots use statsmodels built-in plotting; for quick statistical plots prefer seaborn. |
| license | https://github.com/matplotlib/matplotlib/tree/main/LICENSE |
| metadata | {"skill-author":"K-Dense Inc."} |
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.
Role in ds plugin
The matplotlib skill provides the foundational visualization API for the ds plugin. It is the reference for creating custom figures, multi-panel layouts, styling, and export.
Boundary with other skills:
- scikit-learn display utilities (
ConfusionMatrixDisplay, RocCurveDisplay, learning_curve) remain the primary reference for standard ML diagnostic plots. Use matplotlib when customizing these plots or composing multi-panel figures.
- statsmodels built-in plotting (
plot_diagnostics(), plot_acf/plot_pacf) remain the primary reference for time-series and regression diagnostic plots. Use matplotlib for custom forecast visualizations or publication-quality figure assembly.
- seaborn (built on matplotlib) is preferred for standard statistical plots (violin plots, pair plots, correlation heatmaps) due to its more concise API. Use matplotlib directly for plot types seaborn does not cover, for fine-grained control, or for multi-panel figure composition.
DS plugin conventions:
- Always use the OO interface (
fig, ax = plt.subplots()) in generated code
- Default to
plt.savefig() + plt.close(fig) -- never plt.show() (headless compatibility)
- Save plot files alongside the report in the same output directory (e.g.,
docs/ds/eda/)
- Use
constrained_layout=True for automatic spacing
- Use colorblind-friendly colormaps (viridis, cividis) by default
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:
- Figure - The top-level container for all plot elements
- Axes - The actual plotting area where data is displayed (one Figure can contain multiple Axes)
- Artist - Everything visible on the figure (lines, text, ticks, etc.)
- Axis - The number line objects (x-axis, y-axis) that handle ticks and labels
Two Interfaces
1. pyplot Interface (Implicit, MATLAB-style)
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.savefig('plot.png', dpi=300, bbox_inches='tight')
plt.close()
- Convenient for quick, simple plots
- Maintains state automatically
- Good for interactive work and simple scripts
2. Object-Oriented Interface (Explicit)
import matplotlib.pyplot as plt
fig, ax = plt.subplots(constrained_layout=True)
ax.plot([1, 2, 3, 4])
ax.set_ylabel('some numbers')
plt.savefig('plot.png', dpi=300, bbox_inches='tight')
plt.close(fig)
- 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:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(10, 6), constrained_layout=True)
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)')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Trigonometric Functions')
ax.legend()
ax.grid(True, alpha=0.3)
plt.savefig('plot.png', dpi=300, bbox_inches='tight')
plt.close(fig)
2. Multiple Subplots
Creating subplot layouts:
fig, axes = plt.subplots(2, 2, figsize=(12, 10), constrained_layout=True)
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)
plt.savefig('subplots.png', dpi=300, bbox_inches='tight')
plt.close(fig)
fig, axes = plt.subplot_mosaic([['left', 'right_top'],
['left', 'right_bottom']],
figsize=(10, 8), constrained_layout=True)
axes['left'].plot(x, y)
axes['right_top'].scatter(x, y)
axes['right_bottom'].hist(data)
plt.savefig('mosaic.png', dpi=300, bbox_inches='tight')
plt.close(fig)
from matplotlib.gridspec import GridSpec
fig = plt.figure(figsize=(12, 8), constrained_layout=True)
gs = GridSpec(3, 3, figure=fig)
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1:, 0])
ax3 = fig.add_subplot(gs[1:, 1:])
plt.savefig('gridspec.png', dpi=300, bbox_inches='tight')
plt.close(fig)
3. Plot Types and Use Cases
Line plots - Time series, continuous data, trends
ax.plot(x, y, linewidth=2, linestyle='--', marker='o', color='blue')
Scatter plots - Relationships between variables, correlations
ax.scatter(x, y, s=sizes, c=colors, alpha=0.6, cmap='viridis')
Bar charts - Categorical comparisons
ax.bar(categories, values, color='steelblue', edgecolor='black')
ax.barh(categories, values)
Histograms - Distributions
ax.hist(data, bins=30, edgecolor='black', alpha=0.7)
Heatmaps - Matrix data, correlations
im = ax.imshow(matrix, cmap='coolwarm', aspect='auto')
plt.colorbar(im, ax=ax)
Contour plots - 3D data on 2D plane
contour = ax.contour(X, Y, Z, levels=10)
ax.clabel(contour, inline=True, fontsize=8)
Box plots - Statistical distributions
ax.boxplot([data1, data2, data3], labels=['A', 'B', 'C'])
Violin plots - Distribution densities
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:
plt.style.use('seaborn-v0_8-darkgrid')
print(plt.style.available)
Customizing with rcParams:
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:
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:
plt.savefig('figure.png', dpi=300, bbox_inches='tight', facecolor='white')
plt.savefig('figure.pdf', bbox_inches='tight')
plt.savefig('figure.svg', bbox_inches='tight')
plt.savefig('figure.png', dpi=300, bbox_inches='tight', transparent=True)
plt.close(fig)
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
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.scatter(x, y, z, c=colors, marker='o')
ax.plot(x, y, z, linewidth=2)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.savefig('3d_plot.png', dpi=300, bbox_inches='tight')
plt.close(fig)
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
def create_analysis_plot(data, title, output_path):
"""Create standardized analysis plot."""
fig, ax = plt.subplots(figsize=(10, 6), constrained_layout=True)
ax.plot(data['x'], data['y'], linewidth=2)
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)
plt.savefig(output_path, dpi=300, bbox_inches='tight')
plt.close(fig)
create_analysis_plot(my_data, 'My Analysis', 'docs/ds/eda/analysis.png')
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:
python scripts/plot_template.py
style_configurator.py
Interactive utility to configure matplotlib style preferences and generate custom style sheets.
Usage:
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
- Overlapping elements: Use
constrained_layout=True or tight_layout()
- State confusion: Use OO interface to avoid pyplot state machine issues
- Memory issues with many figures: Close figures explicitly with
plt.close(fig)
- Font warnings: Install fonts or suppress warnings with
plt.rcParams['font.sans-serif']
- DPI confusion: Remember that figsize is in inches, not pixels:
pixels = dpi * inches
Getting Help