Metadata-Version: 2.4
Name: buencolors
Version: 1.0.1
Summary: A pythonic port of the BuenColors R library for handy color palettes.
Author-email: Austin Varela <aav4003@med.cornell.edu>, Caleb Lareau <lareauc@mskcc.org>
Maintainer-email: Austin Varela <aav4003@med.cornell.edu>
License-Expression: MIT
Project-URL: Homepage, https://github.com/austinv11/PyBuenColors
Project-URL: Repository, https://github.com/austinv11/PyBuenColors
Project-URL: Documentation, https://austinv11.github.io/PyBuenColors/
Project-URL: Bug Tracker, https://github.com/austinv11/PyBuenColors/issues
Project-URL: Changelog, https://github.com/austinv11/PyBuenColors/releases
Keywords: colors,visualization,matplotlib,data-science,palettes,bioinformatics
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Framework :: Matplotlib
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib>=3.9.0
Requires-Dist: numpy>=2.0.1
Requires-Dist: pandas>=2.3.0
Requires-Dist: scipy>=1.14.0
Provides-Extra: dev
Requires-Dist: setuptools>=80; extra == "dev"
Requires-Dist: mkdocs-material>=9.6.18; extra == "dev"
Requires-Dist: mkdocs>=1.6.1; extra == "dev"
Requires-Dist: pytest>=8.4.1; extra == "dev"
Requires-Dist: mkdocstrings[python]>=0.25; extra == "dev"
Requires-Dist: mkdocstrings-python>=1.0; extra == "dev"
Requires-Dist: mkdocs-jupyter>=0.25.1; extra == "dev"
Requires-Dist: mkdocs-api-autonav>=0.4.0; extra == "dev"
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.5.0; extra == "dev"
Dynamic: license-file

# PyBuenColors

