# Matplotlib Clean Plots

> Create clean, professional matplotlib visualizations for technical blog posts and learning documentation. Use when creating plots, charts, or data visualizations for blogs, notes, or papers that need clean styling with English labels. Triggers include "plot", "visualize", "draw chart", "create figure", or when writing technical documentation that needs illustrations.

- Skill: `reganzed/matplotlib-clean-plots` (Agent Skill, multi-file: 15 files)
- Install (CLI): `npx skillmds@latest add reganzed/matplotlib-clean-plots`
- Raw SKILL.md: https://api.skillmd.com/api/skills/reganzed/matplotlib-clean-plots/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: ReganZed (https://skillmd.com/u/reganzed)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/reganzed/matplotlib-clean-plots

---


# Matplotlib Clean Plots

Create publication-quality matplotlib visualizations with clean, minimal styling optimized for technical blogs and learning notes.

## Quick Start

### Using Templates (Recommended)

**Setup a new plot file:**

```bash
# 2D plot
./scripts/setup_template.sh my_plot.py

# 3D plot
./scripts/setup_template.sh my_3d_plot.py 3d

# Windows PowerShell
.\scripts\setup_template.ps1 my_plot.py
.\scripts\setup_template.ps1 my_3d_plot.py 3d
```

Then edit and run: `python3 my_plot.py`

**Template includes:**
- Clean style configuration
- Standard color palette (Elegant Teal)
- Proper export settings
- Example structure

### Manual Setup

```python
import matplotlib.pyplot as plt

# Apply clean style
plt.style.use('seaborn-v0_8-white')
plt.rcParams['axes.spines.top'] = False
plt.rcParams['axes.spines.right'] = False
plt.rcParams['figure.dpi'] = 150

# Standard colors
COLOR_TEAL = '#4A9BAA'  # Primary
COLOR_CORAL = '#FF7B7B'  # Emphasis
COLOR_GRAY = '#95A5A6'   # Auxiliary

# Your plot
plt.plot(x, y, color=COLOR_TEAL, linewidth=2.5)
plt.grid(True, alpha=0.3, color=COLOR_GRAY)
plt.savefig('output.png', dpi=150, bbox_inches='tight')
```

## Core Principles

1. **English Labels** - Use clear English for international audience
2. **Clean Styling** - Remove unnecessary elements (top/right spines, excessive decorations)
3. **Math Plots: Axes Through Origin** - For math/function plots, place spines at origin (see Common Patterns)
4. **Preventing Overlap** - Use semi-transparent bounding boxes (`bbox`) for annotations and legends to ensure legibility when crossing lines.
5. **Standard Colors** - Use Elegant Teal Palette for consistency
6. **Proper Export** - Always use `dpi=150, bbox_inches='tight'`
7. **Verify Output** - Check generated images before claiming success

## Standard Colors

**Elegant Teal Palette** (copy from `templates/colors.py` or template files):

```python
COLOR_TEAL = '#4A9BAA'      # Primary - main data, key elements
COLOR_AQUA = '#7ECFC0'      # Secondary - supporting data
COLOR_CREAM = '#FFD9A0'     # Tertiary - annotations, highlights
COLOR_CORAL = '#FF7B7B'     # Emphasis - important markers
COLOR_GRAY = '#95A5A6'      # Auxiliary - grids, reference lines
```

**Usage:** Import from template or copy color definitions. See [Color Palettes Guide](references/color_palettes.md) for detailed usage examples and alternatives.

## Common Patterns

**Use templates for full examples.** Quick patterns:

```python
# Main curve with emphasis points
ax.plot(x, y, color=COLOR_TEAL, linewidth=2.5)
ax.scatter(x_peaks, y_peaks, color=COLOR_CORAL, s=80, zorder=5)

# Filled confidence band
ax.fill_between(x, y_lower, y_upper, color=COLOR_AQUA, alpha=0.3)

# Reference line
ax.axhline(y=0, color=COLOR_GRAY, linestyle='--', alpha=0.5)

# Grid
ax.grid(True, alpha=0.3, color=COLOR_GRAY, linestyle=':')
```

### Mathematical Function Plots (Axes Through Origin)

