Skip to content

Commit bbcde8a

Browse files
authored
Merge pull request #56 from max-models/show-plot-in-jupyter
Show plot in jupyter
2 parents 35102c0 + cb55dd9 commit bbcde8a

29 files changed

Lines changed: 3992 additions & 56 deletions

‎README.md‎

Lines changed: 215 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Maxlotlib
2+
3+
14
# Maxplotlib
25

36
A clean, expressive wrapper around **Matplotlib**, **Plotly**,
@@ -17,6 +20,8 @@ pip install maxplotlibx
1720

1821
### Quickstart
1922

23+
<div id="fig-showcase-1">
24+
2025
``` python
2126
import numpy as np
2227
from maxplotlib import Canvas
@@ -28,13 +33,124 @@ canvas, ax = Canvas.subplots()
2833
ax.plot(x, y)
2934
```
3035

36+
Figure 1
37+
38+
</div>
39+
3140
Plot the figure with the default (matplotlib) backend:
3241

3342
``` python
3443
canvas.show()
3544
```
3645

37-
![](README_files/figure-markdown_strict/cell-3-output-1.png)
46+
![](README_files/figure-commonmark/cell-3-output-1.png)
47+
48+
For Matplotlib-specific customization, pass method calls declaratively.
49+
Figure methods run once and axes methods run for every subplot,
50+
providing access to any Matplotlib API without requiring a maxplotlib
51+
wrapper:
52+
53+
``` python
54+
canvas.plot(matplotlib_customizations={
55+
"figure": {
56+
"suptitle": "My figure",
57+
},
58+
"axes": {
59+
"tick_params": {
60+
"axis": "both",
61+
"which": "major",
62+
"length": 6,
63+
},
64+
},
65+
})
66+
```
67+
68+
For dynamic customization, the same option also accepts a function:
69+
70+
``` python
71+
def customize(fig, axes):
72+
fig.suptitle("My figure")
73+
for ax in axes.flat:
74+
ax.tick_params(axis="both", which="major", length=6)
75+
76+
canvas.plot(matplotlib_customizations=customize)
77+
```
78+
79+
### Axis Label and Tick Styling
80+
81+
Axis labels, titles, and tick appearance accept Matplotlib-style keyword
82+
arguments:
83+
84+
``` python
85+
canvas.set_xlabel("Time", fontsize=12, fontweight="bold", labelpad=10)
86+
canvas.set_ylabel("Duration", color="darkblue")
87+
canvas.set_title("Runtime", fontsize=14, color="navy")
88+
canvas.tick_params(
89+
axis="both",
90+
which="major",
91+
labelsize=10,
92+
colors="darkgreen",
93+
length=6,
94+
)
95+
```
96+
97+
Common axis controls and figure-level layout settings are also
98+
available:
99+
100+
``` python
101+
canvas.set_facecolor("whitesmoke")
102+
canvas.set_axisbelow(True)
103+
canvas.margins(x=0.05, y=0.1)
104+
canvas.minorticks_on()
105+
canvas.invert_yaxis()
106+
canvas.supxlabel("Shared x label")
107+
canvas.supylabel("Shared y label")
108+
canvas.subplots_adjust(left=0.15, bottom=0.15)
109+
canvas.tight_layout()
110+
```
111+
112+
### Secondary Y-Axis
113+
114+
Use `Canvas.twinx()` to add a second y-axis that shares the primary
115+
x-axis:
116+
117+
``` python
118+
twin_canvas, primary = Canvas.subplots()
119+
secondary = twin_canvas.twinx()
120+
121+
primary.plot(x, np.sin(x), color="tab:blue")
122+
secondary.plot(x, 100 * np.cos(x), color="tab:red")
123+
primary.set_ylabel("sin(x)", color="tab:blue")
124+
secondary.set_ylabel("100 cos(x)", color="tab:red")
125+
126+
twin_canvas.show()
127+
```
128+
129+
Secondary y-axes are currently supported by the Matplotlib and Plotly
130+
backends.
131+
132+
### Plotly field plots and tables
133+
134+
Several Matplotlib field and annotation APIs map directly to interactive
135+
Plotly traces, including pseudocolor plots, sparsity patterns,
136+
triangular grids, and tables:
137+
138+
``` python
139+
plotly_canvas, plotly_ax = Canvas.subplots()
140+
plotly_ax.pcolor(x, x, np.outer(np.sin(x), np.cos(x)))
141+
plotly_ax.spy([[1, 0, 1], [0, 1, 0], [1, 0, 1]])
142+
plotly_ax.table(cellText=[["A", "B"], ["1", "2"]])
143+
plotly_canvas.show(backend="plotly")
144+
```
145+
146+
Plotly raises `NotImplementedError` for primitives without a faithful
147+
equivalent instead of silently dropping them. To render the supported
148+
parts of a mixed canvas, explicitly opt into skipping unsupported
149+
primitives:
150+
151+
``` python
152+
plotly_canvas.plot(backend="plotly", allow_unsupported=True)
153+
```
38154

