maxplotlibx 0.1.4__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maxplotlibx-0.1.6/PKG-INFO +160 -0
- maxplotlibx-0.1.6/README.md +123 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/pyproject.toml +3 -2
- maxplotlibx-0.1.6/src/maxplotlib/__init__.py +3 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/backends/matplotlib/utils.py +5 -3
- maxplotlibx-0.1.6/src/maxplotlib/backends/plotext/__init__.py +3 -0
- maxplotlibx-0.1.6/src/maxplotlib/backends/plotext/figure.py +51 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/canvas/canvas.py +646 -72
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/colors/colors.py +0 -1
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/linestyle/linestyle.py +0 -1
- maxplotlibx-0.1.6/src/maxplotlib/subfigure/line_plot.py +2050 -0
- maxplotlibx-0.1.6/src/maxplotlib/tests/test_canvas.py +494 -0
- maxplotlibx-0.1.6/src/maxplotlib/tests/test_flame_chart.py +273 -0
- maxplotlibx-0.1.6/src/maxplotlib/tests/test_gantt_chart.py +274 -0
- maxplotlibx-0.1.6/src/maxplotlib/tests/test_plot.py +104 -0
- maxplotlibx-0.1.6/src/maxplotlib/tests/test_plotext.py +135 -0
- maxplotlibx-0.1.6/src/maxplotlib/tests/test_plotly_backend.py +86 -0
- maxplotlibx-0.1.6/src/maxplotlib/utils/options.py +3 -0
- maxplotlibx-0.1.6/src/maxplotlibx.egg-info/PKG-INFO +160 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlibx.egg-info/SOURCES.txt +6 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlibx.egg-info/requires.txt +2 -1
- maxplotlibx-0.1.4/PKG-INFO +0 -63
- maxplotlibx-0.1.4/README.md +0 -27
- maxplotlibx-0.1.4/src/maxplotlib/__init__.py +0 -3
- maxplotlibx-0.1.4/src/maxplotlib/subfigure/line_plot.py +0 -659
- maxplotlibx-0.1.4/src/maxplotlib/tests/test_canvas.py +0 -6
- maxplotlibx-0.1.4/src/maxplotlib/tests/test_plot.py +0 -0
- maxplotlibx-0.1.4/src/maxplotlib/utils/options.py +0 -3
- maxplotlibx-0.1.4/src/maxplotlibx.egg-info/PKG-INFO +0 -63
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/LICENSE +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/setup.cfg +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/backends/plotly/__init__.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/backends/plotly/utils.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/canvas/__init__.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/colors/__init__.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/linestyle/__init__.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/objects/__init__.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/objects/node.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/objects/path.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/subfigure/__init__.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/subfigure/subfigure.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/tests/test_imports.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/utils/__init__.py +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlibx.egg-info/dependency_links.txt +0 -0
- {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlibx.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: maxplotlibx
|
|
3
|
+
Version: 0.1.6
|
|
4
|
+
Summary: A reproducible plotting module with various backends and export options.
|
|
5
|
+
Author: Max
|
|
6
|
+
Project-URL: Source, https://github.com/max-models/maxplotlib
|
|
7
|
+
Keywords: matplotlib
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: matplotlib
|
|
13
|
+
Requires-Dist: pint
|
|
14
|
+
Requires-Dist: plotly
|
|
15
|
+
Requires-Dist: plotext
|
|
16
|
+
Requires-Dist: tikzfigure[vis]>=0.3.0
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest; extra == "test"
|
|
19
|
+
Requires-Dist: coverage; extra == "test"
|
|
20
|
+
Provides-Extra: docs
|
|
21
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
22
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
23
|
+
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
|
24
|
+
Requires-Dist: nbsphinx; extra == "docs"
|
|
25
|
+
Requires-Dist: ipykernel; extra == "docs"
|
|
26
|
+
Requires-Dist: nbconvert; extra == "docs"
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: maxplotlibx[docs,test]; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff; extra == "dev"
|
|
30
|
+
Requires-Dist: black[jupyter]; extra == "dev"
|
|
31
|
+
Requires-Dist: isort; extra == "dev"
|
|
32
|
+
Requires-Dist: jupyterlab; extra == "dev"
|
|
33
|
+
Requires-Dist: nbstripout; extra == "dev"
|
|
34
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
35
|
+
Requires-Dist: pyproject-fmt; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# Maxplotlib
|
|
39
|
+
|
|
40
|
+
A clean, expressive wrapper around **Matplotlib**, **Plotly**,
|
|
41
|
+
**plotext**, and **tikzfigure** for producing publication-quality
|
|
42
|
+
figures with minimal boilerplate. Swap backends without rewriting your
|
|
43
|
+
data — render the same canvas as a crisp PNG, an interactive Plotly
|
|
44
|
+
chart, a terminal-native plotext figure, or camera-ready **TikZ** code
|
|
45
|
+
for LaTeX.
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
``` bash
|
|
50
|
+
pip install maxplotlibx
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Showcase
|
|
54
|
+
|
|
55
|
+
### Quickstart
|
|
56
|
+
|
|
57
|
+
``` python
|
|
58
|
+
import numpy as np
|
|
59
|
+
from maxplotlib import Canvas
|
|
60
|
+
|
|
61
|
+
x = np.linspace(0, 2 * np.pi, 200)
|
|
62
|
+
y = np.sin(x)
|
|
63
|
+
|
|
64
|
+
canvas, ax = Canvas.subplots()
|
|
65
|
+
ax.plot(x, y)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Plot the figure with the default (matplotlib) backend:
|
|
69
|
+
|
|
70
|
+
``` python
|
|
71
|
+
canvas.show()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
Render the same line graph directly in the terminal with the `plotext`
|
|
77
|
+
backend:
|
|
78
|
+
|
|
79
|
+
``` python
|
|
80
|
+
terminal_fig = canvas.plot(backend="plotext")
|
|
81
|
+
print(terminal_fig.build(keep_colors=False))
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or plot with the TikZ backend:
|
|
85
|
+
|
|
86
|
+
``` python
|
|
87
|
+
canvas.show(backend="tikzfigure")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+

|
|
91
|
+
|
|
92
|
+
### Terminal backend
|
|
93
|
+
|
|
94
|
+
The `plotext` backend is designed for terminal-first workflows. It
|
|
95
|
+
currently supports line plots, scatter plots, bars, filled regions,
|
|
96
|
+
error bars, reference lines, text/annotations, labels/titles, log
|
|
97
|
+
axes, layers, matrix-style `imshow()` rendering, common patches, and
|
|
98
|
+
multi-subplot canvases.
|
|
99
|
+
|
|
100
|
+
``` python
|
|
101
|
+
x = np.linspace(1, 10, 40)
|
|
102
|
+
|
|
103
|
+
canvas, ax = Canvas.subplots()
|
|
104
|
+
ax.plot(x, np.sqrt(x), color="cyan", label="sqrt(x)")
|
|
105
|
+
ax.errorbar(x[::8], np.sqrt(x[::8]), yerr=0.15, color="yellow", label="samples")
|
|
106
|
+
ax.set_title("Terminal plot")
|
|
107
|
+
ax.set_xlabel("x")
|
|
108
|
+
ax.set_ylabel("y")
|
|
109
|
+
ax.set_xscale("log")
|
|
110
|
+
ax.set_legend(True)
|
|
111
|
+
|
|
112
|
+
canvas.show(backend="plotext")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Examples
|
|
116
|
+
|
|
117
|
+
Runnable example scripts live in `examples/`:
|
|
118
|
+
|
|
119
|
+
``` bash
|
|
120
|
+
python examples/plotly_backend_basic.py
|
|
121
|
+
python examples/plotly_backend_parity.py
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Layers
|
|
125
|
+
|
|
126
|
+
``` python
|
|
127
|
+
x = np.linspace(0, 2 * np.pi, 200)
|
|
128
|
+
|
|
129
|
+
canvas, ax = Canvas.subplots(width="10cm", ratio=0.55)
|
|
130
|
+
|
|
131
|
+
ax.plot(x, np.sin(x), color="steelblue", label=r"$\sin(x)$", layer=0)
|
|
132
|
+
ax.plot(x, np.cos(x), color="tomato", label=r"$\cos(x)$", layer=1)
|
|
133
|
+
ax.plot(
|
|
134
|
+
x,
|
|
135
|
+
np.sin(x) * np.cos(x),
|
|
136
|
+
color="seagreen",
|
|
137
|
+
label=r"$\sin(x)\cos(x)$",
|
|
138
|
+
linestyle="dashed",
|
|
139
|
+
layer=2,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
ax.set_xlabel("x")
|
|
143
|
+
ax.set_legend(True)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Show layer 0 only, then layers 0 and 1, then everything:
|
|
147
|
+
|
|
148
|
+
``` python
|
|
149
|
+
canvas.show(layers=[0])
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+

|
|
153
|
+
|
|
154
|
+
Show all layers:
|
|
155
|
+
|
|
156
|
+
``` python
|
|
157
|
+
canvas.show()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+

|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Maxplotlib
|
|
2
|
+
|
|
3
|
+
A clean, expressive wrapper around **Matplotlib**, **Plotly**,
|
|
4
|
+
**plotext**, and **tikzfigure** for producing publication-quality
|
|
5
|
+
figures with minimal boilerplate. Swap backends without rewriting your
|
|
6
|
+
data — render the same canvas as a crisp PNG, an interactive Plotly
|
|
7
|
+
chart, a terminal-native plotext figure, or camera-ready **TikZ** code
|
|
8
|
+
for LaTeX.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
``` bash
|
|
13
|
+
pip install maxplotlibx
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Showcase
|
|
17
|
+
|
|
18
|
+
### Quickstart
|
|
19
|
+
|
|
20
|
+
``` python
|
|
21
|
+
import numpy as np
|
|
22
|
+
from maxplotlib import Canvas
|
|
23
|
+
|
|
24
|
+
x = np.linspace(0, 2 * np.pi, 200)
|
|
25
|
+
y = np.sin(x)
|
|
26
|
+
|
|
27
|
+
canvas, ax = Canvas.subplots()
|
|
28
|
+
ax.plot(x, y)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Plot the figure with the default (matplotlib) backend:
|
|
32
|
+
|
|
33
|
+
``` python
|
|
34
|
+
canvas.show()
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
Render the same line graph directly in the terminal with the `plotext`
|
|
40
|
+
backend:
|
|
41
|
+
|
|
42
|
+
``` python
|
|
43
|
+
terminal_fig = canvas.plot(backend="plotext")
|
|
44
|
+
print(terminal_fig.build(keep_colors=False))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or plot with the TikZ backend:
|
|
48
|
+
|
|
49
|
+
``` python
|
|
50
|
+
canvas.show(backend="tikzfigure")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
### Terminal backend
|
|
56
|
+
|
|
57
|
+
The `plotext` backend is designed for terminal-first workflows. It
|
|
58
|
+
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
|
|
61
|
+
multi-subplot canvases.
|
|
62
|
+
|
|
63
|
+
``` python
|
|
64
|
+
x = np.linspace(1, 10, 40)
|
|
65
|
+
|
|
66
|
+
canvas, ax = Canvas.subplots()
|
|
67
|
+
ax.plot(x, np.sqrt(x), color="cyan", label="sqrt(x)")
|
|
68
|
+
ax.errorbar(x[::8], np.sqrt(x[::8]), yerr=0.15, color="yellow", label="samples")
|
|
69
|
+
ax.set_title("Terminal plot")
|
|
70
|
+
ax.set_xlabel("x")
|
|
71
|
+
ax.set_ylabel("y")
|
|
72
|
+
ax.set_xscale("log")
|
|
73
|
+
ax.set_legend(True)
|
|
74
|
+
|
|
75
|
+
canvas.show(backend="plotext")
|
|
76
|
+
```
|
|
77
|
+
|
|
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
|
+
```
|
|
86
|
+
|
|
87
|
+
### Layers
|
|
88
|
+
|
|
89
|
+
``` python
|
|
90
|
+
x = np.linspace(0, 2 * np.pi, 200)
|
|
91
|
+
|
|
92
|
+
canvas, ax = Canvas.subplots(width="10cm", ratio=0.55)
|
|
93
|
+
|
|
94
|
+
ax.plot(x, np.sin(x), color="steelblue", label=r"$\sin(x)$", layer=0)
|
|
95
|
+
ax.plot(x, np.cos(x), color="tomato", label=r"$\cos(x)$", layer=1)
|
|
96
|
+
ax.plot(
|
|
97
|
+
x,
|
|
98
|
+
np.sin(x) * np.cos(x),
|
|
99
|
+
color="seagreen",
|
|
100
|
+
label=r"$\sin(x)\cos(x)$",
|
|
101
|
+
linestyle="dashed",
|
|
102
|
+
layer=2,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
ax.set_xlabel("x")
|
|
106
|
+
ax.set_legend(True)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Show layer 0 only, then layers 0 and 1, then everything:
|
|
110
|
+
|
|
111
|
+
``` python
|
|
112
|
+
canvas.show(layers=[0])
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+

|
|
116
|
+
|
|
117
|
+
Show all layers:
|
|
118
|
+
|
|
119
|
+
``` python
|
|
120
|
+
canvas.show()
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+

|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "maxplotlibx"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.6"
|
|
8
8
|
description = "A reproducible plotting module with various backends and export options."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -18,7 +18,8 @@ dependencies = [
|
|
|
18
18
|
"matplotlib",
|
|
19
19
|
"pint",
|
|
20
20
|
"plotly",
|
|
21
|
-
"
|
|
21
|
+
"plotext",
|
|
22
|
+
"tikzfigure[vis]>=0.3.0",
|
|
22
23
|
]
|
|
23
24
|
[project.optional-dependencies]
|
|
24
25
|
test = [
|
|
@@ -6,7 +6,7 @@ import matplotlib.pyplot as plt
|
|
|
6
6
|
import pint
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def setup_tex_fonts(fontsize=
|
|
9
|
+
def setup_tex_fonts(fontsize=10, usetex=False):
|
|
10
10
|
"""
|
|
11
11
|
Sets up LaTeX fonts for plotting.
|
|
12
12
|
"""
|
|
@@ -15,6 +15,8 @@ def setup_tex_fonts(fontsize=14, usetex=False):
|
|
|
15
15
|
"font.family": "serif",
|
|
16
16
|
"pgf.rcfonts": False,
|
|
17
17
|
"axes.labelsize": fontsize,
|
|
18
|
+
"axes.titlesize": fontsize,
|
|
19
|
+
"figure.titlesize": fontsize,
|
|
18
20
|
"font.size": fontsize,
|
|
19
21
|
"legend.fontsize": fontsize,
|
|
20
22
|
"xtick.labelsize": fontsize,
|
|
@@ -58,13 +60,13 @@ def convert_to_inches(length_str):
|
|
|
58
60
|
|
|
59
61
|
def _2pt(width, dpi=300, verbose: bool = False):
|
|
60
62
|
if verbose:
|
|
61
|
-
print(f"Converting width: {width} to points
|
|
63
|
+
print(f"Converting width: {width} to points")
|
|
62
64
|
|
|
63
65
|
if isinstance(width, (int, float)):
|
|
64
66
|
return width
|
|
65
67
|
elif isinstance(width, str):
|
|
66
68
|
length_in = convert_to_inches(width)
|
|
67
|
-
length_pt = length_in *
|
|
69
|
+
length_pt = length_in * 72.27
|
|
68
70
|
if verbose:
|
|
69
71
|
print(f"Converted length: {length_in} inches = {length_pt} points")
|
|
70
72
|
return length_pt
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from plotext._figure import _figure_class
|
|
7
|
+
|
|
8
|
+
_ANSI_ESCAPE_RE = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def strip_ansi(text: str) -> str:
|
|
12
|
+
return _ANSI_ESCAPE_RE.sub("", text)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_plotext_figure(nrows: int = 1, ncols: int = 1) -> _figure_class:
|
|
16
|
+
figure = _figure_class()
|
|
17
|
+
if nrows > 1 or ncols > 1:
|
|
18
|
+
figure.subplots(nrows, ncols)
|
|
19
|
+
return figure
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PlotextFigure:
|
|
23
|
+
def __init__(self, figure: _figure_class, suptitle: str | None = None):
|
|
24
|
+
self.figure = figure
|
|
25
|
+
self.suptitle = suptitle
|
|
26
|
+
|
|
27
|
+
def build(self, keep_colors: bool = True) -> str:
|
|
28
|
+
output = self.figure.build()
|
|
29
|
+
if self.suptitle:
|
|
30
|
+
output = f"{self.suptitle}\n{output}"
|
|
31
|
+
return output if keep_colors else strip_ansi(output)
|
|
32
|
+
|
|
33
|
+
def show(self) -> str:
|
|
34
|
+
output = self.build()
|
|
35
|
+
print(output)
|
|
36
|
+
return output
|
|
37
|
+
|
|
38
|
+
def savefig(self, path, append: bool = False, keep_colors: bool = False) -> None:
|
|
39
|
+
destination = Path(path)
|
|
40
|
+
mode = "a" if append else "w"
|
|
41
|
+
with destination.open(mode, encoding="utf-8") as handle:
|
|
42
|
+
handle.write(self.build(keep_colors=keep_colors))
|
|
43
|
+
handle.write("\n")
|
|
44
|
+
|
|
45
|
+
save_fig = savefig
|
|
46
|
+
|
|
47
|
+
def __getattr__(self, name):
|
|
48
|
+
return getattr(self.figure, name)
|
|
49
|
+
|
|
50
|
+
def __str__(self) -> str:
|
|
51
|
+
return self.build(keep_colors=False)
|