tikzplot42 0.6.2__tar.gz → 0.6.3__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.
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/PKG-INFO +2 -1
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/README.md +1 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/pyproject.toml +1 -1
- tikzplot42-0.6.3/src/tikzplot/arrows.py +87 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/axes.py +30 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/axes.pyi +52 -1
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/axes3d.py +21 -7
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/axes3d.pyi +6 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/figure.py +6 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/latex_special.py +1 -1
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/plots.py +5 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/plots.pyi +45 -1
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/texts.py +3 -3
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot42.egg-info/PKG-INFO +2 -1
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot42.egg-info/SOURCES.txt +1 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test7.py +1 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/LICENSE +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/setup.cfg +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/__init__.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/__init__.pyi +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/border_finder.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/colorbar.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/colorbar.pyi +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/colors.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/config.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/config.pyi +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/elements.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/elements.pyi +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/figure.pyi +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/pie.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/py.typed +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/state.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/styles.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot/styles.pyi +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot42.egg-info/dependency_links.txt +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot42.egg-info/requires.txt +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/src/tikzplot42.egg-info/top_level.txt +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test1.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test10.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test11.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test12.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test13.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test14.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test15.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test16.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test17.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test18.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test19.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test2.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test20.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test21.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test22.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test23.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test24.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test25.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test26.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test27.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test28.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test3.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test4.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test5.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test6.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test8.py +0 -0
- {tikzplot42-0.6.2 → tikzplot42-0.6.3}/tests/test9.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tikzplot42
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
4
4
|
Summary: TikzPlot to make TikZ/PGFPlots plots with matplotlib.pyplot-like syntax.
|
|
5
5
|
Author-email: Zan Ambrozic <zan.ambrozic7@gmail.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -764,6 +764,7 @@ Some basic plot commands are already implemented with commonly used arguments:
|
|
|
764
764
|
- `imshow()`,
|
|
765
765
|
- `matshow()`,
|
|
766
766
|
- `text()`,
|
|
767
|
+
- `annotate()`,
|
|
767
768
|
- `bxp()` (without notches),
|
|
768
769
|
- `boxplot()` (without notches),
|
|
769
770
|
- `violin()`,
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tikzplot42"
|
|
7
|
-
version = "0.6.
|
|
7
|
+
version = "0.6.3"
|
|
8
8
|
description = "TikzPlot to make TikZ/PGFPlots plots with matplotlib.pyplot-like syntax."
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Zan Ambrozic", email = "zan.ambrozic7@gmail.com" }
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from .colors import _tex_color
|
|
2
|
+
|
|
3
|
+
class Arrow:
|
|
4
|
+
_LINE_MAP = {"--": "dashed", ":": "dotted", "-.": "dashdotted", "-":"solid"}
|
|
5
|
+
def __init__(self, ax, x1, y1, x2, y2, coordinate1, coordinate2, **kwargs):
|
|
6
|
+
self._axes = ax
|
|
7
|
+
self._x1 = x1
|
|
8
|
+
self._y1 = y1
|
|
9
|
+
self._x2 = x2
|
|
10
|
+
self._y2 = y2
|
|
11
|
+
self._coordinate1 = coordinate1
|
|
12
|
+
self._coordinate2 = coordinate2
|
|
13
|
+
self._kwargs = kwargs
|
|
14
|
+
self._opacity = 1
|
|
15
|
+
self._visible = True
|
|
16
|
+
|
|
17
|
+
def match_color(self, input):
|
|
18
|
+
self._has_color = True
|
|
19
|
+
ccode, op = _tex_color(input)
|
|
20
|
+
if not isinstance(op, bool):
|
|
21
|
+
self._opacity = op
|
|
22
|
+
if isinstance(ccode, str):
|
|
23
|
+
return ccode
|
|
24
|
+
r,g,b=ccode
|
|
25
|
+
self._axes._add_col(r,g,b)
|
|
26
|
+
return f"c{r:.3f}{g:.3f}{b:.3f}".replace(".", "")
|
|
27
|
+
|
|
28
|
+
def _style_string(self):
|
|
29
|
+
output = []
|
|
30
|
+
if "arrowstyle" in self._kwargs:
|
|
31
|
+
allowed = {"<", ">", "|", "stealth", "latex"}
|
|
32
|
+
arstyle = self._kwargs["arrowstyle"]
|
|
33
|
+
arstyle = arstyle.split("-")
|
|
34
|
+
if not all(s in allowed for s in arstyle):
|
|
35
|
+
raise ValueError(f"Arrow style {self._kwargs['arrowstyle']} not recognized. Valid options should consist of: {allowed}, separated by -.")
|
|
36
|
+
output.append(self._kwargs["arrowstyle"])
|
|
37
|
+
if "color" in self._kwargs or "c" in self._kwargs:
|
|
38
|
+
self._color = self.match_color(self._kwargs.get("color") or self._kwargs.get("c"))
|
|
39
|
+
if "alpha" in self._kwargs:
|
|
40
|
+
self._opacity = self._kwargs["alpha"]
|
|
41
|
+
if "line width" in self._kwargs or "lw" in self._kwargs:
|
|
42
|
+
output.append("line width=" + str(self._kwargs.get("line width") or self._kwargs.get("lw")))
|
|
43
|
+
if "linestyle" in self._kwargs or "ls" in self._kwargs:
|
|
44
|
+
ls = self._kwargs.get("linestyle") or self._kwargs.get("ls")
|
|
45
|
+
if ls in self._LINE_MAP:
|
|
46
|
+
ls = self._LINE_MAP[ls]
|
|
47
|
+
elif ls not in self._LINE_MAP.values():
|
|
48
|
+
raise ValueError(f"Line style {ls} not recognized. Valid options are: {list(self._LINE_MAP.keys())}.")
|
|
49
|
+
output.append("line style=" + str(ls))
|
|
50
|
+
if self._opacity < 1:
|
|
51
|
+
output.insert(0,f"opacity={self._opacity}")
|
|
52
|
+
if self._color:
|
|
53
|
+
output.insert(0,f"color={self._color}")
|
|
54
|
+
return ", ".join(output)
|
|
55
|
+
|
|
56
|
+
def _to_tex(self, *args, **kwargs):
|
|
57
|
+
if self._visible:
|
|
58
|
+
if self._coordinate1 is not None:
|
|
59
|
+
return f"\\coordinate {self._coordinate1} at (axis cs:{self._x1},{self._y1});"
|
|
60
|
+
else:
|
|
61
|
+
return ""
|
|
62
|
+
|
|
63
|
+
def _to_tex_fin(self):
|
|
64
|
+
if self._visible:
|
|
65
|
+
if self._coordinate1 is not None and self._coordinate2 is not None:
|
|
66
|
+
return f"\\draw[{self._style_string()}] {self._coordinate2} -- {self._coordinate1};"
|
|
67
|
+
else:
|
|
68
|
+
return ""
|
|
69
|
+
|
|
70
|
+
def _filter(self, which, label):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
def _get_erange(self, which):
|
|
74
|
+
if which == "xmin":
|
|
75
|
+
return min(self._x1, self._x2)
|
|
76
|
+
elif which == "xmax":
|
|
77
|
+
return max(self._x1, self._x2)
|
|
78
|
+
elif which == "ymin":
|
|
79
|
+
return min(self._y1, self._y2)
|
|
80
|
+
elif which == "ymax":
|
|
81
|
+
return max(self._y1, self._y2)
|
|
82
|
+
|
|
83
|
+
def _num_points(self):
|
|
84
|
+
return 2
|
|
85
|
+
|
|
86
|
+
def _reduce_points(self, max_points):
|
|
87
|
+
pass
|
|
@@ -9,6 +9,7 @@ from skimage import measure
|
|
|
9
9
|
|
|
10
10
|
from .elements import Graph, Single
|
|
11
11
|
from .texts import Text
|
|
12
|
+
from .arrows import Arrow
|
|
12
13
|
from .config import TikzConfig
|
|
13
14
|
from .colorbar import Colorbar
|
|
14
15
|
from .state import _next_imshow_num, main_name
|
|
@@ -2560,6 +2561,32 @@ class BaseAxes:
|
|
|
2560
2561
|
txt = Text(self, x, y, None, s, **kwargs)
|
|
2561
2562
|
self._elements[self._get_overlay()].append(txt)
|
|
2562
2563
|
|
|
2564
|
+
def annotate(self, text, xy, xytext=None, arrowprops=None, **kwargs):
|
|
2565
|
+
kws = {"alpha", "color", "c", "fontsize", "size", "backgroundcolor", "horizontalalignment", "ha", "verticalalignment", "va", "rotation", "label"}
|
|
2566
|
+
kwargs = self._check_kwargs("annotate", kws, **kwargs)
|
|
2567
|
+
akws = {"arrowstyle", "alpha", "color", "c", "linewidth", "lw", "linestyle", "ls"}
|
|
2568
|
+
passing_kwargs = {"alpha", "color", "c"}
|
|
2569
|
+
ap0 = {k: kwargs[k] for k in passing_kwargs if k in kwargs}
|
|
2570
|
+
if arrowprops is not None:
|
|
2571
|
+
arrowprops = self._check_kwargs("annotate: arrowprops", akws, **arrowprops)
|
|
2572
|
+
else:
|
|
2573
|
+
arrowprops = {}
|
|
2574
|
+
arrowprops = ap0 | arrowprops
|
|
2575
|
+
assert self._fig is not None
|
|
2576
|
+
xa, ya = xy
|
|
2577
|
+
if xytext is not None:
|
|
2578
|
+
xt, yt = xytext
|
|
2579
|
+
else:
|
|
2580
|
+
return self.text(xa, ya, text, **kwargs)
|
|
2581
|
+
ca = self._fig._next_coordinate_name()
|
|
2582
|
+
ct = self._fig._next_coordinate_name()
|
|
2583
|
+
txt = Text(self, xt, yt, ct, text, **kwargs)
|
|
2584
|
+
self._fig._add_text(txt)
|
|
2585
|
+
arr = Arrow(self, xa, ya, xt, yt, ca, ct, **arrowprops)
|
|
2586
|
+
self._fig._add_arrow(arr)
|
|
2587
|
+
self._elements[self._get_overlay()].append(txt)
|
|
2588
|
+
self._elements[self._get_overlay()].append(arr)
|
|
2589
|
+
|
|
2563
2590
|
def magnify(self, x_p, y_p, x_m, y_m, zoom, size, **kwargs):
|
|
2564
2591
|
kws = {"shape", "connect"}
|
|
2565
2592
|
kwargs = self._check_kwargs("magnify", kws, **kwargs)
|
|
@@ -2568,6 +2595,9 @@ class BaseAxes:
|
|
|
2568
2595
|
self._coordinates.update({f"spypoint{n}": (x_p,y_p)})
|
|
2569
2596
|
self._coordinates.update({f"spyviewr{n}": (x_m,y_m)})
|
|
2570
2597
|
|
|
2598
|
+
def set_axis_off(self):
|
|
2599
|
+
self._axis_options["hide axis"] = None
|
|
2600
|
+
|
|
2571
2601
|
def _add_legend_entries(self):
|
|
2572
2602
|
if self._add_legend == []: return ""
|
|
2573
2603
|
axs, labs = self._add_legend
|
|
@@ -368,7 +368,7 @@ class BaseAxes:
|
|
|
368
368
|
Text position in axis coordinates
|
|
369
369
|
|
|
370
370
|
s: str
|
|
371
|
-
Text content
|
|
371
|
+
Text content
|
|
372
372
|
|
|
373
373
|
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
374
374
|
Text color: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
@@ -395,6 +395,51 @@ class BaseAxes:
|
|
|
395
395
|
Legend entry
|
|
396
396
|
"""
|
|
397
397
|
...
|
|
398
|
+
|
|
399
|
+
def annotate(self, text: str, xy: Tuple[float|int, float|int], xytext: Optional[Tuple[float|int, float|int]] = None, arrowprops: Optional[dict] = None, alpha: float = 1, color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ..., fontsize: Optional[FontSize] = ..., size: Optional[FontSize] = ..., backgroundcolor: Optional[ColorLike] = ..., horizontalalignment: Literal["left", "center", "right"] = "center", ha: Literal["left", "center", "right"] = "center", verticalalignment: Literal["bottom", "center", "top"] = "center", va: Literal["bottom", "center", "top"] = "center", rotation: float = 0, label: Optional[str] = ...) -> None:
|
|
400
|
+
"""
|
|
401
|
+
Add an annotation with optional arrow to the selected axis.
|
|
402
|
+
|
|
403
|
+
Parameters
|
|
404
|
+
----------
|
|
405
|
+
text: str
|
|
406
|
+
Annotation text
|
|
407
|
+
|
|
408
|
+
xy: tuple of float
|
|
409
|
+
Point (x,y) to annotate in axis coordinates
|
|
410
|
+
|
|
411
|
+
xytext: tuple of float, optional
|
|
412
|
+
Position (x,y) of the text in axis coordinates. If not provided, only text will be displayed at specified location (same as using text() method).
|
|
413
|
+
|
|
414
|
+
arrowprops: dict, optional
|
|
415
|
+
Dictionary of properties for the arrow. If not provided, no arrow will be drawn. Possible keys include 'arrowstyle', 'color', 'c', 'linewidth', 'lw', 'linestyle', 'ls', 'alpha'. For 'arrowstyle', basic LaTeX arrow styles are allowed ('>', '<', '|', 'stealth', 'latex', etc., separated by '-' to indicate side).
|
|
416
|
+
|
|
417
|
+
alpha: float, optional
|
|
418
|
+
Opacity
|
|
419
|
+
|
|
420
|
+
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
421
|
+
Text color: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
422
|
+
|
|
423
|
+
fontsize or size: FontSize, optional
|
|
424
|
+
Font size
|
|
425
|
+
|
|
426
|
+
backgroundcolor: all matplotlib color formats (without X11/xkcd), optional
|
|
427
|
+
Background color of text box: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
428
|
+
|
|
429
|
+
horizontalalignment or ha: {"center", "left", "right"}, optional
|
|
430
|
+
Horizontal alignment of text
|
|
431
|
+
|
|
432
|
+
verticalalignment or va: {"center", "top", "bottom"}, optional
|
|
433
|
+
Vertical alignment of text
|
|
434
|
+
|
|
435
|
+
rotation: float or {"vertical", "horizontal"}, optional
|
|
436
|
+
Rotation angle in degrees or preset rotation
|
|
437
|
+
|
|
438
|
+
label: str, optional
|
|
439
|
+
Legend entry
|
|
440
|
+
"""
|
|
441
|
+
...
|
|
442
|
+
|
|
398
443
|
def hlines(
|
|
399
444
|
self,
|
|
400
445
|
y: Union[float, ArrayLike],
|
|
@@ -2094,6 +2139,12 @@ class BaseAxes:
|
|
|
2094
2139
|
"""
|
|
2095
2140
|
...
|
|
2096
2141
|
|
|
2142
|
+
def set_axis_off(self) -> None:
|
|
2143
|
+
"""
|
|
2144
|
+
Turn off axis (no ticks, no labels, no frame)
|
|
2145
|
+
"""
|
|
2146
|
+
...
|
|
2147
|
+
|
|
2097
2148
|
def _add_legend_entries(self) -> str: ...
|
|
2098
2149
|
def _content_tex(self, filename: str) -> str: ...
|
|
2099
2150
|
def _get_hard_range(self, which: Literal["xmin","xmax","ymin","ymax"]) -> Tuple[float,str]: ...
|
|
@@ -86,7 +86,6 @@ class Axes3:
|
|
|
86
86
|
self._width= f"{self._fig._get_width() / ncols}cm"
|
|
87
87
|
if self._fig._get_height():
|
|
88
88
|
self._height = f"{self._fig._get_height() / nrows}cm"
|
|
89
|
-
|
|
90
89
|
self._style_defaults()
|
|
91
90
|
|
|
92
91
|
def _new_pos(self, nrows, ncols, index):
|
|
@@ -1020,14 +1019,26 @@ class Axes3:
|
|
|
1020
1019
|
mode = "lin"
|
|
1021
1020
|
if arg in self._axis_options:
|
|
1022
1021
|
mode = self._axis_options[arg]
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1022
|
+
common = self._get_all_elements().copy()
|
|
1023
|
+
if which in self._axis_options and isinstance(self._axis_options[which], (int, float)):
|
|
1024
|
+
other = which.replace("min", "max") if "min" in which else which.replace("max", "min")
|
|
1025
|
+
if other in self._axis_options and (("min" in which and self._axis_options[which] > self._axis_options[other]) or ("max" in which and self._axis_options[which] < self._axis_options[other])):
|
|
1026
|
+
for e in common:
|
|
1027
|
+
e._filter(other, self._axis_options[which])
|
|
1028
|
+
else:
|
|
1029
|
+
for e in common:
|
|
1030
|
+
e._filter(which, self._axis_options[which])
|
|
1026
1031
|
return (self._axis_options[which], True, mode)
|
|
1032
|
+
values = [e._get_erange(which) for e in common]
|
|
1033
|
+
if which in self._preferred_lims:
|
|
1034
|
+
values.append(self._preferred_lims[which])
|
|
1035
|
+
values = [v for v in values if v is not None]
|
|
1036
|
+
if not values:
|
|
1037
|
+
return (None, False, mode)
|
|
1027
1038
|
if "min" in which:
|
|
1028
|
-
return (min(
|
|
1029
|
-
return (max(
|
|
1030
|
-
|
|
1039
|
+
return (min(values), False, mode)
|
|
1040
|
+
return (max(values), False, mode)
|
|
1041
|
+
|
|
1031
1042
|
def _set_range(self, which, value):
|
|
1032
1043
|
self._axis_options[which] = value
|
|
1033
1044
|
for e in self._get_all_elements():
|
|
@@ -1100,6 +1111,9 @@ class Axes3:
|
|
|
1100
1111
|
def set_minorticks_num(self, num):
|
|
1101
1112
|
self._axis_options["minor tick num"] = num
|
|
1102
1113
|
|
|
1114
|
+
def set_axis_off(self):
|
|
1115
|
+
self._axis_options["hide axis"] = None
|
|
1116
|
+
|
|
1103
1117
|
def _axis_option_string(self):
|
|
1104
1118
|
if self._extend:
|
|
1105
1119
|
self._axis_options.pop("alias", self._axis_options.pop("name", None))
|
|
@@ -581,6 +581,12 @@ class Axes3:
|
|
|
581
581
|
"""
|
|
582
582
|
...
|
|
583
583
|
|
|
584
|
+
def set_axis_off(self) -> None:
|
|
585
|
+
"""
|
|
586
|
+
Turn off the axis lines, ticks, and labels.
|
|
587
|
+
"""
|
|
588
|
+
...
|
|
589
|
+
|
|
584
590
|
def _add_legend_entries(self) -> str: ...
|
|
585
591
|
def _content_tex(self, filename: str) -> str: ...
|
|
586
592
|
def _get_hard_range(self, which: Literal["xmin","xmax","ymin","ymax"]) -> Tuple[float,str]: ...
|
|
@@ -37,6 +37,7 @@ class Figure:
|
|
|
37
37
|
self._num_coordinates = 0
|
|
38
38
|
|
|
39
39
|
self._texts = []
|
|
40
|
+
self._arrows = []
|
|
40
41
|
|
|
41
42
|
self._lims = {"xmin": {}, "xmax": {}, "ymin": {}, "ymax": {}, "zmin": {}, "zmax": {}}
|
|
42
43
|
|
|
@@ -628,6 +629,8 @@ class Figure:
|
|
|
628
629
|
lines.append(spy)
|
|
629
630
|
for text in self._texts:
|
|
630
631
|
lines.append(text._to_tex_fin())
|
|
632
|
+
for arr in self._arrows:
|
|
633
|
+
lines.append(arr._to_tex_fin())
|
|
631
634
|
for ext in self._external:
|
|
632
635
|
lines.append(ext._to_tex())
|
|
633
636
|
lines.append("\\end{tikzpicture}")
|
|
@@ -730,6 +733,9 @@ class Figure:
|
|
|
730
733
|
def _add_text(self, text):
|
|
731
734
|
self._texts.append(text)
|
|
732
735
|
|
|
736
|
+
def _add_arrow(self, arrow):
|
|
737
|
+
self._arrows.append(arrow)
|
|
738
|
+
|
|
733
739
|
def tight_layout(self, h_pad=0, w_pad=0, rect=(0,0,1,1)):
|
|
734
740
|
TikzConfig.SCALE_ONLY_AXIS = True
|
|
735
741
|
if not TikzConfig.USE_GROUPPLOTS:
|
|
@@ -195,6 +195,11 @@ def text(*args, **kwargs):
|
|
|
195
195
|
assert _current_axes
|
|
196
196
|
return _current_axes.text(*args, **kwargs)
|
|
197
197
|
|
|
198
|
+
def annotate(*args, **kwargs):
|
|
199
|
+
_ensure_axes()
|
|
200
|
+
assert _current_axes
|
|
201
|
+
return _current_axes.annotate(*args, **kwargs)
|
|
202
|
+
|
|
198
203
|
def hlines(*args, **kwargs):
|
|
199
204
|
_ensure_axes()
|
|
200
205
|
assert _current_axes
|
|
@@ -754,7 +754,7 @@ def text(x: float, y: float, s: str, color: Optional[ColorLike] = ..., c: Option
|
|
|
754
754
|
Text position in axis coordinates
|
|
755
755
|
|
|
756
756
|
s: str
|
|
757
|
-
Text content
|
|
757
|
+
Text content
|
|
758
758
|
|
|
759
759
|
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
760
760
|
Text color: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
@@ -782,6 +782,50 @@ def text(x: float, y: float, s: str, color: Optional[ColorLike] = ..., c: Option
|
|
|
782
782
|
"""
|
|
783
783
|
...
|
|
784
784
|
|
|
785
|
+
def annotate(self, text: str, xy: Tuple[float|int, float|int], xytext: Optional[Tuple[float|int, float|int]] = None, arrowprops: Optional[dict] = None, alpha: float = 1, color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ..., fontsize: Optional[FontSize] = ..., size: Optional[FontSize] = ..., backgroundcolor: Optional[ColorLike] = ..., horizontalalignment: Literal["left", "center", "right"] = "center", ha: Literal["left", "center", "right"] = "center", verticalalignment: Literal["bottom", "center", "top"] = "center", va: Literal["bottom", "center", "top"] = "center", rotation: float = 0, label: Optional[str] = ...) -> None:
|
|
786
|
+
"""
|
|
787
|
+
Add an annotation with optional arrow to the selected axis.
|
|
788
|
+
|
|
789
|
+
Parameters
|
|
790
|
+
----------
|
|
791
|
+
text: str
|
|
792
|
+
Annotation text
|
|
793
|
+
|
|
794
|
+
xy: tuple of float
|
|
795
|
+
Point (x,y) to annotate in axis coordinates
|
|
796
|
+
|
|
797
|
+
xytext: tuple of float, optional
|
|
798
|
+
Position (x,y) of the text in axis coordinates. If not provided, only text will be displayed at specified location (same as using text() method).
|
|
799
|
+
|
|
800
|
+
arrowprops: dict, optional
|
|
801
|
+
Dictionary of properties for the arrow. If not provided, no arrow will be drawn. Possible keys include 'arrowstyle', 'color', 'c', 'linewidth', 'lw', 'linestyle', 'ls', 'alpha'. For 'arrowstyle', basic LaTeX arrow styles are allowed ('>', '<', '|', 'stealth', 'latex', etc., separated by '-' to indicate side).
|
|
802
|
+
|
|
803
|
+
alpha: float, optional
|
|
804
|
+
Opacity
|
|
805
|
+
|
|
806
|
+
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
807
|
+
Text color: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
808
|
+
|
|
809
|
+
fontsize or size: FontSize, optional
|
|
810
|
+
Font size
|
|
811
|
+
|
|
812
|
+
backgroundcolor: all matplotlib color formats (without X11/xkcd), optional
|
|
813
|
+
Background color of text box: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
814
|
+
|
|
815
|
+
horizontalalignment or ha: {"center", "left", "right"}, optional
|
|
816
|
+
Horizontal alignment of text
|
|
817
|
+
|
|
818
|
+
verticalalignment or va: {"center", "top", "bottom"}, optional
|
|
819
|
+
Vertical alignment of text
|
|
820
|
+
|
|
821
|
+
rotation: float or {"vertical", "horizontal"}, optional
|
|
822
|
+
Rotation angle in degrees or preset rotation
|
|
823
|
+
|
|
824
|
+
label: str, optional
|
|
825
|
+
Legend entry
|
|
826
|
+
"""
|
|
827
|
+
...
|
|
828
|
+
|
|
785
829
|
def loglog(x: ArrayLike = ..., y: ArrayLike = ..., base: Optional[float] = 10, fmt: Optional[str] = ...,*, alpha: Optional[float] = ..., color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ...,
|
|
786
830
|
linestyle: Optional[LineStyle] = ..., ls: Optional[LineStyle] = ..., linewidth: Optional[float]= ..., lw: Optional[float] = ...,
|
|
787
831
|
marker: Optional[MarkerStyle] = ..., markersize: Optional[float] = ..., ms: Optional[float] = ...) -> Graph:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .colors import _tex_color
|
|
2
|
+
from .latex_special import tex_text
|
|
2
3
|
|
|
3
4
|
class Text:
|
|
4
5
|
def __init__(self, ax, x, y, coordinate, s, **kwargs):
|
|
@@ -6,7 +7,7 @@ class Text:
|
|
|
6
7
|
self._x = x
|
|
7
8
|
self._y = y
|
|
8
9
|
self._coordinate = coordinate
|
|
9
|
-
self._s = s
|
|
10
|
+
self._s = tex_text(s)
|
|
10
11
|
self._kwargs = kwargs
|
|
11
12
|
self._color = False
|
|
12
13
|
self._opacity = 1
|
|
@@ -14,7 +15,6 @@ class Text:
|
|
|
14
15
|
self._label = kwargs.get("label", None)
|
|
15
16
|
self._visible = True
|
|
16
17
|
|
|
17
|
-
|
|
18
18
|
def match_color(self, input):
|
|
19
19
|
self._has_color = True
|
|
20
20
|
ccode, op = _tex_color(input)
|
|
@@ -71,7 +71,6 @@ class Text:
|
|
|
71
71
|
output.insert(0,f"color={self._color}")
|
|
72
72
|
return ", ".join(output)
|
|
73
73
|
|
|
74
|
-
|
|
75
74
|
def _to_tex(self, *args, **kwargs):
|
|
76
75
|
if self._visible:
|
|
77
76
|
if self._coordinate is not None:
|
|
@@ -87,6 +86,7 @@ class Text:
|
|
|
87
86
|
return f"\\node[{self._style_string()}] at {self._coordinate} {{{self._fsize or ''}{self._s}}};"
|
|
88
87
|
else:
|
|
89
88
|
return ""
|
|
89
|
+
|
|
90
90
|
def _set_label(self, label):
|
|
91
91
|
self._label = label
|
|
92
92
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tikzplot42
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
4
4
|
Summary: TikzPlot to make TikZ/PGFPlots plots with matplotlib.pyplot-like syntax.
|
|
5
5
|
Author-email: Zan Ambrozic <zan.ambrozic7@gmail.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -764,6 +764,7 @@ Some basic plot commands are already implemented with commonly used arguments:
|
|
|
764
764
|
- `imshow()`,
|
|
765
765
|
- `matshow()`,
|
|
766
766
|
- `text()`,
|
|
767
|
+
- `annotate()`,
|
|
767
768
|
- `bxp()` (without notches),
|
|
768
769
|
- `boxplot()` (without notches),
|
|
769
770
|
- `violin()`,
|
|
@@ -27,6 +27,7 @@ ax.plot(x, y, color="blue", lw=1.5, label="sin(x)")
|
|
|
27
27
|
ax.text(1.5, 0.5, r"text $\alpha$", color="blue", ha="center", on_top=False, va="center", backgroundcolor="cyan", rotation=30)
|
|
28
28
|
ax.plot(x, y2, ls="--", color="red", label="cos(x)")
|
|
29
29
|
ax.text(1.5, -0.5, r"text $\beta$", color="teal", ha="center", va="center", rotation=-70)
|
|
30
|
+
ax.annotate(r"min", xy=(4.7, -1), xytext=(5, -0.5), arrowprops={"arrowstyle": "|-stealth", "color": "grey", "lw": 1.5}, c="cyan", va="bottom", rotation=-10)
|
|
30
31
|
|
|
31
32
|
ax.grid()
|
|
32
33
|
ax.legend(loc="upper right")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|