Skip to content

Commit dc2c223

Browse files
committed
add docs
1 parent a934334 commit dc2c223

17 files changed

Lines changed: 981 additions & 887 deletions

.github/workflows/docs.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: docs
2+
on:
3+
push:
4+
branches:
5+
- master
6+
- main
7+
permissions:
8+
contents: write
9+
jobs:
10+
deploy:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Configure Git Credentials
15+
run: |
16+
git config user.name github-actions[bot]
17+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
18+
- uses: actions/setup-python@v5
19+
with:
20+
python-version: 3.x
21+
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
22+
- uses: actions/cache@v4
23+
with:
24+
key: mkdocs-material-${{ env.cache_id }}
25+
path: ~/.cache
26+
restore-keys: |
27+
mkdocs-material-
28+
- run: pip install mkdocs-material mkdocstrings[python]
29+
- run: mkdocs gh-deploy --force

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
run-local-mkdocs-server:
2+
uv run mkdocs serve

docs/api.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# API Reference
2+
3+
This section is rendered from the package's type hints and NumPy-style docstrings using [`mkdocstrings`](https://mkdocstrings.github.io/). Update the inline documentation in `src/physics_plot/` and rebuild the docs to refresh the content.
4+
5+
## Legend Containers
6+
7+
::: physics_plot.utils.Handles

docs/development.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!-- # Development
2+
3+
This guide outlines how to set up a local development environment, run checks, and contribute improvements to Physics Plot.
4+
5+
## Environment Setup
6+
7+
```bash
8+
uv sync --group dev
9+
```
10+
11+
The command installs runtime dependencies along with development tooling such as Ruff and Black.
12+
13+
## Quality Gates
14+
15+
- `uv run ruff check src` keeps imports sorted and enforces the style guide.
16+
- `uv run black --check src` validates formatting (run without `--check` to auto-format).
17+
- `uv run pytest` executes the test suite once it exists.
18+
19+
Run the commands before opening a pull request so CI stays green.
20+
21+
## Visual Regression Checklist
22+
23+
1. Rebuild figures under `examples/` (start with the Bode plot CLI).
24+
2. Compare the generated images against the versions committed to the repository.
25+
3. Document notable deltas in the pull request description and attach screenshots.
26+
27+
## Documentation
28+
29+
The documentation is built with MkDocs Material:
30+
31+
```bash
32+
uv run mkdocs serve
33+
```
34+
35+
The command starts a live-reloading preview at `http://127.0.0.1:8000`. Commit relevant doc updates alongside code changes to keep users informed.
36+
37+
!!! tip
38+
The project uses `mkdocstrings` to render API docs from docstrings. If you manage dependencies manually, install `mkdocstrings[python]` in addition to `mkdocs-material`.
39+
40+
## Releasing
41+
42+
1. Bump the version in `pyproject.toml`.
43+
2. Regenerate `uv.lock` if dependencies changed (`uv lock --upgrade-package physics-plot`).
44+
3. Build the distribution with `uv build`.
45+
4. Publish via `uv publish` or `twine upload dist/*`.
46+
47+
Coordinate releases through GitHub issues so maintainers can review changes and test across platforms. -->
48+

