Metadata-Version: 2.4
Name: TriShade
Version: 0.1
Summary: Rose Pine, Dracula, Palenight — 20 variants x 20 unique colours for Matplotlib & Seaborn
Author: Jahid Hasan
License: MIT
Project-URL: Homepage, https://github.com/msjahid/TriShade
Project-URL: Repository, https://github.com/msjahid/TriShade
Project-URL: Issues, https://github.com/msjahid/TriShade/issues
Keywords: matplotlib,seaborn,theme,plotting,dracula,rose-pine,palenight,visualization,dark-theme,color-palette
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib>=3.5
Provides-Extra: seaborn
Requires-Dist: seaborn>=0.12; extra == "seaborn"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: twine>=4; extra == "dev"
Requires-Dist: build>=1; extra == "dev"
Dynamic: license-file

# TriShade

**Three beautiful Matplotlib themes — Rosé Pine · Dracula · Palenight**
Each theme has **20 variants** × **20 unique accent colours**.

---

## Table of Contents

1. [Installation](#installation)
2. [Quick Start](#quick-start)
3. [Info & Help](#info--help)
4. [Themes & Variants](#themes--variants)
5. [apply() — full parameter reference](#apply--full-parameter-reference)
6. [palette()](#palette)
7. [subplots()](#subplots)
8. [Font Guide](#font-guide)
9. [Grid Control](#grid-control)
10. [Font Styling](#font-styling)
11. [Works with Seaborn](#works-with-seaborn)
12. [Legend Customisation](#legend-customisation)
13. [Real Example](#real-example)

---

## Installation

```bash
pip install TriShade
```

Add fonts to the package folder (optional but recommended):

```
trishade/
└── fonts/
    ├── JetBrainsMono-Regular.ttf
    ├── SourceCodePro-Regular.ttf
    ├── CascadiaCode.ttf
    ├── Fira Code Regular 400.ttf
    ├── Hack-Regular.ttf
    ├── Microsoft Sans Serif.ttf
    ├── Operator Mono Book Regular.otf
    └── Roboto-Regular.ttf
```

Download sources:

- JetBrains Mono → https://github.com/JetBrains/JetBrainsMono/releases
- Source Code Pro → https://github.com/adobe-fonts/source-code-pro/releases
- Cascadia Code → https://github.com/microsoft/cascadia-code/releases
- Fira Code → https://github.com/tonsky/FiraCode/releases
- Hack → https://github.com/source-foundry/Hack/releases
- Roboto → https://fonts.google.com/specimen/Roboto

---

## Quick Start

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

# 1. Apply a theme ONCE at the top
ts.rosepine.apply("moon")

# 2. Get the 20 accent colours
pal = ts.rosepine.palette("moon")

# 3. Plot normally — theme is applied globally
x = np.linspace(0, 2 * np.pi, 100)
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, np.sin(x), color=pal[0], label="sin")
ax.plot(x, np.cos(x), color=pal[1], label="cos")
ax.legend()
plt.show()
```

---

## Info & Help

```python
import trishade as ts

# package version & author
print(ts.__version__)          # 0.1
print(ts.__author__)           # Jahid Hasan

# theme list
print(ts.__all__)
# ['rosepine', 'dracula', 'palenight']

# variant lists per theme
print(ts.rosepine.VARIANTS)    # list of 20 variant names
print(ts.dracula.VARIANTS)     # list of 20 variant names
print(ts.palenight.VARIANTS)   # list of 20 variant names

# font list
print(list(ts._BUNDLED_FONTS.keys()))
# ['jetbrains', 'sourcecodepro', 'cascadia', 'fira_code',
#  'hack', 'microsoft_sans', 'operator_mono', 'roboto']

# full reference — themes, variants, fonts, params
ts.info()

# per-theme parameter reference
ts.rosepine.help()
ts.dracula.help()
ts.palenight.help()
```

---

## Themes & Variants

### Rosé Pine — 20 variants

| #   | Variant     | Style                |
| --- | ----------- | -------------------- |
| 1   | `main`      | dark original        |
| 2   | `moon`      | softer dark          |
| 3   | `dawn`      | light                |
| 4   | `midnight`  | deep dark            |
| 5   | `ember`     | warm dark            |
| 6   | `slate`     | cool grey dark       |
| 7   | `forest`    | green dark           |
| 8   | `desert`    | warm sand dark       |
| 9   | `ocean`     | deep blue dark       |
| 10  | `lavender`  | purple dark          |
| 11  | `crimson`   | red dark             |
| 12  | `teal`      | teal dark            |
| 13  | `sunset`    | orange warm dark     |
| 14  | `mono`      | monochrome dark      |
| 15  | `quartz`    | pink dark            |
| 16  | `aurora`    | northern lights dark |
| 17  | `parchment` | warm light           |
| 18  | `linen`     | soft light           |
| 19  | `neon`      | electric dark        |
| 20  | `cosmos`    | deep violet dark     |

### Dracula — 20 variants

`classic` · `soft` · `ink` · `blood` · `storm` · `toxic` · `amber` ·
`synthwave` · `volcanic` · `arctic` · `cyber` · `coffee` · `rose` ·
`void` · `galaxy` · `silver` · `jungle` · `velvet` · `neon` · `paper`

### Palenight — 20 variants

`default` · `contrast` · `midnight` · `abyss` · `noir` · `nebula` ·
`twilight` · `rose` · `dusk` · `arctic` · `steel` · `frost` · `ash` ·
`smoke` · `pebble` · `neon` · `vivid` · `day` · `lace` · `aurora`

---

## apply() — full parameter reference

```python
ts.rosepine.apply(
    variant        = "moon",        # which colour palette to use
    font           = "jetbrains",   # which font to use
    font_size_base = 13,            # base font size in points
    font_weight    = "normal",      # text weight
    grid           = False,         # grid lines
    font_color     = None,          # override ALL text colour
    label_color    = None,          # override axis labels & title only
    tick_color     = None,          # override tick labels only
)
```

### variant

```python
ts.rosepine.apply("main")
ts.rosepine.apply("moon")
ts.rosepine.apply("dawn")
ts.dracula.apply("classic")
ts.dracula.apply("synthwave")
ts.palenight.apply("default")
ts.palenight.apply("nebula")
```

### font

```python
ts.rosepine.apply("moon", font="jetbrains")        # JetBrains Mono (default)
ts.rosepine.apply("moon", font="sourcecodepro")    # Source Code Pro
ts.rosepine.apply("moon", font="cascadia")         # Cascadia Code
ts.rosepine.apply("moon", font="fira_code")        # Fira Code
ts.rosepine.apply("moon", font="hack")             # Hack
ts.rosepine.apply("moon", font="microsoft_sans")   # Microsoft Sans Serif
ts.rosepine.apply("moon", font="operator_mono")    # Operator Mono
ts.rosepine.apply("moon", font="roboto")           # Roboto
ts.rosepine.apply("moon", font="fonts/MyFont.ttf") # your own font file
ts.rosepine.apply("moon", font=None)               # Matplotlib default
```

### font_size_base

```python
ts.dracula.apply("classic", font_size_base=10)   # small
ts.dracula.apply("classic", font_size_base=13)   # default
ts.dracula.apply("classic", font_size_base=16)   # large
# tick labels = 85% of base,  title = 115% of base
```

### font_weight

```python
ts.rosepine.apply("moon", font_weight="normal")  # default
ts.rosepine.apply("moon", font_weight="bold")    # bold everywhere
ts.rosepine.apply("moon", font_weight="light")   # light everywhere
```

### grid

```python
ts.rosepine.apply("moon", grid=False)   # off — default
ts.rosepine.apply("moon", grid=True)    # both axes
ts.rosepine.apply("moon", grid="x")     # vertical lines only
ts.rosepine.apply("moon", grid="y")     # horizontal lines only
```

### font_color / label_color / tick_color

```python
# override ALL text at once
ts.dracula.apply("classic", font_color="#ffffff")

# override specific parts independently
ts.dracula.apply("classic",
    label_color = "#ff79c6",   # axis labels & title
    tick_color  = "#8be9fd",   # tick labels
)

# combine all three
ts.dracula.apply("classic",
    font_color  = "#f8f8f2",
    label_color = "#ff79c6",
    tick_color  = "#8be9fd",
)
```

---

## palette()

Returns a list of **20 unique hex strings** for the given variant.

```python
pal = ts.rosepine.palette("moon")
# ['#eb6f92', '#9ccfd8', '#f6c177', '#c4a7e7', ...]  — 20 colours

pal = ts.dracula.palette("classic")
pal = ts.palenight.palette("nebula")

# use slices for different chart types
ax.bar(cats, vals, color=pal[:6])       # 6 bars — 6 colours
ax.plot(x, y,      color=pal[0])        # 1 line
ax.scatter(x, y,   color=pal[3])        # scatter
for i in range(4):
    ax.plot(x, data[i], color=pal[i])   # 4 lines — 4 colours
```

---

## subplots()

Applies the theme and creates the figure in one call.

```python
# basic
fig, ax = ts.rosepine.subplots(variant="moon")

# with layout
fig, axes = ts.dracula.subplots(2, 2, variant="classic", figsize=(12, 8))

# with all params
fig, ax = ts.palenight.subplots(
    1, 2,
    variant        = "nebula",
    font           = "fira_code",
    font_size_base = 14,
    font_weight    = "bold",
    figsize        = (12, 5),
)
```

---

## Font Guide

Font recommendations by use case:

| Use case                  | Recommended font           |
| ------------------------- | -------------------------- |
| Data science / code plots | `jetbrains` or `fira_code` |
| Academic / reports        | `sourcecodepro`            |
| Modern dashboards         | `roboto` or `cascadia`     |
| Terminal aesthetic        | `hack`                     |
| General purpose           | `jetbrains` (default)      |

```python
# check which fonts are available
print(list(ts._BUNDLED_FONTS.keys()))

# apply with font
ts.rosepine.apply("moon", font="fira_code")
```

---

## Grid Control

Always start with `grid=False`, then toggle per axis:

```python
ts.rosepine.apply("moon", grid=False)   # global default off

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 4))

ax1.grid(True)             # both axes on
ax2.grid(True, axis="y")   # horizontal only
ax3.grid(False)            # off — no call needed
```

---

## Font Styling

```python
# bold everything
ts.dracula.apply("classic", font_weight="bold")

# large font
ts.dracula.apply("classic", font_size_base=16)

# custom colours
ts.dracula.apply("classic",
    label_color = "#ff79c6",   # axis labels & title
    tick_color  = "#8be9fd",   # tick labels
)

# all controls together
ts.rosepine.apply(
    "moon",
    font           = "fira_code",
    font_size_base = 14,
    font_weight    = "bold",
    font_color     = "#e0def4",
    label_color    = "#eb6f92",
    tick_color     = "#9ccfd8",
    grid           = False,
)
```

---

## Works with Seaborn

```python
import seaborn as sns
import trishade as ts

ts.dracula.apply("classic", grid=False)
pal = ts.dracula.palette("classic")

# pass palette=pal[:n]  where n = number of hue groups
sns.scatterplot(data=df, x="x",   y="y",   hue="group",  palette=pal[:3])
sns.boxplot(    data=df, x="day", y="val",               palette=pal[:4])
sns.histplot(   data=df, x="val", hue="time", kde=True,  palette=pal[:2])
sns.violinplot( data=df, x="day", y="tip",               palette=pal[:4])
sns.barplot(    data=df, x="cat", y="val",               palette=pal[:5])
```

---

## Legend Customisation

`apply()` sets global defaults. Customise per-plot directly via Matplotlib:

```python
ts.rosepine.apply("moon", grid=False)
pal = ts.rosepine.palette("moon")

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x, np.sin(x), color=pal[0], label="sin")
ax.plot(x, np.cos(x), color=pal[1], label="cos")

ax.legend(
    loc            = "upper right",   # position
    fontsize       = 12,              # font size
    title          = "Functions",     # legend title
    title_fontsize = 13,
    facecolor      = "#282A36",       # background colour
    edgecolor      = "#ff79c6",       # border colour
    labelcolor     = "#f8f8f2",       # text colour
    framealpha     = 0.9,
    ncols          = 2,               # number of columns
)
plt.show()
```

---

## Real Example

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

# apply theme once at the top
ts.rosepine.apply(
    "moon",
    font           = "jetbrains",
    font_size_base = 13,
    font_weight    = "normal",
    grid           = False,
)
pal = ts.rosepine.palette("moon")

# data
tree_number = [10, 5, 15, 8, 6, 1, 13]
tree_name   = ['Orange','Banana','Litchi','Guava','Mango','Apple','Cherries']
tree_pos    = np.arange(len(tree_name))

# plot
fig, ax = plt.subplots(figsize=(10, 5))
bars = ax.bar(tree_pos, tree_number, color=pal[:7], zorder=2)
ax.set_xticks(tree_pos)
ax.set_xticklabels(tree_name)
ax.set_title("Tree Count by Fruit")
ax.set_xlabel("Fruit")
ax.set_ylabel("Count")
ax.grid(True, axis="y")

# value labels on bars
for bar, val in zip(bars, tree_number):
    ax.text(bar.get_x() + bar.get_width() / 2,
            bar.get_height() + 0.2,
            str(val), ha="center", va="bottom", fontsize=10)

plt.tight_layout()
plt.show()
```

---

## License

MIT — Jahid Hasan
