Metadata-Version: 2.4
Name: plotshelf
Version: 1.1.1
Summary: Save a final matplotlib figure once; find it later in a searchable gallery.
Author-email: Rohit Raut <rohit.raut@yale.edu>
License-Expression: MIT
Project-URL: Homepage, https://github.com/rohitraut/plotshelf
Keywords: matplotlib,plots,figures,logbook,research
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib
Dynamic: license-file

# plotshelf

Save a final matplotlib figure once, find it later.

You make a plot, it's good, it goes in a talk. Three months later you need it
again and you can't remember which script made it, so you remake it. plotshelf
is the smallest thing that stops that.

```bash
pip install plotshelf
```

```python
from plotshelf import save_plot

save_plot(fig, name="Accuracy vs training set size",
          note="held-out test set, 5 seeds averaged, N=12000",
          tags="accuracy, baseline")
```

Every plot gets its own folder, named after the plot, holding every file for it:

```
plots/accuracy_vs_training_set_size/
    accuracy_vs_training_set_size.pdf     vector master, for slides and papers
    accuracy_vs_training_set_size.png     preview, dpi=200
    accuracy_vs_training_set_size.json    name, note, tags, source script, date
```

So a plot and everything belonging to it move, copy and delete as one unit.

## Notes

- **`name` is required, and keyword-only.** It is the identity of the plot: it
  names the folder, names the files, and decides what overwrites what. Making it
  positional made it too easy to save a plot under the wrong one.
- **PDF is the master.** Text stays text and curves stay curves, so there is no
  resolution to regret later. Pass `png=False` if you don't want the raster copy, or
  `pdf=False` if you only want the raster. Both off is an error.
- **`source` is auto-detected** from the calling script, so every plot records
  what made it. In Jupyter it records `"notebook"`.
- **Same name overwrites** that plot's folder. Punctuation and case are ignored
  when forming the folder name. Use a different name to keep both versions.
- **No index file.** Nothing is tracked anywhere but on disk, so nothing can
  disagree with what's actually there.

## Gallery (optional, off by default)

```python
save_plot(fig, name="...", html=True)   # also rebuilds plots/gallery.html
```

Open `gallery.html` and type in the filter box: it matches across name, note,
tags and source script at once. It is rebuilt from the folders on disk, so
deleting a plot folder removes it from the gallery on the next build.

## Help

Three ways, no docs site to go look up:

```python
import plotshelf
plotshelf.help()            # one-screen cheatsheet: every function, every argument
help(plotshelf.save_plot)   # per-argument detail, the normal Python way
```
```bash
python -m plotshelf         # same cheatsheet, from the shell
```

## API

```
save_plot(fig, *, name, note="", tags="", source=None,
          dir="plots", pdf=True, png=True, html=False) -> Path
```

| | required? | default | what it is |
|---|---|---|---|
| `fig` | **yes** | | matplotlib Figure, passed positionally |
| `name` | **yes** | | keyword-only; names the folder and the files |
| `note` | no | `""` | dataset, cuts, sample size, what it shows |
| `tags` | no | `""` | `"accuracy, baseline"`, or a list |
| `source` | no | auto | detected from the calling script |
| `dir` | no | `"plots"` | where the plot folders live |
| `pdf` | no | `True` | write the vector master |
| `png` | no | `True` | write a dpi=200 raster copy |
| `html` | no | `False` | also rebuild `<dir>/gallery.html` |

Returns the plot's folder.

`gallery(dir="plots") -> Path` builds the gallery by hand.

`help() -> None` prints the cheatsheet.

## Development

```bash
python plotshelf.py --test
```
Runs the built-in self-check in a temp directory: folder layout, mandatory
keyword `name`, `pdf`/`png` toggles, overwrite-by-name, corrupt sidecars, and
the gallery. Prints one `ok ->` line, or raises.

MIT.
