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.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-13 | ✗→✓ | ▲ Improved | 225% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 132% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 94% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 275% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 166% | 0% |
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:
For project work, install Matplotlib with uv:
bashuv add matplotlib
For notebook interactivity:
bashuv add matplotlib ipympl
Then enable the widget backend in Jupyter with %matplotlib widget or %matplotlib ipympl.
Matplotlib 3.10 requires Python 3.10+ and NumPy 1.23+. Non-interactive file output works through backends such as Agg, PDF, and SVG. For GUI windows, Matplotlib auto-selects an available backend; if TkAgg fails in a uv-managed Python, update uv and Python builds with uv self update and uv python upgrade --reinstall, or install a Qt backend with uv add pyside6.
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 fig.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], tick_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 fig.savefig('figure.png', dpi=300, bbox_inches='tight', facecolor='white') # Vector format for publications (scalable) fig.savefig('figure.pdf', bbox_inches='tight') fig.savefig('figure.svg', bbox_inches='tight') # Transparent background fig.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 backgroundpythonfig = 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') fig.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:
bashuv run python scripts/plot_template.py
style_configurator.pyInteractive utility to configure matplotlib style preferences and generate custom style sheets.
Usage:
bashuv run python 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 * inchesOther measured skills in the registry, with their headline benchmark lift.