For math/function plots, use **spines through the origin** to match textbook conventions.

```python
AXIS_COLOR = '#444444'

def setup_math_axes(ax, xticks, yticks):
    """Spines through origin — use for all math/function plots."""
    for spine in ['top', 'right']:
        ax.spines[spine].set_visible(False)
    ax.spines['left'].set_position('zero')
    ax.spines['bottom'].set_position('zero')
    for spine in ['left', 'bottom']:
        ax.spines[spine].set_color(AXIS_COLOR)
        ax.spines[spine].set_linewidth(1.0)
    ax.set_xticks(xticks)
    ax.set_yticks(yticks)
    ax.tick_params(axis='both', colors=AXIS_COLOR, labelsize=9,
                   direction='inout', length=5)

# Usage
setup_math_axes(ax, xticks=[-3, -2, -1, 1, 2, 3],
                yticks=[1, 2, 3])
ax.set_xlim(-3.2, 3.2)
ax.set_ylim(-0.5, 3.6)
ax.grid(True, alpha=0.15, color=COLOR_GRAY, linestyle=':')
ax.text(3.25, -0.15, '$x$', fontsize=11, ha='left', va='top', color=AXIS_COLOR)
ax.text(0.1, 3.55, '$y$', fontsize=11, ha='left', va='bottom', color=AXIS_COLOR)
```

### Preventing Text & Line Overlap

When labels or legends cross plot lines, use bounding boxes to maintain legibility:

```python
# For Annotations
ax.annotate('Important Point', 
            xy=(x_val, y_val), xytext=(20, 20),
            textcoords='offset points',
            arrowprops=dict(arrowstyle='->', color=COLOR_TEAL),
            # semi-transparent white box hides underlying lines
            bbox=dict(facecolor='white', edgecolor='none', alpha=0.8, pad=2))

# For Legends
ax.legend(frameon=True, framealpha=0.8, edgecolor='none')
```

**Key rules:**
- **Skip 0 in tick lists** to avoid clutter at the origin
- **Use `ax.text()` for axis labels** at tips, not `set_xlabel`/`set_ylabel` (those align to edges, not centered spines)
- Grid: dotted (`':'`), alpha `0.15`, with `AXIS_COLOR = '#444444'` for spines (darker than `COLOR_GRAY`)

See [Plot Templates Guide](references/plot_templates_guide.md) for complete examples.

## Special Plot Types

- **3D Plots**: See [3D Plotting Guide](references/3d_plotting_guide.md)
- **Polar Plots**: See [Polar Plots Guide](references/polar_plots_guide.md) for best practices and common pitfalls

## Key Settings

```python
# Base style
plt.style.use('seaborn-v0_8-white')
plt.rcParams['axes.spines.top'] = False
plt.rcParams['axes.spines.right'] = False
plt.rcParams['figure.dpi'] = 150

# Font sizes
plt.rcParams['font.size'] = 10
plt.rcParams['axes.labelsize'] = 11
plt.rcParams['axes.titlesize'] = 12
```

See [Style Options Reference](references/style_options.md) for complete configuration.

## Files Structure

```
matplotlib-clean-plots/
├── templates/          # Copy these to start
│   ├── plot_template.py       - Basic 2D plot
│   ├── plot_3d_template.py    - 3D visualization
│   └── colors.py              - Color definitions
├── scripts/            # Setup utilities
│   ├── setup_template.sh      - Create from template (bash)
│   └── setup_template.ps1     - Create from template (PowerShell)
├── references/         # Detailed documentation
│   ├── color_palettes.md      - Color usage guide
│   ├── 3d_plotting_guide.md   - 3D visualization guide
│   ├── polar_plots_guide.md   - Polar coordinate plots guide
│   ├── plot_templates_guide.md - Complete examples
│   ├── style_options.md       - Style customization
│   └── export_guide.md        - Export best practices
└── examples/           # Demonstrations
    └── teal_palette_demo.py   - Color palette demo
```

## Workflow

1. **Create** from template: `./scripts/setup_template.sh my_plot.py`
2. **Edit** the file with your data and labels
3. **Run**: `python3 my_plot.py`
4. **Verify** the output image

---

**Remember**: Always verify output before claiming success!

