Skip to content

Commit fb8de5e

Browse files
committed
Added README.qmd
1 parent 206e15d commit fb8de5e

2 files changed

Lines changed: 449 additions & 10 deletions

File tree

README.md

Lines changed: 229 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,246 @@
11
# maxplotlib
22

3-
This is a wrapper for matplotlib so I can produce figures with consistent formatting. It also has some pretty nice additions such as using layers and exporting to tikz.
3+
4+
# maxplotlib
5+
6+
A clean, expressive wrapper around **Matplotlib** for producing
7+
publication-quality figures with minimal boilerplate. Swap backends
8+
without rewriting your data — render the same canvas as a crisp PNG, an
9+
interactive Plotly chart, or camera-ready **TikZ** code for LaTeX.
410

511
## Install
612

7-
Create and activate python environment
13+
``` bash
14+
python -m venv env && source env/bin/activate
15+
pip install maxplotlibx
16+
```
17+
18+
For development extras (tests, docs, linting):
819

20+
``` bash
21+
pip install "maxplotlibx[dev]"
922
```
10-
python -m venv env
11-
source env/bin/activate
12-
pip install --upgrade pip
23+
24+
## Showcase
25+
26+
``` python
27+
import numpy as np
28+
from maxplotlib import Canvas
29+
30+
rng = np.random.default_rng(0)
31+
x = np.linspace(0, 2 * np.pi, 300)
32+
33+
canvas, axes = Canvas.subplots(nrows=2, ncols=2, width="18cm", ratio=0.65)
34+
35+
# ── top-left: multi-line with legend ──────────────────────────────────────────
36+
ax = axes[0][0]
37+
ax.plot(x, np.sin(x), color="royalblue", linewidth=2, label=r"$\sin(x)$")
38+
ax.plot(x, np.cos(x), color="tomato", linewidth=2,
39+
linestyle="dashed", label=r"$\cos(x)$")
40+
ax.plot(x, np.sin(2 * x) * 0.5, color="seagreen", linewidth=1.5,
41+
linestyle="dotted", label=r"$\frac{1}{2}\sin(2x)$")
42+
ax.set_xlabel("x")
43+
ax.set_ylabel("amplitude")
44+
ax.set_title("Line plots")
45+
ax.set_legend(True)
46+
ax.set_grid(True)
47+
48+
# ── top-right: scatter coloured by distance ────────────────────────────────────
49+
ax = axes[0][1]
50+
n = 250
51+
sx = rng.standard_normal(n)
52+
sy = rng.standard_normal(n)
53+
ax.scatter(sx, sy, c=np.hypot(sx, sy), s=25, alpha=0.8)
54+
ax.set_xlabel("x")
55+
ax.set_ylabel("y")
56+
ax.set_title("Scatter — coloured by distance")
57+
ax.set_aspect("equal")
58+
59+
# ── bottom-left: bar chart ────────────────────────────────────────────────────
60+
ax = axes[1][0]
61+
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
62+
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
63+
temps = [3, 4, 8, 13, 18, 22, 24, 23, 18, 12, 7, 4]
64+
month_idx = np.arange(len(months))
65+
ax.bar(month_idx, temps, color="steelblue", width=0.7, label="avg °C")
66+
ax.set_xticks(month_idx, labels=months)
67+
ax.set_xlabel("month")
68+
ax.set_ylabel("temperature (°C)")
69+
ax.set_title("Bar chart")
70+
71+
# ── bottom-right: fill_between confidence band ────────────────────────────────
72+
ax = axes[1][1]
73+
mean = np.sin(x) * np.exp(-x / (2 * np.pi))
74+
std = 0.15 + 0.1 * np.abs(np.cos(x))
75+
ax.plot(x, mean, color="darkorchid", linewidth=2, label="mean")
76+
ax.fill_between(x, mean - std, mean + std, alpha=0.25, color="darkorchid",
77+
label="±1 σ")
78+
ax.set_xlabel("x")
79+
ax.set_ylabel("y")
80+
ax.set_title("Confidence band")
81+
ax.set_legend(True)
82+
ax.set_grid(True)
83+
84+
canvas.suptitle("maxplotlib — four plot types, one canvas")
85+
fig, _ = canvas.plot()
86+
fig
1387
```
1488

15-
Install the code and requirements with pip
89+
<div id="fig-showcase">
90+
91+
<div class="cell-output cell-output-display" execution_count="2">
92+
93+
<div id="fig-showcase-1">
94+
95+
<img src="README_files/figure-commonmark/fig-showcase-output-1.png"
96+
data-ref-parent="fig-showcase" />
97+
98+
(a) maxplotlib showcase — four plot types, one canvas.
99+
100+
</div>
101+
102+
</div>
103+
104+
<div class="cell-output cell-output-display">
105+
106+
<div id="fig-showcase-2">
107+
108+
<img src="README_files/figure-commonmark/fig-showcase-output-2.png"
109+
id="fig-showcase-2" data-ref-parent="fig-showcase" />
110+
111+
(b)
112+
113+
</div>
114+
115+
</div>
116+
117+
Figure 1
118+
119+
</div>
120+
121+
## Quick start
16122

