maxplotlibx 0.1.1__tar.gz → 0.1.2__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.1 → maxplotlibx-0.1.2}/PKG-INFO +2 -1
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/pyproject.toml +2 -1
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/backends/matplotlib/utils.py +0 -10
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/canvas/canvas.py +177 -86
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/colors/colors.py +0 -1
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/subfigure/line_plot.py +16 -65
- maxplotlibx-0.1.2/src/maxplotlib/tests/test_canvas.py +6 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/tests/test_imports.py +1 -2
- maxplotlibx-0.1.2/src/maxplotlib/utils/options.py +3 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlibx.egg-info/PKG-INFO +2 -1
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlibx.egg-info/SOURCES.txt +0 -3
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlibx.egg-info/requires.txt +1 -0
- maxplotlibx-0.1.1/src/maxplotlib/backends/matplotlib/utils_old.py +0 -852
- maxplotlibx-0.1.1/src/maxplotlib/objects/layer.py +0 -20
- maxplotlibx-0.1.1/src/maxplotlib/subfigure/tikz_figure.py +0 -497
- maxplotlibx-0.1.1/src/maxplotlib/tests/test_canvas.py +0 -7
- maxplotlibx-0.1.1/src/maxplotlib/utils/options.py +0 -3
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/LICENSE +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/README.md +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/setup.cfg +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/backends/plotly/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/backends/plotly/utils.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/canvas/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/colors/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/linestyle/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/linestyle/linestyle.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/objects/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/objects/node.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/objects/path.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/subfigure/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/subfigure/subfigure.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/tests/test_plot.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlib/utils/__init__.py +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlibx.egg-info/dependency_links.txt +0 -0
- {maxplotlibx-0.1.1 → maxplotlibx-0.1.2}/src/maxplotlibx.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maxplotlibx
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A reproducible plotting module with various backends and export options.
|
|
5
5
|
Author: Max
|
|
6
6
|
Project-URL: Source, https://github.com/max-models/maxplotlib
|
|
@@ -12,6 +12,7 @@ License-File: LICENSE
|
|
|
12
12
|
Requires-Dist: matplotlib
|
|
13
13
|
Requires-Dist: pint
|
|
14
14
|
Requires-Dist: plotly
|
|
15
|
+
Requires-Dist: tikzpics>=0.1.1
|
|
15
16
|
Provides-Extra: test
|
|
16
17
|
Requires-Dist: pytest; extra == "test"
|
|
17
18
|
Requires-Dist: coverage; extra == "test"
|
|
@@ -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.2"
|
|
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,6 +18,7 @@ dependencies = [
|
|
|
18
18
|
"matplotlib",
|
|
19
19
|
"pint",
|
|
20
20
|
"plotly",
|
|
21
|
+
"tikzpics>=0.1.1",
|
|
21
22
|
]
|
|
22
23
|
[project.optional-dependencies]
|
|
23
24
|
test = [
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
# import sys; from os.path import dirname; sys.path.append(f'{dirname(__file__)}/../../')
|
|
2
2
|
|
|
3
3
|
# import matplotlib.pylab as pylab
|
|
4
|
-
import math
|
|
5
|
-
import pickle
|
|
6
|
-
from pathlib import Path
|
|
7
4
|
|
|
8
|
-
import _pickle as cPickle
|
|
9
|
-
import matplotlib.colors as mcolors
|
|
10
5
|
import matplotlib.pyplot as plt
|
|
11
|
-
import numpy as np
|
|
12
6
|
import pint
|
|
13
|
-
from matplotlib.collections import PatchCollection
|
|
14
|
-
from mpl_toolkits.mplot3d import Axes3D
|
|
15
|
-
from mpl_toolkits.mplot3d.art3d import Line3DCollection, Poly3DCollection
|
|
16
7
|
|
|
17
8
|
|
|
18
9
|
def setup_tex_fonts(fontsize=14, usetex=False):
|
|
@@ -71,7 +62,6 @@ def _2pt(width, dpi=300):
|
|
|
71
62
|
elif isinstance(width, str):
|
|
72
63
|
length_in = convert_to_inches(width)
|
|
73
64
|
length_pt = length_in * dpi
|
|
74
|
-
# print(f"{length_in = } {length_pt = }")
|
|
75
65
|
return length_pt
|
|
76
66
|
else:
|
|
77
67
|
raise NotImplementedError
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import re
|
|
2
3
|
from typing import Dict
|
|
3
4
|
|
|
5
|
+
import matplotlib.patches as patches
|
|
4
6
|
import matplotlib.pyplot as plt
|
|
5
|
-
import plotly.graph_objects as go
|
|
6
7
|
from plotly.subplots import make_subplots
|
|
8
|
+
from tikzpics import TikzFigure
|
|
7
9
|
|
|
8
10
|
from maxplotlib.backends.matplotlib.utils import (
|
|
9
11
|
set_size,
|
|
10
12
|
setup_plotstyle,
|
|
11
13
|
setup_tex_fonts,
|
|
12
14
|
)
|
|
15
|
+
from maxplotlib.colors.colors import Color
|
|
16
|
+
from maxplotlib.linestyle.linestyle import Linestyle
|
|
13
17
|
from maxplotlib.subfigure.line_plot import LinePlot
|
|
14
|
-
from maxplotlib.subfigure.tikz_figure import TikzFigure
|
|
15
18
|
from maxplotlib.utils.options import Backends
|
|
16
19
|
|
|
17
20
|
|
|
@@ -145,8 +148,6 @@ class Canvas:
|
|
|
145
148
|
|
|
146
149
|
# Initialize the LinePlot for the given subplot position
|
|
147
150
|
tikz_figure = TikzFigure(
|
|
148
|
-
col=col,
|
|
149
|
-
row=row,
|
|
150
151
|
label=label,
|
|
151
152
|
**kwargs,
|
|
152
153
|
)
|
|
@@ -225,7 +226,6 @@ class Canvas:
|
|
|
225
226
|
layers: list | None = None,
|
|
226
227
|
layer_by_layer: bool = False,
|
|
227
228
|
verbose: bool = False,
|
|
228
|
-
plot: bool = True,
|
|
229
229
|
):
|
|
230
230
|
filename_no_extension, extension = os.path.splitext(filename)
|
|
231
231
|
if backend == "matplotlib":
|
|
@@ -254,7 +254,6 @@ class Canvas:
|
|
|
254
254
|
else:
|
|
255
255
|
|
|
256
256
|
fig, axs = self.plot(
|
|
257
|
-
show=False,
|
|
258
257
|
backend="matplotlib",
|
|
259
258
|
savefig=True,
|
|
260
259
|
layers=layers,
|
|
@@ -263,20 +262,33 @@ class Canvas:
|
|
|
263
262
|
if verbose:
|
|
264
263
|
print(f"Saved {full_filepath}")
|
|
265
264
|
|
|
266
|
-
def plot(
|
|
265
|
+
def plot(
|
|
266
|
+
self,
|
|
267
|
+
backend: Backends = "matplotlib",
|
|
268
|
+
savefig=False,
|
|
269
|
+
layers=None,
|
|
270
|
+
):
|
|
267
271
|
if backend == "matplotlib":
|
|
268
272
|
return self.plot_matplotlib(savefig=savefig, layers=layers)
|
|
269
273
|
elif backend == "plotly":
|
|
270
274
|
return self.plot_plotly(savefig=savefig)
|
|
275
|
+
elif backend == "tikzpics":
|
|
276
|
+
return self.plot_tikzpics(savefig=savefig)
|
|
271
277
|
else:
|
|
272
278
|
raise ValueError(f"Invalid backend: {backend}")
|
|
273
279
|
|
|
274
|
-
def show(
|
|
280
|
+
def show(
|
|
281
|
+
self,
|
|
282
|
+
backend: Backends = "matplotlib",
|
|
283
|
+
):
|
|
275
284
|
if backend == "matplotlib":
|
|
276
285
|
self.plot(backend="matplotlib", savefig=False, layers=None)
|
|
277
286
|
self._matplotlib_fig.show()
|
|
278
287
|
elif backend == "plotly":
|
|
279
|
-
|
|
288
|
+
self.plot_plotly(savefig=False)
|
|
289
|
+
elif backend == "tikzpics":
|
|
290
|
+
fig = self.plot_tikzpics(savefig=False)
|
|
291
|
+
fig.show()
|
|
280
292
|
else:
|
|
281
293
|
raise ValueError("Invalid backend")
|
|
282
294
|
|
|
@@ -307,19 +319,20 @@ class Canvas:
|
|
|
307
319
|
dpi=self.dpi,
|
|
308
320
|
)
|
|
309
321
|
|
|
310
|
-
# print(f"{(fig_width / self._dpi, fig_height / self._dpi) = }")
|
|
311
|
-
|
|
312
322
|
fig, axes = plt.subplots(
|
|
313
323
|
self.nrows,
|
|
314
324
|
self.ncols,
|
|
315
325
|
figsize=(fig_width, fig_height),
|
|
316
326
|
squeeze=False,
|
|
317
|
-
dpi=self.
|
|
327
|
+
dpi=self.dpi,
|
|
318
328
|
)
|
|
319
329
|
|
|
320
330
|
for (row, col), subplot in self.subplots.items():
|
|
321
331
|
ax = axes[row][col]
|
|
322
|
-
subplot
|
|
332
|
+
if isinstance(subplot, TikzFigure):
|
|
333
|
+
plot_matplotlib(subplot, ax, layers=layers)
|
|
334
|
+
else:
|
|
335
|
+
subplot.plot_matplotlib(ax, layers=layers)
|
|
323
336
|
# ax.set_title(f"Subplot ({row}, {col})")
|
|
324
337
|
ax.grid()
|
|
325
338
|
|
|
@@ -329,6 +342,22 @@ class Canvas:
|
|
|
329
342
|
self._matplotlib_axes = axes
|
|
330
343
|
return fig, axes
|
|
331
344
|
|
|
345
|
+
def plot_tikzpics(
|
|
346
|
+
self,
|
|
347
|
+
savefig=None,
|
|
348
|
+
verbose=False,
|
|
349
|
+
) -> TikzFigure:
|
|
350
|
+
if len(self.subplots) > 1:
|
|
351
|
+
raise NotImplementedError(
|
|
352
|
+
"Only one subplot is supported for tikzpics backend."
|
|
353
|
+
)
|
|
354
|
+
for (row, col), line_plot in self.subplots.items():
|
|
355
|
+
if verbose:
|
|
356
|
+
print(f"Plotting subplot at row {row}, col {col}")
|
|
357
|
+
print(f"{line_plot = }")
|
|
358
|
+
tikz_subplot = line_plot.plot_tikzpics(verbose=verbose)
|
|
359
|
+
return tikz_subplot
|
|
360
|
+
|
|
332
361
|
def plot_plotly(self, show=True, savefig=None, usetex=False):
|
|
333
362
|
"""
|
|
334
363
|
Generate and optionally display the subplots using Plotly.
|
|
@@ -338,7 +367,7 @@ class Canvas:
|
|
|
338
367
|
savefig (str, optional): Filename to save the figure if provided.
|
|
339
368
|
"""
|
|
340
369
|
|
|
341
|
-
|
|
370
|
+
setup_tex_fonts(
|
|
342
371
|
fontsize=self.fontsize,
|
|
343
372
|
usetex=usetex,
|
|
344
373
|
) # adjust or redefine for Plotly if needed
|
|
@@ -423,9 +452,6 @@ class Canvas:
|
|
|
423
452
|
return self._subplot_matrix
|
|
424
453
|
|
|
425
454
|
# Property setters
|
|
426
|
-
@nrows.setter
|
|
427
|
-
def dpi(self, value):
|
|
428
|
-
self._dpi = value
|
|
429
455
|
|
|
430
456
|
@nrows.setter
|
|
431
457
|
def nrows(self, value):
|
|
@@ -472,75 +498,140 @@ class Canvas:
|
|
|
472
498
|
raise IndexError("Subplot index out of range")
|
|
473
499
|
self._subplot_matrix[row][col] = value
|
|
474
500
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
#
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
#
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
501
|
+
|
|
502
|
+
def plot_matplotlib(tikzfigure: TikzFigure, ax, layers=None):
|
|
503
|
+
"""
|
|
504
|
+
Plot all nodes and paths on the provided axis using Matplotlib.
|
|
505
|
+
|
|
506
|
+
Parameters:
|
|
507
|
+
- ax (matplotlib.axes.Axes): Axis on which to plot the figure.
|
|
508
|
+
"""
|
|
509
|
+
|
|
510
|
+
# TODO: Specify which layers to retreive nodes from with layers=layers
|
|
511
|
+
nodes = tikzfigure.layers.get_nodes()
|
|
512
|
+
paths = tikzfigure.layers.get_paths()
|
|
513
|
+
|
|
514
|
+
for path in paths:
|
|
515
|
+
x_coords = [node.x for node in path.nodes]
|
|
516
|
+
y_coords = [node.y for node in path.nodes]
|
|
517
|
+
|
|
518
|
+
# Parse path color
|
|
519
|
+
path_color_spec = path.kwargs.get("color", "black")
|
|
520
|
+
try:
|
|
521
|
+
color = Color(path_color_spec).to_rgb()
|
|
522
|
+
except ValueError as e:
|
|
523
|
+
print(e)
|
|
524
|
+
color = "black"
|
|
525
|
+
|
|
526
|
+
# Parse line width
|
|
527
|
+
line_width_spec = path.kwargs.get("line_width", 1)
|
|
528
|
+
if isinstance(line_width_spec, str):
|
|
529
|
+
match = re.match(r"([\d.]+)(pt)?", line_width_spec)
|
|
530
|
+
if match:
|
|
531
|
+
line_width = float(match.group(1))
|
|
532
|
+
else:
|
|
533
|
+
print(
|
|
534
|
+
f"Invalid line width specification: '{line_width_spec}', defaulting to 1",
|
|
535
|
+
)
|
|
536
|
+
line_width = 1
|
|
537
|
+
else:
|
|
538
|
+
line_width = float(line_width_spec)
|
|
539
|
+
|
|
540
|
+
# Parse line style using Linestyle class
|
|
541
|
+
style_spec = path.kwargs.get("style", "solid")
|
|
542
|
+
linestyle = Linestyle(style_spec).to_matplotlib()
|
|
543
|
+
|
|
544
|
+
ax.plot(
|
|
545
|
+
x_coords,
|
|
546
|
+
y_coords,
|
|
547
|
+
color=color,
|
|
548
|
+
linewidth=line_width,
|
|
549
|
+
linestyle=linestyle,
|
|
550
|
+
zorder=1, # Lower z-order to place behind nodes
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
# Plot nodes after paths so they appear on top
|
|
554
|
+
for node in nodes:
|
|
555
|
+
# Determine shape and size
|
|
556
|
+
shape = node.kwargs.get("shape", "circle")
|
|
557
|
+
fill_color_spec = node.kwargs.get("fill", "white")
|
|
558
|
+
edge_color_spec = node.kwargs.get("draw", "black")
|
|
559
|
+
linewidth = float(node.kwargs.get("line_width", 1))
|
|
560
|
+
size = float(node.kwargs.get("size", 1))
|
|
561
|
+
|
|
562
|
+
# Parse colors using the Color class
|
|
563
|
+
try:
|
|
564
|
+
facecolor = Color(fill_color_spec).to_rgb()
|
|
565
|
+
except ValueError as e:
|
|
566
|
+
print(e)
|
|
567
|
+
facecolor = "white"
|
|
568
|
+
|
|
569
|
+
try:
|
|
570
|
+
edgecolor = Color(edge_color_spec).to_rgb()
|
|
571
|
+
except ValueError as e:
|
|
572
|
+
print(e)
|
|
573
|
+
edgecolor = "black"
|
|
574
|
+
|
|
575
|
+
# Plot shapes
|
|
576
|
+
if shape == "circle":
|
|
577
|
+
radius = size / 2
|
|
578
|
+
circle = patches.Circle(
|
|
579
|
+
(node.x, node.y),
|
|
580
|
+
radius,
|
|
581
|
+
facecolor=facecolor,
|
|
582
|
+
edgecolor=edgecolor,
|
|
583
|
+
linewidth=linewidth,
|
|
584
|
+
zorder=2, # Higher z-order to place on top of paths
|
|
585
|
+
)
|
|
586
|
+
ax.add_patch(circle)
|
|
587
|
+
elif shape == "rectangle":
|
|
588
|
+
width = height = size
|
|
589
|
+
rect = patches.Rectangle(
|
|
590
|
+
(node.x - width / 2, node.y - height / 2),
|
|
591
|
+
width,
|
|
592
|
+
height,
|
|
593
|
+
facecolor=facecolor,
|
|
594
|
+
edgecolor=edgecolor,
|
|
595
|
+
linewidth=linewidth,
|
|
596
|
+
zorder=2, # Higher z-order
|
|
597
|
+
)
|
|
598
|
+
ax.add_patch(rect)
|
|
599
|
+
else:
|
|
600
|
+
# Default to circle if shape is unknown
|
|
601
|
+
radius = size / 2
|
|
602
|
+
circle = patches.Circle(
|
|
603
|
+
(node.x, node.y),
|
|
604
|
+
radius,
|
|
605
|
+
facecolor=facecolor,
|
|
606
|
+
edgecolor=edgecolor,
|
|
607
|
+
linewidth=linewidth,
|
|
608
|
+
zorder=2,
|
|
609
|
+
)
|
|
610
|
+
ax.add_patch(circle)
|
|
611
|
+
|
|
612
|
+
# Add text inside the shape
|
|
613
|
+
if node.content:
|
|
614
|
+
ax.text(
|
|
615
|
+
node.x,
|
|
616
|
+
node.y,
|
|
617
|
+
node.content,
|
|
618
|
+
fontsize=10,
|
|
619
|
+
ha="center",
|
|
620
|
+
va="center",
|
|
621
|
+
wrap=True,
|
|
622
|
+
zorder=3, # Even higher z-order for text
|
|
623
|
+
)
|
|
624
|
+
|
|
625
|
+
# Remove axes, ticks, and legend
|
|
626
|
+
ax.axis("off")
|
|
627
|
+
|
|
628
|
+
# Adjust plot limits
|
|
629
|
+
all_x = [node.x for node in nodes]
|
|
630
|
+
all_y = [node.y for node in nodes]
|
|
631
|
+
padding = 1 # Adjust padding as needed
|
|
632
|
+
ax.set_xlim(min(all_x) - padding, max(all_x) + padding)
|
|
633
|
+
ax.set_ylim(min(all_y) - padding, max(all_y) + padding)
|
|
634
|
+
ax.set_aspect("equal", adjustable="datalim")
|
|
544
635
|
|
|
545
636
|
|
|
546
637
|
if __name__ == "__main__":
|
|
@@ -2,9 +2,7 @@ import matplotlib.pyplot as plt
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
import plotly.graph_objects as go
|
|
4
4
|
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
|
5
|
-
|
|
6
|
-
import maxplotlib.subfigure.tikz_figure as tf
|
|
7
|
-
from maxplotlib.objects.layer import Tikzlayer
|
|
5
|
+
from tikzpics import TikzFigure
|
|
8
6
|
|
|
9
7
|
|
|
10
8
|
class Node:
|
|
@@ -224,6 +222,21 @@ class LinePlot:
|
|
|
224
222
|
if self.ymax is not None:
|
|
225
223
|
ax.axis(ymax=self.ymax)
|
|
226
224
|
|
|
225
|
+
def plot_tikzpics(self, layers=None, verbose: bool = False) -> TikzFigure:
|
|
226
|
+
|
|
227
|
+
tikz_figure = TikzFigure()
|
|
228
|
+
for layer_name, layer_lines in self.layered_line_data.items():
|
|
229
|
+
if layers and layer_name not in layers:
|
|
230
|
+
continue
|
|
231
|
+
for line in layer_lines:
|
|
232
|
+
if line["plot_type"] == "plot":
|
|
233
|
+
x = (line["x"] + self._xshift) * self._xscale
|
|
234
|
+
y = (line["y"] + self._yshift) * self._yscale
|
|
235
|
+
|
|
236
|
+
nodes = [[xi, yi] for xi, yi in zip(x, y)]
|
|
237
|
+
tikz_figure.draw(nodes=nodes, **line["kwargs"])
|
|
238
|
+
return tikz_figure
|
|
239
|
+
|
|
227
240
|
def plot_plotly(self):
|
|
228
241
|
"""
|
|
229
242
|
Plot all lines using Plotly and return a list of traces for each line.
|
|
@@ -255,68 +268,6 @@ class LinePlot:
|
|
|
255
268
|
|
|
256
269
|
return traces
|
|
257
270
|
|
|
258
|
-
def add_node(self, x, y, label=None, content="", layer=0, **kwargs):
|
|
259
|
-
"""
|
|
260
|
-
Add a node to the TikZ figure.
|
|
261
|
-
|
|
262
|
-
Parameters:
|
|
263
|
-
- x (float): X-coordinate of the node.
|
|
264
|
-
- y (float): Y-coordinate of the node.
|
|
265
|
-
- label (str, optional): Label of the node. If None, a default label will be assigned.
|
|
266
|
-
- **kwargs: Additional TikZ node options (e.g., shape, color).
|
|
267
|
-
|
|
268
|
-
Returns:
|
|
269
|
-
- node (Node): The Node object that was added.
|
|
270
|
-
"""
|
|
271
|
-
if label is None:
|
|
272
|
-
label = f"node{self._node_counter}"
|
|
273
|
-
node = Node(x=x, y=y, label=label, layer=layer, content=content, **kwargs)
|
|
274
|
-
self.nodes.append(node)
|
|
275
|
-
if layer in self.layers:
|
|
276
|
-
self.layers[layer].add(node)
|
|
277
|
-
else:
|
|
278
|
-
# print(f"{self.layers = } {layer = }")
|
|
279
|
-
self.layers[layer] = Tikzlayer(layer)
|
|
280
|
-
self.layers[layer].add(node)
|
|
281
|
-
self._node_counter += 1
|
|
282
|
-
return node
|
|
283
|
-
|
|
284
|
-
def add_path(self, nodes, layer=0, **kwargs):
|
|
285
|
-
"""
|
|
286
|
-
Add a line or path connecting multiple nodes.
|
|
287
|
-
|
|
288
|
-
Parameters:
|
|
289
|
-
- nodes (list of str): List of node names to connect.
|
|
290
|
-
- **kwargs: Additional TikZ path options (e.g., style, color).
|
|
291
|
-
|
|
292
|
-
Examples:
|
|
293
|
-
- add_path(['A', 'B', 'C'], color='blue')
|
|
294
|
-
Connects nodes A -> B -> C with a blue line.
|
|
295
|
-
"""
|
|
296
|
-
if not isinstance(nodes, list):
|
|
297
|
-
raise ValueError("nodes parameter must be a list of node names.")
|
|
298
|
-
|
|
299
|
-
nodes = [
|
|
300
|
-
(
|
|
301
|
-
node
|
|
302
|
-
if isinstance(node, Node)
|
|
303
|
-
else (
|
|
304
|
-
self.get_node(node)
|
|
305
|
-
if isinstance(node, str)
|
|
306
|
-
else ValueError(f"Invalid node type: {type(node)}")
|
|
307
|
-
)
|
|
308
|
-
)
|
|
309
|
-
for node in nodes
|
|
310
|
-
]
|
|
311
|
-
path = Path(nodes, **kwargs)
|
|
312
|
-
self.paths.append(path)
|
|
313
|
-
if layer in self.layers:
|
|
314
|
-
self.layers[layer].add(path)
|
|
315
|
-
else:
|
|
316
|
-
self.layers[layer] = Tikzlayer(layer)
|
|
317
|
-
self.layers[layer].add(path)
|
|
318
|
-
return path
|
|
319
|
-
|
|
320
271
|
@property
|
|
321
272
|
def xmin(self):
|
|
322
273
|
return self._xmin
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maxplotlibx
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A reproducible plotting module with various backends and export options.
|
|
5
5
|
Author: Max
|
|
6
6
|
Project-URL: Source, https://github.com/max-models/maxplotlib
|
|
@@ -12,6 +12,7 @@ License-File: LICENSE
|
|
|
12
12
|
Requires-Dist: matplotlib
|
|
13
13
|
Requires-Dist: pint
|
|
14
14
|
Requires-Dist: plotly
|
|
15
|
+
Requires-Dist: tikzpics>=0.1.1
|
|
15
16
|
Provides-Extra: test
|
|
16
17
|
Requires-Dist: pytest; extra == "test"
|
|
17
18
|
Requires-Dist: coverage; extra == "test"
|
|
@@ -3,7 +3,6 @@ README.md
|
|
|
3
3
|
pyproject.toml
|
|
4
4
|
src/maxplotlib/__init__.py
|
|
5
5
|
src/maxplotlib/backends/matplotlib/utils.py
|
|
6
|
-
src/maxplotlib/backends/matplotlib/utils_old.py
|
|
7
6
|
src/maxplotlib/backends/plotly/__init__.py
|
|
8
7
|
src/maxplotlib/backends/plotly/utils.py
|
|
9
8
|
src/maxplotlib/canvas/__init__.py
|
|
@@ -13,13 +12,11 @@ src/maxplotlib/colors/colors.py
|
|
|
13
12
|
src/maxplotlib/linestyle/__init__.py
|
|
14
13
|
src/maxplotlib/linestyle/linestyle.py
|
|
15
14
|
src/maxplotlib/objects/__init__.py
|
|
16
|
-
src/maxplotlib/objects/layer.py
|
|
17
15
|
src/maxplotlib/objects/node.py
|
|
18
16
|
src/maxplotlib/objects/path.py
|
|
19
17
|
src/maxplotlib/subfigure/__init__.py
|
|
20
18
|
src/maxplotlib/subfigure/line_plot.py
|
|
21
19
|
src/maxplotlib/subfigure/subfigure.py
|
|
22
|
-
src/maxplotlib/subfigure/tikz_figure.py
|
|
23
20
|
src/maxplotlib/tests/test_canvas.py
|
|
24
21
|
src/maxplotlib/tests/test_imports.py
|
|
25
22
|
src/maxplotlib/tests/test_plot.py
|