39155
Render the same line graph directly in the terminal with the `plotext`
40156
backend:
@@ -44,20 +160,76 @@ terminal_fig = canvas.plot(backend="plotext")
44160
print(terminal_fig.build(keep_colors=False))
45161
```
46162

163+
Runtime
164+
┌─────────────────────────────────────────────────────────────────────────┐
165+
1.00┤ ▗▄▞▀▀▀▀▀▙▄▖ │
166+
│ ▗▄▀▘ ▝▀▄ │
167+
│ ▗▞▘ ▀▄ │
168+
0.67┤ ▟▀ ▀▄ │
169+
│ ▄▛ ▚▖ │
170+
0.33┤ ▗▞ ▝▄ │
171+
│ ▄▀ ▚▖ │
172+
│▗▞▘ ▀▄ │
173+
0.00┤▀ ▝▚▖ ▞│
174+
│ ▀▄ ▗▞▘│
175+
│ ▝▚ ▄▀ │
176+
-0.33┤ ▀▖ ▞▘ │
177+
│ ▝▚ ▟▀ │
178+
-0.67┤ ▀▄ ▄▛ │
179+
│ ▀▄ ▗▞▘ │
180+
│ ▀▄▖ ▗▄▀▘ │
181+
-1.00┤ ▝▀▜▄▄▄▄▄▞▀▘ │
182+
└┬─────────────────┬─────────────────┬─────────────────┬─────────────────┬┘
183+
0.0 1.6 3.1 4.7 6.3
184+
Duration Time
185+
47186
Or plot with the TikZ backend:
48187

49188
``` python
50189
canvas.show(backend="tikzfigure")
51190
```
52191

53-
![](README_files/figure-markdown_strict/cell-4-output-1.png)
192+
![](README_files/figure-commonmark/cell-12-output-1.png)
193+
194+
### Horizontal Subplots with TikZ Backend
195+
196+
The tikzfigure backend supports creating side-by-side subplots (1×n
197+
layouts):
198+
199+
``` python
200+
x = np.linspace(0, 2 * np.pi, 200)
201+
canvas, (ax1, ax2) = Canvas.subplots(ncols=2, width="10cm", ratio=0.3)
202+
203+
ax1.plot(x, np.sin(x), color="royalblue")
204+
ax1.set_title("sin(x)")
205+
206+
ax2.plot(x, np.cos(x), color="tomato")
207+
ax2.set_title("cos(x)")
208+
209+
canvas.suptitle("Trigonometric Functions")
210+
canvas.show(backend="tikzfigure") # Generates LaTeX subfigures
211+
```
212+
213+
<div id="fig-showcase-subplots">
214+
215+
<img
216+
src="README_files/figure-commonmark/fig-showcase-subplots-output-1.png"
217+
id="fig-showcase-subplots" />
54218

55-
### Terminal backend
219+
Figure 2
220+
221+
</div>
222+
223+
**Note:** Only horizontal layouts (1×n) are currently supported with the
224+
tikzfigure backend. Vertical/grid layouts will raise
225+
`NotImplementedError`. See the tutorials for more examples.
226+
227+
### Terminal Backend with plotext
56228

57229
The `plotext` backend is designed for terminal-first workflows. It
58230
currently supports line plots, scatter plots, bars, filled regions,
59-
error bars, reference lines, text/annotations, labels/titles, log
60-
axes, layers, matrix-style `imshow()` rendering, common patches, and
231+
error bars, reference lines, text/annotations, labels/titles, log axes,
232+
layers, matrix-style `imshow()` rendering, common patches, and
61233
multi-subplot canvases.
62234

63235
``` python
@@ -75,17 +247,35 @@ ax.set_legend(True)
75247
canvas.show(backend="plotext")
76248
```
77249

78-
## Examples
79-
80-
Runnable example scripts live in `examples/`:
81-
82-
``` bash
83-
python examples/plotly_backend_basic.py
84-
python examples/plotly_backend_parity.py
85-
```
250+
Terminal plot
251+
┌──────────────────────────────────────────────────────────────────────────┐
252+
3.16┤ ▞▞ sqrt(x) ▄▞│
253+
│ │▗▄▞▀ │
254+
│ ▄┼▘ │
255+
2.79┤ ▄▀▀ │
256+
│ ┼▀▀ │
257+
2.42┤ ▗▞▀▀│ │
258+
│ ▗▞▀▀▘ │
259+
│ ▗▄┼▄▀▘ │
260+
2.04┤ ▗▄▀▘ │ │
261+
│ ▗▄▞▀▘ │
262+
│ │ ▄▄▀▀▘ │
263+
1.67┤ ▗▄▄┼▀▀ │
264+
│ ▗▄▄▞▀▀▘ │
265+
1.30┤ ▄▄▄▄▀▀▀▘ │
266+
│ ▄▄▞▀▀ │
267+
│┼ ▗▄▄▞▀▀▀▀▀ │
268+
0.93┤│▀▀▘ │
269+
└┬─────────────────┬──────────────────┬─────────────────┬─────────────────┬┘
270+
1.0 1.8 3.2 5.6 10.0
271+
y x
272+
273+
<maxplotlib.backends.plotext.figure.PlotextFigure at 0x110a30550>
86274

87275
### Layers
88276

277+
<div id="fig-showcase-2">
278+
89279
``` python
90280
x = np.linspace(0, 2 * np.pi, 200)
91281

@@ -106,18 +296,28 @@ ax.set_xlabel("x")
106296
ax.set_legend(True)
107297
```
108298

299+
Figure 3
300+
301+
</div>
302+
109303
Show layer 0 only, then layers 0 and 1, then everything:
110304

111305
``` python
112306
canvas.show(layers=[0])
113307
```
114308

115-
![](README_files/figure-markdown_strict/cell-6-output-1.png)
309+
![](README_files/figure-commonmark/cell-16-output-1.png)
310+
311+
(<Figure size 590.551x324.803 with 1 Axes>,
312+
array([[<Axes: xlabel='x'>]], dtype=object))
116313

117314
Show all layers:
118315

119316
``` python
120317
canvas.show()
121318
```
122319

123-
![](README_files/figure-markdown_strict/cell-7-output-1.png)
320+
![](README_files/figure-commonmark/cell-17-output-1.png)
321+
322+
(<Figure size 590.551x324.803 with 1 Axes>,
323+
array([[<Axes: xlabel='x'>]], dtype=object))

0 commit comments

Comments
 (0)