123+
### One-liner with `Canvas.subplots()`
124+
125+
`Canvas.subplots()` mirrors `plt.subplots()` but returns a `Canvas` and
126+
subplot axes that speak the maxplotlib API.
127+
128+
``` python
129+
import numpy as np
130+
from maxplotlib import Canvas
131+
132+
x = np.linspace(0, 2 * np.pi, 200)
133+
134+
canvas, ax = Canvas.subplots(width="10cm", ratio=0.55)
135+
ax.plot(x, np.sin(x), color="royalblue", label=r"$\sin(x)$", linewidth=2)
136+
ax.plot(x, np.cos(x), color="tomato", label=r"$\cos(x)$", linewidth=2,
137+
linestyle="dashed")
138+
ax.set_xlabel("x")
139+
ax.set_ylabel("y")
140+
ax.set_legend(True)
141+
ax.set_grid(True)
142+
canvas.show()
143+
```
144+
145+
### Canvas-level shortcut API
146+
147+
For single-subplot figures every plot method is available directly on
148+
the `Canvas` object — no need to grab an axes handle:
149+
150+
``` python
151+
canvas = Canvas(ratio=0.5, fontsize=12)
152+
canvas.add_line(x, np.sin(x), label="sin", color="steelblue")
153+
canvas.add_line(x, np.cos(x), label="cos", color="darkorange", linestyle="dashed")
154+
canvas.set_xlabel("angle (rad)")
155+
canvas.set_ylabel("amplitude")
156+
canvas.set_legend(True)
157+
canvas.show()
158+
```
159+
160+
## Key features
161+
162+
### Multiple backends — same API
163+
164+
| Backend | How to use | Output |
165+
|----|----|----|
166+
| `matplotlib` (default) | `canvas.show()` | inline PNG / static file |
167+
| `plotly` | `fig = canvas.plot(backend='plotly')` | interactive HTML widget |
168+
| `tikzfigure` | `tz = canvas.plot(backend='tikzfigure')` | LaTeX `\draw` commands |
169+
170+
``` python
171+
# Render as interactive Plotly figure
172+
fig = canvas.plot(backend="plotly")
173+
fig.show()
174+
175+
# Export TikZ code for a LaTeX document
176+
tikz = canvas.plot(backend="tikzfigure")
177+
print(tikz.generate_tikz())
17178
```
18-
pip install -e .
179+
180+
### Layers
181+
182+
Tag each plot call with a `layer=` integer. Then render any subset —
183+
handy for step-by-step derivations, lecture slides, or overlays.
184+
185+
``` python
186+
canvas, ax = Canvas.subplots()
187+
ax.plot(x, np.sin(x), layer=0, label=r"$\sin(x)$", color="steelblue")
188+
ax.plot(x, np.cos(x), layer=1, label=r"$\cos(x)$", color="tomato")
189+
ax.plot(x, np.sin(x) * np.cos(x), layer=2,
190+
label=r"$\sin(x)\cos(x)$", color="seagreen", linestyle="dashed")
191+
192+
canvas.show(layers=[0]) # only sin
193+
canvas.show(layers=[0, 1]) # sin + cos
194+
canvas.show() # everything
19195
```
20196

21-
Additional dependencies for developers can be installed with
197+
### Size and typography
22198

199+
Pass physical dimensions and a font size; maxplotlib converts to the
200+
correct `figsize` automatically.
201+
202+
``` python
203+
canvas = Canvas(width="17cm", ratio=0.5, fontsize=11)
23204
```
24-
pip install -e ".[dev]"
205+
206+
`ratio` accepts a float **or** the string `"golden"` (default) for the
207+
golden ratio.
208+
209+
### Saving figures
210+
211+
``` python
212+
canvas.savefig("figure.pdf") # vector PDF
213+
canvas.savefig("figure.png") # raster PNG
214+
canvas.savefig("figure.svg") # SVG
25215
```
26216

27-
Some examples can be found in `tutorials/`
217+
## Plot types
218+
219+
| Method | Description |
220+
|-----------------------------------|--------------------------------|
221+
| `ax.plot(x, y)` | Line plot |
222+
| `ax.scatter(x, y)` | Scatter plot |
223+
| `ax.bar(categories, values)` | Bar chart |
224+
| `ax.fill_between(x, y1, y2)` | Shaded band |
225+
| `ax.errorbar(x, y, yerr)` | Error bars |
226+
| `ax.axhline(y)` / `ax.axvline(x)` | Reference lines |
227+
| `ax.annotate(text, xy)` | Annotation with optional arrow |
228+
229+
## Tutorials
230+
231+
Step-by-step Jupyter notebooks in `tutorials/`:
232+
233+
| Notebook | Topic |
234+
|----------------------|----------------------------------|
235+
| `tutorial_01` | Quick start |
236+
| `tutorial_02` | Multiple subplots |
237+
| `tutorial_03` | All plot types |
238+
| `tutorial_04` | Colours, linestyles, markers |
239+
| `tutorial_05` | Axes, ticks, scales, annotations |
240+
| `tutorial_06` | Layers |
241+
| `tutorial_07_tikz` | TikZ backend |
242+
| `tutorial_08_plotly` | Plotly backend |
243+
244+
## License
245+
246+
MIT — see [`LICENSE`](LICENSE).

0 commit comments

Comments
 (0)