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.
Files changed (45) hide show
  1. maxplotlibx-0.1.6/PKG-INFO +160 -0
  2. maxplotlibx-0.1.6/README.md +123 -0
  3. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/pyproject.toml +3 -2
  4. maxplotlibx-0.1.6/src/maxplotlib/__init__.py +3 -0
  5. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/backends/matplotlib/utils.py +5 -3
  6. maxplotlibx-0.1.6/src/maxplotlib/backends/plotext/__init__.py +3 -0
  7. maxplotlibx-0.1.6/src/maxplotlib/backends/plotext/figure.py +51 -0
  8. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/canvas/canvas.py +646 -72
  9. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/colors/colors.py +0 -1
  10. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/linestyle/linestyle.py +0 -1
  11. maxplotlibx-0.1.6/src/maxplotlib/subfigure/line_plot.py +2050 -0
  12. maxplotlibx-0.1.6/src/maxplotlib/tests/test_canvas.py +494 -0
  13. maxplotlibx-0.1.6/src/maxplotlib/tests/test_flame_chart.py +273 -0
  14. maxplotlibx-0.1.6/src/maxplotlib/tests/test_gantt_chart.py +274 -0
  15. maxplotlibx-0.1.6/src/maxplotlib/tests/test_plot.py +104 -0
  16. maxplotlibx-0.1.6/src/maxplotlib/tests/test_plotext.py +135 -0
  17. maxplotlibx-0.1.6/src/maxplotlib/tests/test_plotly_backend.py +86 -0
  18. maxplotlibx-0.1.6/src/maxplotlib/utils/options.py +3 -0
  19. maxplotlibx-0.1.6/src/maxplotlibx.egg-info/PKG-INFO +160 -0
  20. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlibx.egg-info/SOURCES.txt +6 -0
  21. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlibx.egg-info/requires.txt +2 -1
  22. maxplotlibx-0.1.4/PKG-INFO +0 -63
  23. maxplotlibx-0.1.4/README.md +0 -27
  24. maxplotlibx-0.1.4/src/maxplotlib/__init__.py +0 -3
  25. maxplotlibx-0.1.4/src/maxplotlib/subfigure/line_plot.py +0 -659
  26. maxplotlibx-0.1.4/src/maxplotlib/tests/test_canvas.py +0 -6
  27. maxplotlibx-0.1.4/src/maxplotlib/tests/test_plot.py +0 -0
  28. maxplotlibx-0.1.4/src/maxplotlib/utils/options.py +0 -3
  29. maxplotlibx-0.1.4/src/maxplotlibx.egg-info/PKG-INFO +0 -63
  30. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/LICENSE +0 -0
  31. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/setup.cfg +0 -0
  32. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/backends/plotly/__init__.py +0 -0
  33. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/backends/plotly/utils.py +0 -0
  34. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/canvas/__init__.py +0 -0
  35. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/colors/__init__.py +0 -0
  36. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/linestyle/__init__.py +0 -0
  37. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/objects/__init__.py +0 -0
  38. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/objects/node.py +0 -0
  39. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/objects/path.py +0 -0
  40. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/subfigure/__init__.py +0 -0
  41. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/subfigure/subfigure.py +0 -0
  42. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/tests/test_imports.py +0 -0
  43. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlib/utils/__init__.py +0 -0
  44. {maxplotlibx-0.1.4 → maxplotlibx-0.1.6}/src/maxplotlibx.egg-info/dependency_links.txt +0 -0
  45. {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
+ ![](README_files/figure-markdown_strict/cell-3-output-1.png)
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
+ ![](README_files/figure-markdown_strict/cell-4-output-1.png)
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
+ ![](README_files/figure-markdown_strict/cell-6-output-1.png)
153
+
154
+ Show all layers:
155
+
156
+ ``` python
157
+ canvas.show()
158
+ ```
159
+
160
+ ![](README_files/figure-markdown_strict/cell-7-output-1.png)
@@ -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
+ ![](README_files/figure-markdown_strict/cell-3-output-1.png)
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
+ ![](README_files/figure-markdown_strict/cell-4-output-1.png)
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
+ ![](README_files/figure-markdown_strict/cell-6-output-1.png)
116
+
117
+ Show all layers:
118
+
119
+ ``` python
120
+ canvas.show()
121
+ ```
122
+
123
+ ![](README_files/figure-markdown_strict/cell-7-output-1.png)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "maxplotlibx"
7
- version = "0.1.4"
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
- "tikzfigure[vis]>=0.2.0",
21
+ "plotext",
22
+ "tikzfigure[vis]>=0.3.0",
22
23
  ]
23
24
  [project.optional-dependencies]
24
25
  test = [
@@ -0,0 +1,3 @@
1
+ from maxplotlib.canvas.canvas import Canvas, SubplotSpacing
2
+
3
+ __all__ = ["Canvas", "SubplotSpacing"]
@@ -6,7 +6,7 @@ import matplotlib.pyplot as plt
6
6
  import pint
7
7
 
8
8
 
9
- def setup_tex_fonts(fontsize=14, usetex=False):
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 with dpi={dpi}")
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 * dpi
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,3 @@
1
+ from maxplotlib.backends.plotext.figure import PlotextFigure, create_plotext_figure
2
+
3
+ __all__ = ["PlotextFigure", "create_plotext_figure"]
@@ -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)