1+ # Maxlotlib
2+
3+
14# Maxplotlib
25
36A 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
2126import numpy as np
2227from maxplotlib import Canvas
@@ -28,13 +33,124 @@ canvas, ax = Canvas.subplots()
2833ax.plot(x, y)
2934```
3035
36+ Figure 1
37+
38+ </div >
39+
3140Plot the figure with the default (matplotlib) backend:
3241
3342``` python
3443canvas.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
39155Render the same line graph directly in the terminal with the ` plotext `
40156backend:
@@ -44,20 +160,76 @@ terminal_fig = canvas.plot(backend="plotext")
44160print (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+
47186Or plot with the TikZ backend:
48187
49188``` python
50189canvas.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
57229The ` plotext ` backend is designed for terminal-first workflows. It
58230currently 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
61233multi-subplot canvases.
62234
63235``` python
@@ -75,17 +247,35 @@ ax.set_legend(True)
75247canvas.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
90280x = np.linspace(0 , 2 * np.pi, 200 )
91281
@@ -106,18 +296,28 @@ ax.set_xlabel("x")
106296ax.set_legend(True )
107297```
108298
299+ Figure 3
300+
301+ </div >
302+
109303Show layer 0 only, then layers 0 and 1, then everything:
110304
111305``` python
112306canvas.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
117314Show all layers:
118315
119316``` python
120317canvas.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