docs/examples.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Examples
2+
3+
See the [examples directory on GitHub](https://github.com/c0rychu/physics-plot/tree/main/examples).
4+
5+
<!-- Physics Plot ships with runnable demos so you can see how the style sheet and utilities behave on real data. Clone the repository locally, install the dependencies, and run the scripts from the project root.
6+
7+
## Bode Plot
8+
9+
```bash
10+
uv run python examples/bode-plot.py
11+
```
12+
13+
The script generates a two-panel magnitude/phase plot for a first-order low-pass filter:
14+
15+
![Bode plot example](https://raw.githubusercontent.com/c0rychu/physics-plot/main/examples/bode-plot%402x.png)
16+
17+
Look for the balanced serif typography, synchronised axis limits, and consistent legend placement driven by the default style.
18+
19+
## Violin Plot
20+
21+
Open `examples/violin-plot.ipynb` in JupyterLab or VS Code and execute the cells:
22+
23+
The notebook demonstrates using `physics_plot.Handles` to build legend entries for violin plots that otherwise omit labels.
24+
25+
![Violin plot example](https://raw.githubusercontent.com/c0rychu/physics-plot/main/examples/violin-plot%402x.png)
26+
27+
!!! tip
28+
Capture before/after screenshots when you tweak the style sheet or utilities. Attach them to issues or pull requests to document visual changes.
29+
30+
## Your Own Figures
31+
32+
- Swap in your data but keep the script structure to validate visual regressions quickly.
33+
- Use the examples as smoke tests by running them after style tweaks; unexpected exceptions often reveal mismatched dependencies or missing fonts.
34+
- Consider adding new examples that cover edge cases (e.g., log scales, multiple axes) if you find gaps. Place supporting assets under `examples/` so contributors can reproduce the output.
35+
-->

docs/fig/bode-plot@2x.png

223 KB
Loading

docs/fig/compare-sg.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import matplotlib.pyplot as plt
2+
import numpy as np
3+
4+
5+
def sine_gaussian(t, f0, sigma, t0=0, A=1):
6+
return (
7+
A
8+
* np.exp(-((t - t0) ** 2) / (2 * sigma**2))
9+
* np.sin(2 * np.pi * f0 * (t - t0))
10+
)
11+
12+
13+
t = np.linspace(-0.01, 0.01, 2000)
14+
y = sine_gaussian(t, f0=300, t0=-0.002, sigma=0.002)
15+
16+
with plt.style.context("physics_plot.pp_base"):
17+
plt.figure()
18+
plt.plot(t, y, label="offset = 0")
19+
plt.plot(t, y - 0.5, label="offset = -0.5")
20+
plt.plot(t, y - 1, label="offset = -1")
21+
plt.legend(loc="upper right")
22+
plt.title(r"$\texttt{physics_plot}$ style")
23+
plt.xlabel("Time [s]")
24+
plt.ylabel("Amplitude")
25+
plt.tight_layout()
26+
plt.savefig("with-pp@2x.png")
27+
28+
plt.figure()
29+
plt.plot(t, y, label="offset = 0")
30+
plt.plot(t, y - 0.5, label="offset = -0.5")
31+
plt.plot(t, y - 1, label="offset = -1")
32+
plt.legend(loc="upper right")
33+
plt.title("Matplotlib default style")
34+
plt.xlabel("Time [s]")
35+
plt.ylabel("Amplitude")
36+
plt.tight_layout()
37+
plt.savefig("without-pp@2x.png", dpi=600)

docs/fig/compare.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import matplotlib.pyplot as plt
2+
import numpy as np
3+
4+
5+
# Functions for example plot
6+
def db(x):
7+
return 20.0 * np.log10(x)
8+
9+
10+
def model(f):
11+
return 10.0 / (f - 1.0j * 10)
12+
13+
14+
# Plot with physics_plot style
15+
with plt.style.context("physics_plot.pp_base"):
16+
fig, (ax_m, ax_p) = plt.subplots(
17+
nrows=2, ncols=1, figsize=(5, 3.5), constrained_layout=True
18+
)
19+
fig.suptitle(r"Low Pass Filter ($\texttt{physics_plot}$ style)")
20+
f = np.logspace(0, 3, 1000)
21+
22+
# Magnitude
23+
ax_m.semilogx(f, db(np.abs(model(f))), "r", label="LPF")
24+
ax_m.set_xlim(1e0, 1e3)
25+
ax_m.set_ylabel("Magnitude [dB]")
26+
ax_m.grid(visible=True, which="major")
27+
ax_m.grid(visible=True, which="minor", linestyle=":")
28+
ax_m.legend(loc=1)
29+
30+
# Phase
31+
ax_p.semilogx(f, np.angle(model(f), deg=True), "r", label="LPF")
32+
ax_p.set_xlim(1e0, 1e3)
33+
ax_p.set_ylim(0, 90)
34+
ax_p.set_xlabel("Frequency [Hz]")
35+
ax_p.set_ylabel("Phase [deg]")
36+
ax_p.grid(visible=True, which="major")
37+
ax_p.grid(visible=True, which="minor", linestyle=":")
38+
ax_p.legend(loc=1)
39+
40+
# fig.savefig("with-pp@2x.png")
41+
fig.savefig("bode-plot@2x.png")
42+
43+
44+
# # Plot without physics_plot style
45+
# fig, (ax_m, ax_p) = plt.subplots(
46+
# nrows=2, ncols=1, figsize=(5, 3.5), constrained_layout=True
47+
# )
48+
# fig.suptitle("Low Pass Filter (Matplotlib default style)")
49+
# f = np.logspace(0, 3, 1000)
50+
51+
# # Magnitude
52+
# ax_m.semilogx(f, db(np.abs(model(f))), "b", label="LPF")
53+
# ax_m.set_xlim(1e0, 1e3)
54+
# ax_m.set_ylabel("Magnitude [dB]")
55+
# ax_m.grid(visible=True, which="major")
56+
# ax_m.grid(visible=True, which="minor", linestyle=":")
57+
# ax_m.legend(loc=1)
58+
59+
# # Phase
60+
# ax_p.semilogx(f, np.angle(model(f), deg=True), "b", label="LPF")
61+
# ax_p.set_xlim(1e0, 1e3)
62+
# ax_p.set_ylim(0, 90)
63+
# ax_p.set_xlabel("Frequency [Hz]")
64+
# ax_p.set_ylabel("Phase [deg]")
65+
# ax_p.grid(visible=True, which="major")
66+
# ax_p.grid(visible=True, which="minor", linestyle=":")
67+
# ax_p.legend(loc=1)
68+
69+
# fig.savefig("without-pp@2x.png", dpi=600)

docs/fig/with-pp@2x.png

186 KB
Loading

docs/fig/without-pp@2x.png

352 KB
Loading

0 commit comments

Comments
 (0)