[![PyPI version](https://img.shields.io/pypi/v/buencolors.svg)](https://pypi.org/project/buencolors/)
[![Build Status](https://img.shields.io/github/actions/workflow/status/austinv11/PyBuenColors/ci.yml?branch=master)](https://github.com/austinv11/PyBuenColors/actions)
[![License](https://img.shields.io/github/license/austinv11/PyBuenColors.svg)](https://github.com/austinv11/PyBuenColors/blob/master/LICENSE)

A pythonic port of the [BuenColors R package](https://github.com/caleblareau/BuenColors) for convenient scientific color palettes and matplotlib styles.

Color palettes are a direct port from the R package, with many based on the [wesanderson](https://github.com/karthik/wesanderson) R package.

## Installation

```bash
pip install buencolors
```

## Quick Start

### Using the Pretty Plot Style

The easiest way to improve your matplotlib plots is to use the included `pretty-plot` style:

```python
import matplotlib.pyplot as plt
import numpy as np

# Apply the pretty-plot style
plt.style.use('pretty-plot')

# Create a beautiful plot
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
```

**Before (default):**

![Default Style](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/default_style.png)

**After (pretty-plot):**

![Pretty Style](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/pretty_style.png)

### Using Color Palettes

BuenColors automatically registers all palettes as matplotlib colormaps:

```python
import buencolors as bc
import matplotlib.pyplot as plt
import numpy as np

# List available palettes
bc.list_palettes()

# Palettes are available directly as colormaps
plt.style.use('pretty-plot')
data = np.random.randn(100, 100)
plt.imshow(data, cmap='Zissou')
plt.colorbar()
plt.show()

# Or use get_palette() to extract individual colors
colors = bc.get_palette('Zissou')
for i, color in enumerate(colors):
    plt.plot([0, 1], [i, i], color=color, linewidth=10)
plt.show()
```

## Features

### Helper Functions

BuenColors provides several utility functions to make your plots publication-ready:

#### Eject Legend

Move legends outside the plot area to avoid obscuring data:

```python
import matplotlib as plt
import buencolors as bc

# Your plot code here
plt.plot(x, y1, label='Dataset 1')
plt.plot(x, y2, label='Dataset 2')

# Eject the legend to the right
bc.eject_legend()
```

![Eject Legend Example](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/util_eject_legend.png)

#### Rotate X-Tick Labels

Automatically rotate discrete x-tick labels for better readability:

```python
bc.rotate_discrete_xticks()
```

![Rotate XTicks Example](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/util_rotate_xticks.png)

#### Grab Legend

Extract a legend to a separate figure for independent saving or publication:

```python
# Create a plot with legend
plt.plot(x, y1, label='Dataset 1')
plt.plot(x, y2, label='Dataset 2')
plt.legend()

# Extract legend to separate figure (removes from original by default)
legend_fig = bc.grab_legend()
legend_fig.savefig('legend.pdf', bbox_inches='tight')
plt.savefig('plot.pdf')  # Plot saved without legend

# Or keep legend on original plot
legend_fig = bc.grab_legend(remove=False)
legend_fig.savefig('legend_copy.pdf', bbox_inches='tight')
plt.show()  # Original plot still has legend
```

![Grab Legend Example](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/util_grab_legend.png)

#### Color by Density

Color scatter plot points by their density:

```python
x = np.random.randn(1000)
y = np.random.randn(1000)
density = bc.get_density(x, y)

plt.scatter(x, y, c=density, cmap='viridis', s=5)
plt.colorbar(label='Density')
```

![Density Example](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/util_density.png)

#### Shuffle Plot Order

Randomize the order of plot elements to avoid overplotting bias:

```python
x_shuffled, y_shuffled, colors_shuffled = bc.shuffle(x, y, colors)
plt.scatter(x_shuffled, y_shuffled, c=colors_shuffled)
```

![Shuffle Example](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/util_shuffle.png)

#### Number to Color

Map numerical values to colors from a palette:

```python
values = [1, 2, 3, 4, 5]
colors = bc.number_to_color(values, palette='Zissou')
```

![Number to Color Example](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/util_number_to_color.png)

## Single-Cell Analysis

BuenColors provides specialized functions for single-cell analysis visualization, designed to work seamlessly with Scanpy and AnnData objects.

### Installation for Single-Cell Features

To use the single-cell features, install with scanpy and anndata:

```bash
pip install buencolors scanpy anndata
```

### Clean UMAP Visualization

The `clean_umap()` function creates publication-ready UMAP plots with minimal decorations:

```python
import scanpy as sc
import buencolors as bc
import matplotlib.pyplot as plt

# Load example dataset
adata = sc.datasets.pbmc3k_processed()

# Create a clean UMAP colored by cell type
with plt.style.context('pretty-plot'):
    bc.clean_umap(adata, color='louvain', palette='lawhoops')
```

Features of `clean_umap()`:

- **Minimal decorations**: No borders, ticks, or frame
- **Custom L-shaped axis indicators**: Small arrows showing UMAP dimensions
- **Auto-ejected legend**: Automatically positioned to the right to avoid obscuring data
- **Shuffled cells**: Randomizes plotting order to avoid non-random ordering artifacts
- **scVelo-style outlines**: Concentric black/white rings around points

![Clean UMAP Example](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/single_cell_clean_umap.png)

### scVelo-Style Outlines

Add concentric outline rings to UMAP points via the `outline_style` parameter:

```python
# Outline every cell
bc.clean_umap(adata, color='louvain', outline_style=True)

# Highlight one group — all other cells are dimmed
bc.clean_umap(adata, color='louvain', outline_style='CD4 T cells')

# Highlight multiple groups
bc.clean_umap(adata, color='louvain', outline_style=['NK cells', 'CD8 T cells'])

# Adjust ring widths: (black_bg_fraction, white_gap_fraction)
bc.clean_umap(adata, color='louvain', outline_style=True, outline_width=(0.5, 0.1))
```

`outline_style` accepts:

| Value | Effect |
|---|---|
| `False` (default) | No outlines |
| `True` | Outline every cell |
| `"Group name"` | Dim all cells, outline the named group |
| `["G1", "G2"]` | Dim all cells, outline the listed groups |

## Examples

For detailed examples and interactive notebooks, see the [documentation](https://austinv11.github.io/PyBuenColors/) or the [docs/examples directory](docs/examples/).

## Available Palettes

![All Palettes](https://raw.githubusercontent.com/austinv11/PyBuenColors/master/figures/all_palettes.png)

## License

This project is licensed under the MIT License.

## Credits

- Original [BuenColors R package](https://github.com/caleblareau/BuenColors)
- Wes Anderson palettes inspired by [wesanderson](https://github.com/karthik/wesanderson)
