Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Low-level plotting library for full customization. Use when you need fine-grained control over every plot element, creating novel plot types, or integrating with specific scientific workflows. Export to PNG/PDF/SVG for publication. For quick statistical plots use seaborn; for interactive plots use plotly; for publication-ready multi-panel figures with journal styling, use scientific-visualization.
.claude/skills/matplotlib/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | — | — |
| case-02 | ✓→✓ | = Same ✓ | — | — |
| case-05 | ✗→✗ | = Same ✗ | — | — |
| case-08 | ✗→✗ | = Same ✗ | — | — |
| case-12 | ✗→✗ | = Same ✗ | — | — |
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.
This skill should be used when:
Matplotlib uses a hierarchical structure of objects:
1. pyplot Interface (Implicit, MATLAB-style)
pythonimport matplotlib.pyplot as plt plt.plot([1, 2, 3, 4]) plt.ylabel('some numbers') plt.show()
2. Object-Oriented Interface (Explicit)
pythonimport matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3, 4]) ax.set_ylabel('some numbers') plt.show()
Single plot workflow:
pythonimport 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()
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
Line plots - Time series, continuous data, trends
pythonax.plot(x, y, linewidth=2, linestyle='--', marker='o', color='blue')
Scatter plots - Relationships between variables, correlations
pythonax.scatter(x, y, s=sizes, c=colors, alpha=0.6, cmap='viridis')
Bar charts - Categorical comparisons
pythonax.bar(categories, values, color='steelblue', edgecolor='black') # For horizontal bars: ax.barh(categories, values)
Histograms - Distributions
pythonax.hist(data, bins=30, edgecolor='black', alpha=0.7)
Heatmaps - Matrix data, correlations
pythonim = ax.imshow(matrix, cmap='coolwarm', aspect='auto') plt.colorbar(im, ax=ax)
Contour plots - 3D data on 2D plane
pythoncontour = ax.contour(X, Y, Z, levels=10) ax.clabel(contour, inline=True, fontsize=8)
Box plots - Statistical distributions
pythonax.boxplot([data1, data2, data3], labels=['A', 'B', 'C'])
Violin plots - Distribution densities
pythonax.violinplot([data1, data2, data3], positions=[1, 2, 3])
For comprehensive plot type examples and variations, refer to references/plot_types.md.
Color specification methods:
'red', 'blue', 'steelblue''#FF5733'(0.1, 0.2, 0.3)cmap='viridis', cmap='plasma', cmap='coolwarm'Using style sheets:
pythonplt.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:
pythonplt.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:
pythonax.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.
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 whitespacefacecolor='white': Ensures white background (useful for transparent themes)transparent=True: Transparent backgroundpythonfrom 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')
fig, ax = plt.subplots(figsize=(10, 6))constrained_layout=True or tight_layout() to prevent overlapping elementsfig, ax = plt.subplots(constrained_layout=True) is recommended for automatic spacingrasterized=True in plot calls to reduce file sizepython# 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')
This skill includes helper scripts in the scripts/ directory:
plot_template.pyTemplate script demonstrating various plot types with best practices. Use this as a starting point for creating new visualizations.
Usage:
bashpython scripts/plot_template.py
style_configurator.pyInteractive utility to configure matplotlib style preferences and generate custom style sheets.
Usage:
bashpython scripts/style_configurator.py
For comprehensive information, consult the reference documents:
references/plot_types.md - Complete catalog of plot types with code examples and use casesreferences/styling_guide.md - Detailed styling options, colormaps, and customizationreferences/api_reference.md - Core classes and methods referencereferences/common_issues.md - Troubleshooting guide for common problemsMatplotlib integrates well with:
%matplotlib inline or %matplotlib widgetconstrained_layout=True or tight_layout()plt.close(fig)plt.rcParams['font.sans-serif']pixels = dpi * inches| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 23 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.