Metadata-Version: 2.4
Name: oxford_matplotlib_theme
Version: 1.0.0
Summary: Matplotlib visualization theme following Official Oxford University colors and styling.
Author-email: Sami Adnan <sami.adnan@phc.ox.ac.uk>
License-Expression: MIT
Project-URL: Homepage, https://github.com/sami5001/oxford-matplotlib-theme
Project-URL: Documentation, https://github.com/sami5001/oxford-matplotlib-theme#readme
Project-URL: Repository, https://github.com/sami5001/oxford-matplotlib-theme
Project-URL: Issues, https://github.com/sami5001/oxford-matplotlib-theme/issues
Keywords: oxford,matplotlib,theme,visualization,plotting,academic,publication
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib>=3.5.0
Requires-Dist: numpy>=1.21.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=3.0.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: flake8>=4.0.0; extra == "dev"
Requires-Dist: mypy>=0.950; extra == "dev"
Provides-Extra: examples
Requires-Dist: pandas>=1.3.0; extra == "examples"
Requires-Dist: scikit-learn>=1.0.0; extra == "examples"
Requires-Dist: scipy>=1.7.0; extra == "examples"
Provides-Extra: all
Requires-Dist: oxford_matplotlib_theme[dev,examples]; extra == "all"
Dynamic: license-file

# Oxford Matplotlib Theme

Official Oxford University colors and styling for Matplotlib visualizations.

[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Create publication-quality figures with official Oxford University branding for academic papers, presentations, and reports.

> Author: Sami Adnan
> Nuffield Department of Primary Care Health Sciences 
> University of Oxford

---

## Features

**Official Oxford Branding**
- 56 official Oxford University brand colors (35 brand + 21 thesis colors)
- Compliant with [Oxford Brand Guidelines](https://communications.admin.ox.ac.uk/communications-resources/visual-identity/identity-guidelines/colours)
- Oxford Blue (#002147) throughout axes, labels, and text

**13 Curated Color Palettes**
- General purpose: PRIMARY, PROFESSIONAL, VIBRANT, PASTEL
- Data-specific: DIVERGING, SEQUENTIAL_BLUE
- Themed: HEALTH, TRADITIONAL, CONTEMPORARY, CELEBRATORY, CORPORATE, INNOVATIVE
- Academic: PHC_THESIS (27 colors for thesis work)

**7 Pre-configured Presets**
- `default` - Standard for academic papers
- `presentation` - Larger fonts for slides (1.4x)
- `poster` - Extra large fonts for posters (1.8x)
- `colorblind` - Accessible color palette
- `minimal` - Clean with grid background
- `notebook` - Optimized for Jupyter
- `print` - High contrast for printing

**Journal-Ready Export**
- Direct SVG/PNG/PDF export (no browser required!)
- Pre-configured settings for Nature, PLOS, BMJ, Lancet
- 300 DPI publication quality

**Zero Browser Dependencies**
- Unlike Plotly themes, no kaleido or Chrome required
- Faster rendering and export
- Smaller file sizes for vector formats

---

## Installation

```bash
# Clone the repository
git clone https://github.com/sami5001/oxford-matplotlib-theme.git
cd oxford-matplotlib-theme

# Install in editable mode
pip install -e .

# Or install with all dependencies
pip install -e ".[all]"
```

### Dependencies

**Core** (required):
- matplotlib >= 3.5.0
- numpy >= 1.21.0

**Examples** (optional):
- pandas >= 1.3.0
- scikit-learn >= 1.0.0
- scipy >= 1.7.0

---

## Quick Start

### Basic Usage

```python
import matplotlib.pyplot as plt
from oxford_matplotlib_theme import apply_oxford_theme

# Apply Oxford theme globally
apply_oxford_theme()

# Create your plot
plt.plot([1, 2, 3], [1, 4, 9])
plt.title('My Oxford Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
```

### Using the Convenience Function

```python
from oxford_matplotlib_theme import oxford_figure

# Create pre-styled figure
fig, ax = oxford_figure()
ax.plot([1, 2, 3], [1, 4, 9])
ax.set_title('My Oxford Plot')
plt.show()
```

### Using Presets

```python
from oxford_matplotlib_theme import apply_preset

# Larger fonts for presentations
apply_preset('presentation')

# Create plots - automatically uses larger fonts
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
plt.show()
```

### Custom Colors

```python
from oxford_matplotlib_theme import get_palette, OXFORD_COLORS

# Use specific Oxford colors
plt.plot(x, y, color=OXFORD_COLORS['coral'])

# Get a color palette
colors = get_palette('vibrant', n_colors=5)
for i, color in enumerate(colors):
    plt.plot(x, data[i], color=color, label=f'Series {i+1}')
```

### Export for Journal Submission

```python
from oxford_matplotlib_theme import save_oxford_figure, get_journal_preset

# Get Nature journal preset
preset = get_journal_preset('nature')

# Create figure with journal size
fig, ax = oxford_figure(figsize=preset['figsize'])
ax.plot(x, y)
ax.set_title('My Research')

# Save with journal settings
save_oxford_figure(fig, 'figure1', format=preset['format'], dpi=preset['dpi'])
# Creates: figure1.svg at 300 DPI
```

---

## Color Palettes

All palettes use official Oxford University brand colors:

| Palette | Colors | Use Case |
|---------|--------|----------|
| **PRIMARY** | 10 | General purpose, most versatile |
| **PROFESSIONAL** | 6 | Business/academic presentations |
| **VIBRANT** | 7 | Eye-catching visualizations |
| **PASTEL** | 7 | Softer, subtle visualizations |
| **DIVERGING** | 5 | Data with meaningful center point |
| **SEQUENTIAL_BLUE** | 5 | Continuous/ordered data |
| **HEALTH** | 5 | Medical/PHC department specific |
| **TRADITIONAL** | 6 | Heritage and stability |
| **CONTEMPORARY** | 6 | Modern and clean |
| **CELEBRATORY** | 6 | Festive and bright |
| **CORPORATE** | 6 | Professional and formal |
| **INNOVATIVE** | 6 | Tech-focused and forward-looking |
| **PHC_THESIS** | 27 | Comprehensive thesis palette |

Access palettes:
```python
from oxford_matplotlib_theme import get_palette, ColorPalettes

# Get palette as list
colors = get_palette('vibrant')

# Access palette class
all_professional = ColorPalettes.PROFESSIONAL
```

---

## Available Presets

| Preset | Description | Font Scale |
|--------|-------------|------------|
| **default** | Standard for academic papers | 1.0 |
| **presentation** | Larger fonts for slides | 1.4 |
| **poster** | Extra large for conference posters | 1.8 |
| **colorblind** | Accessible color palette | 1.0 |
| **minimal** | Clean with grid background | 1.0 |
| **notebook** | Optimized for Jupyter | 1.1 |
| **print** | High contrast for printing | 1.0 |

```python
from oxford_matplotlib_theme import apply_preset, list_presets

# See all presets
list_presets()

# Use a preset
apply_preset('presentation')
```

---

## Journal Export Presets

Built-in settings for major journals:

| Journal | Figure Size (inches) | DPI | Format |
|---------|---------------------|-----|--------|
| **Nature** (single) | 3.5 × 2.5 | 300 | SVG |
| **Nature** (double) | 7.0 × 5.0 | 300 | SVG |
| **PLOS** | 6.83 × 5.0 | 300 | TIFF |
| **BMJ** | 3.27 × 2.5 | 300 | EPS |
| **Lancet** | 3.27 × 2.5 | 300 | TIFF |

```python
from oxford_matplotlib_theme import get_journal_preset

preset = get_journal_preset('nature')
# Returns: {'figsize': (3.5, 2.5), 'dpi': 300, 'format': 'svg'}
```

---

## Examples

### Line Plot with Multiple Series

```python
import numpy as np
from oxford_matplotlib_theme import apply_oxford_theme

apply_oxford_theme()

x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(x, np.sin(x), label='sin(x)', linewidth=2)
ax.plot(x, np.cos(x), label='cos(x)', linewidth=2)

ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')
ax.set_title('Trigonometric Functions')
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()
```

### Bar Chart with Oxford Colors

```python
from oxford_matplotlib_theme import get_palette

categories = ['A', 'B', 'C', 'D']
values = [23, 45, 56, 78]
colors = get_palette('professional', n_colors=4)

fig, ax = plt.subplots()
ax.bar(categories, values, color=colors[0])
ax.set_ylabel('Values')
ax.set_title('Category Comparison')
ax.grid(True, axis='y', alpha=0.3)
plt.show()
```

### ROC Curve for Clinical ML

```python
from sklearn.metrics import roc_curve, auc
from oxford_matplotlib_theme import apply_oxford_theme, get_palette

apply_oxford_theme()
colors = get_palette('primary', n_colors=3)

# Assuming you have y_true and y_pred
fpr, tpr, _ = roc_curve(y_true, y_pred)
roc_auc = auc(fpr, tpr)

fig, ax = plt.subplots(figsize=(8, 8))
ax.plot(fpr, tpr, color=colors[0], linewidth=2.5,
       label=f'ROC curve (AUC = {roc_auc:.3f})')
ax.plot([0, 1], [0, 1], 'k--', linewidth=1.5, alpha=0.5)

ax.set_xlabel('False Positive Rate')
ax.set_ylabel('True Positive Rate')
ax.set_title('ROC Curve - Clinical Prediction Model')
ax.legend(loc='lower right')
ax.grid(True, alpha=0.3)
plt.show()
```

### More Examples

See the `examples/` directory for complete runnable examples:
- `basic_usage.py` - 6 fundamental plot types
- `clinical_ml.py` - ROC, PR, calibration curves for healthcare research
- `publication_figures.py` - Multi-panel journal-ready figures
- `migration_comparison.py` - Plotly to Matplotlib migration guide

---

## Advanced Usage

### Custom Color Cycles

```python
from oxford_matplotlib_theme import apply_oxford_theme

# Use specific colors in custom order
custom_colors = ['coral', 'aqua', 'oxford_blue', 'vivid_green']
apply_oxford_theme(color_cycle=custom_colors)
```

### Font Scaling

```python
# Make all fonts 50% larger
apply_oxford_theme(font_scale=1.5)

# For presentations
apply_oxford_theme(font_scale=1.4)

# For posters
apply_oxford_theme(font_scale=1.8)
```

### Adding Branding

```python
from oxford_matplotlib_theme import add_oxford_branding

fig, ax = oxford_figure()
ax.plot([1, 2, 3], [1, 4, 9])

# Add watermark
add_oxford_branding(
    fig,
    add_watermark=True,
    watermark_text='University of Oxford',
    position='bottom_right',
    opacity=0.5
)
plt.show()
```

---

## Migration from oxford-plotly-theme

If you're migrating from the Plotly version:

| Plotly | Matplotlib |
|--------|------------|
| `create_oxford_figure()` | `oxford_figure()` returns `(fig, ax)` |
| `fig.add_trace(go.Scatter(...))` | `ax.plot(...)` |
| `get_color_palette()` | `get_palette()` |
| `fig.write_image()` (needs kaleido) | `fig.savefig()` (native) |
| Manual sizing | `get_journal_preset()` |

**Key benefits of matplotlib version:**
- No browser/kaleido dependency
- Faster export
- Built-in presets
- Better LaTeX integration
- Native format support

See `examples/migration_comparison.py` and `docs/MIGRATION_GUIDE.md` for detailed migration instructions.

---

## Documentation

- **API Reference**: See `docs/API_REFERENCE.md` for complete function documentation
- **Migration Guide**: See `docs/MIGRATION_GUIDE.md` for Plotly to Matplotlib migration
- **Examples**: See `examples/` directory for runnable code

---

## Contributing

This theme is maintained for internal use at the University of Oxford. For bug reports or feature requests, please open an issue on GitHub.

---

## License

MIT License - Copyright (c) 2025 Sami Adnan

Based on [Oxford University Brand Guidelines](https://communications.admin.ox.ac.uk/communications-resources/visual-identity/identity-guidelines/colours)

---

## Acknowledgments

- Oxford University Communications Office for brand guidelines
- Inspired by `oxford-plotly-theme`
- Built for clinical prediction research at Oxford Primary Health Care

---

## Contact

Sami Adnan
Nuffield Department of Primary Care Health Sciences 
University of Oxford

For questions about Oxford brand guidelines, contact the [Oxford Communications Office](https://communications.admin.ox.ac.uk/).
