tikzplot42 0.4.5__tar.gz → 0.4.7__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.4.5 → tikzplot42-0.4.7}/PKG-INFO +6 -3
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/README.md +5 -2
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/pyproject.toml +1 -1
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/axes.py +26 -10
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/axes.pyi +99 -3
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/elements.py +63 -6
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/figure.py +47 -23
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/figure.pyi +4 -2
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/plots.py +4 -4
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/plots.pyi +139 -17
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot42.egg-info/PKG-INFO +6 -3
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test13.py +4 -3
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test2.py +3 -2
- tikzplot42-0.4.7/tests/test4.py +9 -0
- tikzplot42-0.4.5/tests/test4.py +0 -8
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/LICENSE +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/setup.cfg +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/__init__.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/__init__.pyi +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/axes3d.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/axes3d.pyi +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/colorbar.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/colorbar.pyi +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/colors.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/config.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/config.pyi +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/elements.pyi +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/latex_special.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/py.typed +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/state.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/styles.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/styles.pyi +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot/texts.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot42.egg-info/SOURCES.txt +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot42.egg-info/dependency_links.txt +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot42.egg-info/requires.txt +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/src/tikzplot42.egg-info/top_level.txt +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test1.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test10.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test11.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test12.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test3.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test5.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test6.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test7.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test8.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test9.py +0 -0
- {tikzplot42-0.4.5 → tikzplot42-0.4.7}/tests/test_styles.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tikzplot42
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.7
|
|
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
|
|
@@ -717,13 +717,15 @@ Alternativley, download this package and install using: `pip install [path]`, wh
|
|
|
717
717
|
Instead of using `import matplotlib.pyplot (as plt)`, use `import tikzplot.plots (as plt)`.
|
|
718
718
|
|
|
719
719
|
## LaTeX requirements
|
|
720
|
+
All required packages are automatically detected and can be printed at save using kwarg `print_requirements=True` (for standalone files, preambule is automatically added).
|
|
720
721
|
- `\usepackage{tikz}`,
|
|
721
722
|
- `\usepackage{pgfplots}`,
|
|
722
723
|
- `\pgfplotsset{compat=1.18}` (may be lower, but compilation is not guaranteed),
|
|
723
724
|
- `\usepgfplotslibrary{fillbetween}` (if you use fill-between plots),
|
|
724
725
|
- `\usepgfplotslibrary{groupplots}` (recommended for best results, enabled by default, may be avoided by setting TikzConfig USE_GROUPPLOTS=False),
|
|
725
726
|
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False),
|
|
726
|
-
- `\usepgfplotslibrary{polar}` required for polar axis
|
|
727
|
+
- `\usepgfplotslibrary{polar}` required for polar axis,
|
|
728
|
+
- `\usetikzlibrary{patterns.meta}` for hatch patterns (available for fill_between, hist and axvspan/axhspan).
|
|
727
729
|
|
|
728
730
|
Export using `plt.savefig("example_graph.tex")` (recommended) or `plt.show()`.
|
|
729
731
|
Then use the generated file as `\input{example_graph.tex}`.
|
|
@@ -768,7 +770,7 @@ If axes and plot have different name for command with same effect, both are impl
|
|
|
768
770
|
There is a limited support for built-in styles (e.g. `plt.style.use("default")`), you may also define your own style using `plt.style.set_profile()`. Currently supported features are: color cycle (hex colors sequence), line width (in pt), grid (with matplotlib kwargs), background (latex style key=value), additional settings (raw latex code for optional arguments to axis: key=value).
|
|
769
771
|
|
|
770
772
|
#### Supported common **kwargs
|
|
771
|
-
- `color/c
|
|
773
|
+
- `color/c`,
|
|
772
774
|
- `linestyle/ls`,
|
|
773
775
|
- `linewidth/ls`,
|
|
774
776
|
- `fmt`,
|
|
@@ -790,6 +792,7 @@ For plot configurations (default sizes, paddings, etc.), use `from tikzplot impo
|
|
|
790
792
|
Currently supported parameters are listed with their default values in `src/tikzplot/config.py`.
|
|
791
793
|
|
|
792
794
|
## More features coming soon...
|
|
795
|
+
- bar plots,
|
|
793
796
|
- more developed styles,
|
|
794
797
|
- improved 3D plots (currently only basic support: plot, errorbar, fill_between, scatter, plot_wireframe, plot_surface),
|
|
795
798
|
- ...
|
|
@@ -15,13 +15,15 @@ Alternativley, download this package and install using: `pip install [path]`, wh
|
|
|
15
15
|
Instead of using `import matplotlib.pyplot (as plt)`, use `import tikzplot.plots (as plt)`.
|
|
16
16
|
|
|
17
17
|
## LaTeX requirements
|
|
18
|
+
All required packages are automatically detected and can be printed at save using kwarg `print_requirements=True` (for standalone files, preambule is automatically added).
|
|
18
19
|
- `\usepackage{tikz}`,
|
|
19
20
|
- `\usepackage{pgfplots}`,
|
|
20
21
|
- `\pgfplotsset{compat=1.18}` (may be lower, but compilation is not guaranteed),
|
|
21
22
|
- `\usepgfplotslibrary{fillbetween}` (if you use fill-between plots),
|
|
22
23
|
- `\usepgfplotslibrary{groupplots}` (recommended for best results, enabled by default, may be avoided by setting TikzConfig USE_GROUPPLOTS=False),
|
|
23
24
|
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False),
|
|
24
|
-
- `\usepgfplotslibrary{polar}` required for polar axis
|
|
25
|
+
- `\usepgfplotslibrary{polar}` required for polar axis,
|
|
26
|
+
- `\usetikzlibrary{patterns.meta}` for hatch patterns (available for fill_between, hist and axvspan/axhspan).
|
|
25
27
|
|
|
26
28
|
Export using `plt.savefig("example_graph.tex")` (recommended) or `plt.show()`.
|
|
27
29
|
Then use the generated file as `\input{example_graph.tex}`.
|
|
@@ -66,7 +68,7 @@ If axes and plot have different name for command with same effect, both are impl
|
|
|
66
68
|
There is a limited support for built-in styles (e.g. `plt.style.use("default")`), you may also define your own style using `plt.style.set_profile()`. Currently supported features are: color cycle (hex colors sequence), line width (in pt), grid (with matplotlib kwargs), background (latex style key=value), additional settings (raw latex code for optional arguments to axis: key=value).
|
|
67
69
|
|
|
68
70
|
#### Supported common **kwargs
|
|
69
|
-
- `color/c
|
|
71
|
+
- `color/c`,
|
|
70
72
|
- `linestyle/ls`,
|
|
71
73
|
- `linewidth/ls`,
|
|
72
74
|
- `fmt`,
|
|
@@ -88,6 +90,7 @@ For plot configurations (default sizes, paddings, etc.), use `from tikzplot impo
|
|
|
88
90
|
Currently supported parameters are listed with their default values in `src/tikzplot/config.py`.
|
|
89
91
|
|
|
90
92
|
## More features coming soon...
|
|
93
|
+
- bar plots,
|
|
91
94
|
- more developed styles,
|
|
92
95
|
- improved 3D plots (currently only basic support: plot, errorbar, fill_between, scatter, plot_wireframe, plot_surface),
|
|
93
96
|
- ...
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tikzplot42"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.7"
|
|
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" }
|
|
@@ -138,7 +138,7 @@ class BaseAxes:
|
|
|
138
138
|
return self._plot(y,x,settings={"xcomb": None}, **kwargs)
|
|
139
139
|
|
|
140
140
|
def fill_between(self, x, y1, y2=None, **kwargs):
|
|
141
|
-
kws = {"fmt", "alpha", "color", "c", "label"}
|
|
141
|
+
kws = {"fmt", "alpha", "color", "c", "label", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"}
|
|
142
142
|
kwargs = self._check_kwargs("fill_between", kws, **kwargs)
|
|
143
143
|
def _check_instance(xs, ys, pname):
|
|
144
144
|
for el in self._elements:
|
|
@@ -147,6 +147,7 @@ class BaseAxes:
|
|
|
147
147
|
else:
|
|
148
148
|
return None
|
|
149
149
|
assert self._fig is not None
|
|
150
|
+
self._fig._add_required_package("\\usepgfplotslibrary{fillbetween}")
|
|
150
151
|
name1 = self._fig._get_free_path_name()
|
|
151
152
|
name2 = self._fig._get_free_path_name()
|
|
152
153
|
if isinstance(y1, (int, float)):
|
|
@@ -222,7 +223,7 @@ class BaseAxes:
|
|
|
222
223
|
self._plot([xs[i]]*2, [ymins[i], ymaxs[i]], None, None, None, c=colorss[i], ls=lss[i])
|
|
223
224
|
|
|
224
225
|
def hist(self, x, bins=10, density=False,**kwargs):
|
|
225
|
-
kws = {"alpha", "color", "c", "label", "facecolor", "fc", "edgecolor", "ec", "orientation", "rwidth", "cumulative", "range", "histtype", "weights", "cumulative", "align", "stacked", "fill"}
|
|
226
|
+
kws = {"alpha", "color", "c", "label", "facecolor", "fc", "edgecolor", "ec", "orientation", "rwidth", "cumulative", "range", "histtype", "weights", "cumulative", "align", "stacked", "fill", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"}
|
|
226
227
|
kwargs = self._check_kwargs("hist", kws, **kwargs)
|
|
227
228
|
if isinstance(x, (list, tuple)) and len(x) > 0 and isinstance(x[0], (list, tuple, _np.ndarray)):
|
|
228
229
|
try:
|
|
@@ -246,7 +247,7 @@ class BaseAxes:
|
|
|
246
247
|
|
|
247
248
|
stack = kwargs.pop("stacked", False)
|
|
248
249
|
datas = {}
|
|
249
|
-
for kw in ["color", "c", "facecolor", "fc", "edgecolor", "ec", "label"]:
|
|
250
|
+
for kw in ["color", "c", "facecolor", "fc", "edgecolor", "ec", "label", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"]:
|
|
250
251
|
if kw in kwargs:
|
|
251
252
|
if isinstance(kwargs[kw], (list)):
|
|
252
253
|
if len(kwargs[kw]) != len(datasets):
|
|
@@ -299,17 +300,29 @@ class BaseAxes:
|
|
|
299
300
|
old_counts = _np.zeros(len(edges), dtype=_np.float64)
|
|
300
301
|
totals, _ = _np.histogram(all_data, edges, density=False, weights=kwargs.get("weights", None), range=kwargs.get("range", None))
|
|
301
302
|
tot_sum = totals.sum()
|
|
303
|
+
align_offset = 0
|
|
304
|
+
if "align" in kwargs:
|
|
305
|
+
if kwargs["align"] not in ["left", "mid", "right"]:
|
|
306
|
+
raise Warning(f"Invalid align value: {kwargs['align']}. Must be 'left', 'mid', or 'right'.")
|
|
307
|
+
if kwargs["align"] == "left":
|
|
308
|
+
align_offset = -widths.mean()/2
|
|
309
|
+
elif kwargs["align"] == "mid":
|
|
310
|
+
align_offset = 0
|
|
311
|
+
elif kwargs["align"] == "right":
|
|
312
|
+
align_offset = widths.mean()/2
|
|
302
313
|
for i in range(len(datasets)):
|
|
303
314
|
data = datasets[i]
|
|
304
315
|
settings = base_settings.copy()
|
|
305
316
|
kws = datas.get(i, {})
|
|
306
317
|
if "label" in kws:
|
|
307
|
-
if "xbar" in settings
|
|
318
|
+
if "xbar" in settings:
|
|
308
319
|
settings["xbar legend"] = None
|
|
309
|
-
|
|
320
|
+
elif "xbar interval" in settings:
|
|
321
|
+
settings["xbar interval legend"] = None
|
|
322
|
+
elif "ybar" in settings:
|
|
310
323
|
settings["ybar legend"] = None
|
|
311
|
-
|
|
312
|
-
|
|
324
|
+
else:
|
|
325
|
+
settings["ybar interval legend"] = None
|
|
313
326
|
fill = kws.pop("facecolor", kws.pop("fc", kws.pop("color", kws.pop("c", None))))
|
|
314
327
|
draw = kws.pop("edgecolor", kws.pop("ec", None))
|
|
315
328
|
if fill:
|
|
@@ -325,7 +338,7 @@ class BaseAxes:
|
|
|
325
338
|
if "rwidth" in kwargs:
|
|
326
339
|
xs = [edges[0] + widths[0]*(1-kwargs["rwidth"])/2]
|
|
327
340
|
new_counts = []
|
|
328
|
-
for j in range(len(widths)):
|
|
341
|
+
for j in range(len(widths)):
|
|
329
342
|
xs.append(xs[-1] + widths[j]*kwargs["rwidth"])
|
|
330
343
|
new_counts.append(counts[j])
|
|
331
344
|
if j < len(counts)-1:
|
|
@@ -339,6 +352,7 @@ class BaseAxes:
|
|
|
339
352
|
xs = (edges[:-1] + edges[1:]) / 2
|
|
340
353
|
if offset > 0:
|
|
341
354
|
settings["bar shift"] = f"{offset*(i - len(datasets)/2 + 0.5)}"
|
|
355
|
+
xs = xs + align_offset * _np.ones_like(xs)
|
|
342
356
|
if "cumulative" in kwargs and kwargs["cumulative"]:
|
|
343
357
|
counts = _np.cumsum(counts)
|
|
344
358
|
if stack:
|
|
@@ -386,7 +400,7 @@ class BaseAxes:
|
|
|
386
400
|
self._plot((xmin, xmax), y, settings={"axhline": None}, **kwargs)
|
|
387
401
|
|
|
388
402
|
def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
|
|
389
|
-
kws = {"c", "color", "alpha", "label"}
|
|
403
|
+
kws = {"c", "color", "alpha", "label", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"}
|
|
390
404
|
kwargs = self._check_kwargs("axvspan", kws, **kwargs)
|
|
391
405
|
self._ext_ymin = self._ext_ymax = True
|
|
392
406
|
if TikzConfig.USE_GROUPPLOTS:
|
|
@@ -394,7 +408,7 @@ class BaseAxes:
|
|
|
394
408
|
self._plot([xmin, xmax], [ymin, ymax], settings={"axvspan": None}, **kwargs)
|
|
395
409
|
|
|
396
410
|
def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
|
|
397
|
-
kws = {"c", "color", "alpha", "label"}
|
|
411
|
+
kws = {"c", "color", "alpha", "label", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"}
|
|
398
412
|
kwargs = self._check_kwargs("axhspan", kws, **kwargs)
|
|
399
413
|
if isinstance(self, Secondary):
|
|
400
414
|
self._primary._ext_xmin = self._primary._ext_xmax = True
|
|
@@ -989,6 +1003,8 @@ class Axes(BaseAxes):
|
|
|
989
1003
|
def _to_tex(self, filename, single):
|
|
990
1004
|
lines = []
|
|
991
1005
|
lines2 = []
|
|
1006
|
+
if self._polar:
|
|
1007
|
+
self._fig._add_required_package("\\usepgfplotslibrary{polar}")
|
|
992
1008
|
if self._polar and TikzConfig.USE_GROUPPLOTS and not single:
|
|
993
1009
|
lines.append(f"\\nextgroupplot[alias={self._axis_options['alias']}, width={self._width}, height={self._height}, hide axis]")
|
|
994
1010
|
lines2.append("\\begin{polaraxis}")
|
|
@@ -7,6 +7,7 @@ ColorLike = Union[str, Sequence[float], Sequence[Sequence[float] | ArrayLike], n
|
|
|
7
7
|
LineStyle = Literal["-", "--", "-.", ":", "solid", "dashed", "dashdot", "none", ""]
|
|
8
8
|
MarkerStyle = Literal["o", "s", "^", "v", "x", "+", ".", "*", "None", ""]
|
|
9
9
|
FontSize = Literal["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"]
|
|
10
|
+
HatchStyle = Literal["/", "\\", "|", "-", "+", "x", ".", "*"]
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class BaseAxes:
|
|
@@ -190,7 +191,12 @@ class BaseAxes:
|
|
|
190
191
|
y2: Optional[ArrayLike] = ...,
|
|
191
192
|
alpha: Optional[float] = ...,
|
|
192
193
|
color: Optional[ColorLike] = ...,
|
|
193
|
-
c: Optional[ColorLike] =
|
|
194
|
+
c: Optional[ColorLike] = ...,
|
|
195
|
+
label: Optional[str] = ...,
|
|
196
|
+
hatch: Optional[str] = ...,
|
|
197
|
+
hatch_color: Optional[ColorLike] = ...,
|
|
198
|
+
hatch_linewidth: Optional[float] = ...,
|
|
199
|
+
hatch_distance: Optional[float] = ...,
|
|
194
200
|
) -> None:
|
|
195
201
|
"""
|
|
196
202
|
Fill space between two plots (or a single plot and x-axis).
|
|
@@ -209,6 +215,17 @@ class BaseAxes:
|
|
|
209
215
|
label: str, optional
|
|
210
216
|
Legend entry
|
|
211
217
|
|
|
218
|
+
hatch: str, optional
|
|
219
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
220
|
+
|
|
221
|
+
hatch_color: ColorLike, optional
|
|
222
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
223
|
+
|
|
224
|
+
hatch_linewidth: float, optional
|
|
225
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
226
|
+
|
|
227
|
+
hatch_distance: float, optional
|
|
228
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
212
229
|
"""
|
|
213
230
|
...
|
|
214
231
|
|
|
@@ -293,10 +310,64 @@ class BaseAxes:
|
|
|
293
310
|
align: Literal["left", "mid", "right"] = ...,
|
|
294
311
|
stacked: bool = False,
|
|
295
312
|
fill: bool = True,
|
|
313
|
+
hatch: str = ...,
|
|
314
|
+
hatch_color: ColorLike = ...,
|
|
315
|
+
hatch_linewidth: float = ...,
|
|
316
|
+
hatch_distance: float = ...,
|
|
296
317
|
#**kwargs: Any
|
|
297
318
|
) -> None:
|
|
298
319
|
"""
|
|
299
320
|
Draw histogram to the selected axis.
|
|
321
|
+
|
|
322
|
+
Parameters
|
|
323
|
+
----------
|
|
324
|
+
x: ArrayLike or sequence of ArrayLike
|
|
325
|
+
Data to be histogrammed. If a sequence of arrays is given, each array is histogrammed separately and the result is stacked (if stacked=True) or overlaid.
|
|
326
|
+
|
|
327
|
+
bins: int or sequence of float, optional
|
|
328
|
+
Number of bins or bin edges. If an integer is given, it defines the number of equal-width bins in the given range (10 by default). If a sequence is given, it defines the bin edges, including the rightmost edge.
|
|
329
|
+
|
|
330
|
+
density: bool, optional
|
|
331
|
+
If True, the histogram is normalized to form a probability density, i.e., the area under the histogram will sum to 1. Default is False.
|
|
332
|
+
|
|
333
|
+
cumulative: bool, optional
|
|
334
|
+
If True, the histogram is cumulative, i.e., each bin will contain the sum of all previous bins. Default is False.
|
|
335
|
+
|
|
336
|
+
histtype: {"bar", "barstacked", "step", "stepfilled"}, optional
|
|
337
|
+
The type of histogram to draw. "bar" (default) draws a traditional bar histogram, "barstacked" draws a stacked bar histogram, "step" draws a line plot that represents the histogram, and "stepfilled" draws a filled step plot.
|
|
338
|
+
|
|
339
|
+
orientation: {"horizontal", "vertical"}, optional
|
|
340
|
+
The orientation of the histogram. "vertical" (default) draws vertical bars, while "horizontal" draws horizontal bars.
|
|
341
|
+
|
|
342
|
+
rwidth: float, optional
|
|
343
|
+
The relative width of the bars as a fraction of the bin width. If None (default), the bars will be drawn with full width.
|
|
344
|
+
|
|
345
|
+
range: tuple of float, optional
|
|
346
|
+
The lower and upper range of the bins. If not provided, the range is automatically determined from the data.
|
|
347
|
+
|
|
348
|
+
color, facecolor, fc, edgecolor, ec: ColorLike, optional
|
|
349
|
+
The color of the bars. Can be a single color or a sequence of colors for multiple datasets. If not provided, the default color cycle is used.
|
|
350
|
+
|
|
351
|
+
align: {"left", "mid", "right"}, optional
|
|
352
|
+
The alignment of the bars. "mid" (default) centers the bars on the bin edges, "left" aligns the left edge of the bars with the bin edges, and "right" aligns the right edge of the bars with the bin edges.
|
|
353
|
+
|
|
354
|
+
stacked: bool, optional
|
|
355
|
+
If True, multiple datasets are stacked on top of each other. Default is False.
|
|
356
|
+
|
|
357
|
+
fill: bool, optional
|
|
358
|
+
If True (default), the bars are filled. If False, only the edges of the bars are drawn.
|
|
359
|
+
|
|
360
|
+
hatch: str, optional
|
|
361
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
362
|
+
|
|
363
|
+
hatch_color: ColorLike, optional
|
|
364
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
365
|
+
|
|
366
|
+
hatch_linewidth: float, optional
|
|
367
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
368
|
+
|
|
369
|
+
hatch_distance: float, optional
|
|
370
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
300
371
|
"""
|
|
301
372
|
...
|
|
302
373
|
|
|
@@ -394,7 +465,7 @@ class BaseAxes:
|
|
|
394
465
|
Legend entry
|
|
395
466
|
"""
|
|
396
467
|
|
|
397
|
-
def axvspan(self, xmin:float, xmax:float, ymin:float=0, ymax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., label:Optional[str] = ...) -> None:
|
|
468
|
+
def axvspan(self, xmin:float, xmax:float, ymin:float=0, ymax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., label:Optional[str] = ..., hatch:Optional[str] = ..., hatch_color:Optional[ColorLike] = ..., hatch_linewidth:Optional[float] = ..., hatch_distance:Optional[float] = ...) -> None:
|
|
398
469
|
"""
|
|
399
470
|
Draw a background vertical span to the selected axis between given x coordinates.
|
|
400
471
|
|
|
@@ -414,9 +485,21 @@ class BaseAxes:
|
|
|
414
485
|
|
|
415
486
|
label: str, optional
|
|
416
487
|
Legend entry
|
|
488
|
+
|
|
489
|
+
hatch: str, optional
|
|
490
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
491
|
+
|
|
492
|
+
hatch_color: ColorLike, optional
|
|
493
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
494
|
+
|
|
495
|
+
hatch_linewidth: float, optional
|
|
496
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
497
|
+
|
|
498
|
+
hatch_distance: float, optional
|
|
499
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
417
500
|
"""
|
|
418
501
|
|
|
419
|
-
def axhspan(self, ymin:float, ymax:float, xmin:float=0, xmax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., label:Optional[str] = ...) -> None:
|
|
502
|
+
def axhspan(self, ymin:float, ymax:float, xmin:float=0, xmax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., label:Optional[str] = ..., hatch:Optional[str] = ..., hatch_color:Optional[ColorLike] = ..., hatch_linewidth:Optional[float] = ..., hatch_distance:Optional[float] = ...) -> None:
|
|
420
503
|
"""
|
|
421
504
|
Draw a background horizontal span to the selected axis between given y coordinates.
|
|
422
505
|
|
|
@@ -436,6 +519,19 @@ class BaseAxes:
|
|
|
436
519
|
|
|
437
520
|
label: str, optional
|
|
438
521
|
Legend entry
|
|
522
|
+
|
|
523
|
+
hatch: str, optional
|
|
524
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
525
|
+
|
|
526
|
+
hatch_color: ColorLike, optional
|
|
527
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
528
|
+
|
|
529
|
+
hatch_linewidth: float, optional
|
|
530
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
531
|
+
|
|
532
|
+
hatch_distance: float, optional
|
|
533
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
534
|
+
|
|
439
535
|
"""
|
|
440
536
|
|
|
441
537
|
def magnify(self, x_p: float, y_p: float, x_m: float, y_m: float, zoom: float, size: float, **kwargs) -> int:
|
|
@@ -13,6 +13,7 @@ class BaseGraph:
|
|
|
13
13
|
_COLOR_MAP = {'b':'blue', 'g':'teal', 'r':'red', 'c':'cyan', 'm':'magenta', 'y':'yellow', 'k':'black', 'w':'white', "orange":"orange", "green": "green", "cyan":"cyan", "peru": "brown", "lime": "lime", "gray": "gray", "magenta": "magetna", "purple": "violet"}
|
|
14
14
|
_LINE_MAP = {"--": "dashed", ":": "dotted", "-.": "dashdotted", "-":"solid"}
|
|
15
15
|
_MARKER_MAP = {'o':'*', ".": "*", 's':'square*', '^':'triangle', 'v':'triangle*', 'd':'diamond', '+':'+', 'x':'x', '*':'star'}
|
|
16
|
+
_HATCH_MAP = {"-": {"Lines": {"angle": 0}}, "|": {"Lines": {"angle": 90}}, "+": {"Hatch": {}}, "x": {"Hatch": {"angle": 45}}, "/": {"Lines": {"angle": 45}}, "\\": {"Lines": {"angle": 135}}, ".": {"Dots": {"angle": 45}}, "*": {"Stars": {"angle": 45}}}
|
|
16
17
|
|
|
17
18
|
_settings: dict[str, Any]
|
|
18
19
|
_style: dict[str, Any]
|
|
@@ -119,7 +120,10 @@ class BaseGraph:
|
|
|
119
120
|
c = self._style.get("c", self._style.get("color"))
|
|
120
121
|
sel_col = match_color(c)
|
|
121
122
|
if sel_col:
|
|
122
|
-
|
|
123
|
+
if "axhspan" in self._settings or "axvspan" in self._settings:
|
|
124
|
+
opts["fill"] = f"{{{sel_col}}}"
|
|
125
|
+
else:
|
|
126
|
+
opts["color"] = f"{{{sel_col}}}"
|
|
123
127
|
|
|
124
128
|
if "ls" in self._style or "linestyle" in self._style:
|
|
125
129
|
ls = self._style.get("ls", self._style.get("linestyle"))
|
|
@@ -167,6 +171,50 @@ class BaseGraph:
|
|
|
167
171
|
opts["opacity"] = self._opacity
|
|
168
172
|
if not self._has_color and self._classic:
|
|
169
173
|
opts["color"] = f"{{{match_color(f'C{self._axes._get_defcol()}')}}}"
|
|
174
|
+
|
|
175
|
+
if "hatch" in self._style:
|
|
176
|
+
self._axes._fig._add_required_package("\\usetikzlibrary{patterns.meta}")
|
|
177
|
+
def match_hatch(input):
|
|
178
|
+
chars = list(input)
|
|
179
|
+
hatches = []
|
|
180
|
+
while chars:
|
|
181
|
+
if chars[0] in self._HATCH_MAP.keys():
|
|
182
|
+
hatches.append(self._HATCH_MAP[chars[0]])
|
|
183
|
+
chars.pop(0)
|
|
184
|
+
elif len(chars) > 1 and chars[0] + chars[1] in self._HATCH_MAP.keys():
|
|
185
|
+
hatches.append(self._HATCH_MAP[chars[0] + chars[1]])
|
|
186
|
+
chars.pop(0)
|
|
187
|
+
chars.pop(0)
|
|
188
|
+
else:
|
|
189
|
+
raise ValueError(f"Unrecognized hatch pattern {input}")
|
|
190
|
+
return hatches
|
|
191
|
+
hatch = match_hatch(self._style["hatch"])
|
|
192
|
+
hatch_args = {}
|
|
193
|
+
hatch_color = match_color(self._style.get("hatch_color", "black"))
|
|
194
|
+
if "hatch_linewidth" in self._style:
|
|
195
|
+
hatch_args["line width"] = f"{self._style['hatch_linewidth']}pt"
|
|
196
|
+
if "hatch_distance" in self._style:
|
|
197
|
+
hatch_args["distance"] = f"{self._style['hatch_distance']}"
|
|
198
|
+
opts["postaction"] = []
|
|
199
|
+
types = [list(h.keys())[0] for h in hatch]
|
|
200
|
+
duplicated_hatchs = set(k for k in types if types.count(k) > 1)
|
|
201
|
+
dhs = duplicated_hatchs.copy()
|
|
202
|
+
hatch = [h for h in hatch if list(h.keys())[0] not in duplicated_hatchs or duplicated_hatchs.remove(list(h.keys())[0])]
|
|
203
|
+
for i in range(len(hatch)):
|
|
204
|
+
h = hatch[i]
|
|
205
|
+
h_type = list(h.keys())[0]
|
|
206
|
+
h_args = {"distance": 3.0} | h[h_type] | hatch_args
|
|
207
|
+
if h_type in dhs:
|
|
208
|
+
h_args["distance"] = f"{h_args.get('distance', 3.0)/2}"
|
|
209
|
+
if h_type in ["Dots", "Stars", "Hatch"]:
|
|
210
|
+
if h_type in ["Dots", "Stars"] and "line width" in h_args:
|
|
211
|
+
h_args["radius"] = f"{h_args.pop('line width')}"
|
|
212
|
+
if h_args.get("angle", 0) != 0:
|
|
213
|
+
h_args["xshift"] = f"{0.5 * float(h_args.get('distance', 0)) / np.sin(np.radians(h_args.get('angle', 0)))}"
|
|
214
|
+
else:
|
|
215
|
+
h_args["yshift"] = f"{0.5 * float(h_args.get('distance', 0)) / np.cos(np.radians(h_args.get('angle', 0)))}"
|
|
216
|
+
opts["postaction"].append(f"pattern={{{h_type}[{', '.join(f'{k}={v}' for k,v in h_args.items())}]}}, pattern color={hatch_color}")
|
|
217
|
+
|
|
170
218
|
if self._classic:
|
|
171
219
|
if isinstance(self, Graph) and (self._xerr is not None or self._yerr is not None) or (isinstance(self, Graph3) and self._zerr is not None):
|
|
172
220
|
opts["error bars/.cd"] = None
|
|
@@ -206,7 +254,16 @@ class BaseGraph:
|
|
|
206
254
|
self._p_dict[i] = self._st_dict[st]
|
|
207
255
|
opts["point meta"] = "explicit symbolic"
|
|
208
256
|
opts["scatter/classes"] = f"{{\n" + ',\n'.join(f"{v}={{{k}}}" for k,v in self._st_dict.items()) + "\n}"
|
|
209
|
-
self._style_str = "
|
|
257
|
+
self._style_str = ""
|
|
258
|
+
for o in opts:
|
|
259
|
+
if opts[o] is None:
|
|
260
|
+
self._style_str += f"{o},\n"
|
|
261
|
+
elif isinstance(opts[o], list):
|
|
262
|
+
for q in opts[o]:
|
|
263
|
+
self._style_str += f"{o}={{{q}}},\n"
|
|
264
|
+
else:
|
|
265
|
+
self._style_str += f"{o}={opts[o]},\n"
|
|
266
|
+
self._style_str.removesuffix(",\n")
|
|
210
267
|
return self._style_str
|
|
211
268
|
|
|
212
269
|
def _save_data(self, points, filename):
|
|
@@ -378,9 +435,9 @@ class Graph(BaseGraph):
|
|
|
378
435
|
rect = f"\\fill[{style}] (axis cs:{self._x[0]}, {lower}) rectangle (axis cs:{self._x[1]}, {upper});"
|
|
379
436
|
if self._label and self._axes._legend_on:
|
|
380
437
|
if label_opts:
|
|
381
|
-
rect += f"\\addlegendentry[{label_opts}]{{{self._label}}}"
|
|
438
|
+
rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry[{label_opts}]{{{self._label}}}"
|
|
382
439
|
else:
|
|
383
|
-
rect += f"\\addlegendentry{{{self._label}}}"
|
|
440
|
+
rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry{{{self._label}}}"
|
|
384
441
|
if TikzConfig.USE_GROUPPLOTS:
|
|
385
442
|
return f"\\begin{{pgfonlayer}}{{axis background}}{rect}\\end{{pgfonlayer}}"
|
|
386
443
|
return rect
|
|
@@ -393,9 +450,9 @@ class Graph(BaseGraph):
|
|
|
393
450
|
rect = f"\\fill[{style}] (axis cs:{lower}, {self._y[0]}) rectangle (axis cs:{upper}, {self._y[1]});"
|
|
394
451
|
if self._label and self._axes._legend_on:
|
|
395
452
|
if label_opts:
|
|
396
|
-
rect += f"\\addlegendentry[{label_opts}]{{{self._label}}}"
|
|
453
|
+
rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry[{label_opts}]{{{self._label}}}"
|
|
397
454
|
else:
|
|
398
|
-
rect += f"\\addlegendentry{{{self._label}}}"
|
|
455
|
+
rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry{{{self._label}}}"
|
|
399
456
|
if TikzConfig.USE_GROUPPLOTS:
|
|
400
457
|
return f"\\begin{{pgfonlayer}}{{axis background}}{rect}\\end{{pgfonlayer}}"
|
|
401
458
|
return rect
|
|
@@ -37,6 +37,8 @@ class Figure:
|
|
|
37
37
|
|
|
38
38
|
self._lims = {"xmin": {}, "xmax": {}, "ymin": {}, "ymax": {}}
|
|
39
39
|
|
|
40
|
+
self._required_packages: dict[str, int] = {} # int for priority: 0-tikz, 1-pgfplots, 2-other packages, 3-pgfplotsset, 4-tikzlibraries, 5-pgfplotslibraries
|
|
41
|
+
|
|
40
42
|
def add_subplot(self, nrows=1, ncols=1, index=1, sharex=None, sharey=None, projection=None, polar=False):
|
|
41
43
|
if projection=="3d":
|
|
42
44
|
ax = Axes3(nrows, ncols, index, self)
|
|
@@ -261,32 +263,13 @@ class Figure:
|
|
|
261
263
|
for ax in self._axes:
|
|
262
264
|
ax._reduce_points(limit)
|
|
263
265
|
|
|
264
|
-
def _to_tex(self, filename, png=False):
|
|
266
|
+
def _to_tex(self, filename, png=False, standalone=None, print_requirements=False):
|
|
265
267
|
single = self._nrows * self._ncols == 1
|
|
266
268
|
if not self._axes:
|
|
267
269
|
return ""
|
|
268
270
|
self._shared_ranges()
|
|
269
271
|
if TikzConfig.REDUCE_NUM_POINTS:
|
|
270
272
|
self._reduce_points()
|
|
271
|
-
preambule = ""
|
|
272
|
-
if TikzConfig.STANDALONE:
|
|
273
|
-
if png:
|
|
274
|
-
preambule += "\\documentclass[tikz,border=2pt,convert={density=300,outext=.png}]{standalone}\n"
|
|
275
|
-
else:
|
|
276
|
-
preambule += "\\documentclass[tikz,border=2pt]{standalone}\n"
|
|
277
|
-
preambule += "\\usepackage{tikz}\n"
|
|
278
|
-
preambule += "\\usepackage{pgfplots}\n"
|
|
279
|
-
if TikzConfig.USE_GROUPPLOTS and not single:
|
|
280
|
-
preambule += "\\usepgfplotslibrary{groupplots}\n"
|
|
281
|
-
preambule += "\\usepgfplotslibrary{fillbetween}\n"
|
|
282
|
-
preambule += "\\usepgfplotslibrary{polar}\n"
|
|
283
|
-
preambule += f"\\pgfplotsset{{compat={TikzConfig.TIKZ_COMPAT}}}\n"
|
|
284
|
-
if TikzConfig.USE_XCOLOR:
|
|
285
|
-
preambule += "\\usepackage{xcolor}\n"
|
|
286
|
-
if self._spies:
|
|
287
|
-
preambule += "\\usetikzlibrary{spy}\n"
|
|
288
|
-
preambule += "\\begin{document}\n"
|
|
289
|
-
|
|
290
273
|
lines0 = [g for g in self._globals]
|
|
291
274
|
lines = []
|
|
292
275
|
lines2 = []
|
|
@@ -319,8 +302,23 @@ class Figure:
|
|
|
319
302
|
for c in self._col_dict:
|
|
320
303
|
r,g,b=self._col_dict[c]
|
|
321
304
|
lines0.insert(1,f"\\definecolor{{{c}}}{{rgb}}{{{r:.3f}, {g:.3f}, {b:.3f}}}")
|
|
305
|
+
preambule = ""
|
|
306
|
+
stdalone = TikzConfig.STANDALONE if standalone is None else standalone
|
|
307
|
+
if stdalone:
|
|
308
|
+
if png:
|
|
309
|
+
preambule += "\\documentclass[tikz,border=2pt,convert={density=300,outext=.png}]{standalone}\n"
|
|
310
|
+
else:
|
|
311
|
+
preambule += "\\documentclass[tikz,border=2pt]{standalone}\n"
|
|
312
|
+
self._check_required_packages()
|
|
313
|
+
preambule += "\n".join(self._required_packages.keys()) + "\n"
|
|
314
|
+
preambule += "\\begin{document}\n"
|
|
315
|
+
if print_requirements and not stdalone:
|
|
316
|
+
self._check_required_packages()
|
|
317
|
+
print("Required packages:")
|
|
318
|
+
for p in self._required_packages.keys():
|
|
319
|
+
print(p)
|
|
322
320
|
fin = ""
|
|
323
|
-
if
|
|
321
|
+
if stdalone:
|
|
324
322
|
fin += "\\end{document}"
|
|
325
323
|
for k in self._lims.keys():
|
|
326
324
|
for j in self._lims[k]:
|
|
@@ -329,8 +327,8 @@ class Figure:
|
|
|
329
327
|
output = preambule + "\n" + "\n".join(lines) + "\n" + fin
|
|
330
328
|
return output
|
|
331
329
|
|
|
332
|
-
def _save(self, filename):
|
|
333
|
-
content = self._to_tex(filename)
|
|
330
|
+
def _save(self, filename, standalone=None, print_requirements=False):
|
|
331
|
+
content = self._to_tex(filename, png=False, standalone=standalone, print_requirements=print_requirements)
|
|
334
332
|
if not TikzConfig.SAVE_DATAPOINTS or (TikzConfig.SAVE_DATAPOINTS and not TikzConfig.UPDATE_DATA_ONLY):
|
|
335
333
|
with open(filename, "w", encoding="utf-8") as f:
|
|
336
334
|
f.write(content)
|
|
@@ -370,3 +368,29 @@ class Figure:
|
|
|
370
368
|
|
|
371
369
|
def tight_layout(self):
|
|
372
370
|
pass
|
|
371
|
+
|
|
372
|
+
def _add_required_package(self, package):
|
|
373
|
+
if package not in self._required_packages:
|
|
374
|
+
if package.startswith("\\usepackage"):
|
|
375
|
+
self._required_packages[package] = 2
|
|
376
|
+
elif package.startswith("\\pgfplotsset"):
|
|
377
|
+
self._required_packages[package] = 3
|
|
378
|
+
elif package.startswith("\\usetikzlibrary"):
|
|
379
|
+
self._required_packages[package] = 4
|
|
380
|
+
elif package.startswith("\\usepgfplotslibrary"):
|
|
381
|
+
self._required_packages[package] = 5
|
|
382
|
+
else:
|
|
383
|
+
self._required_packages[package] = 6
|
|
384
|
+
|
|
385
|
+
def _check_required_packages(self):
|
|
386
|
+
single = self._nrows * self._ncols == 1
|
|
387
|
+
self._required_packages["\\usepackage{tikz}"] = 0
|
|
388
|
+
self._required_packages["\\usepackage{pgfplots}"] = 1
|
|
389
|
+
if TikzConfig.USE_GROUPPLOTS and not single:
|
|
390
|
+
self._required_packages["\\usepgfplotslibrary{groupplots}"] = 5
|
|
391
|
+
self._required_packages[f"\\pgfplotsset{{compat={TikzConfig.TIKZ_COMPAT}}}"] = 3
|
|
392
|
+
if TikzConfig.USE_XCOLOR:
|
|
393
|
+
self._required_packages["\\usepackage{xcolor}"] = 2
|
|
394
|
+
if self._spies:
|
|
395
|
+
self._required_packages["\\usetikzlibrary{spy}"] = 4
|
|
396
|
+
self._required_packages = dict(sorted(self._required_packages.items(), key=lambda item: item[1]))
|
|
@@ -58,8 +58,8 @@ class Figure:
|
|
|
58
58
|
def _shared_ranges(self) -> None: ...
|
|
59
59
|
def _add_spy(self, zoom: float, size: float, **kwargs) -> int: ...
|
|
60
60
|
def _reduce_points(self) -> None: ...
|
|
61
|
-
def _to_tex(self, filename: str, png: Optional[bool]=False) -> str: ...
|
|
62
|
-
def _save(self, filename: str) -> None: ...
|
|
61
|
+
def _to_tex(self, filename: str, png: Optional[bool]=False, standalone: None | bool=None, print_requirements: bool=False) -> str: ...
|
|
62
|
+
def _save(self, filename: str, standalone: None | bool=None, print_requirements: bool=False) -> None: ...
|
|
63
63
|
def _save_image(self, filename: str) -> None: ...
|
|
64
64
|
def _get_width(self) -> float | None: ...
|
|
65
65
|
def _get_height(self) -> float | None: ...
|
|
@@ -80,3 +80,5 @@ class Figure:
|
|
|
80
80
|
Placeholder; spacings are set in TikzConfig.
|
|
81
81
|
"""
|
|
82
82
|
...
|
|
83
|
+
def _add_required_package(self, package: str) -> None: ...
|
|
84
|
+
def _check_required_packages(self) -> None: ...
|
|
@@ -258,7 +258,7 @@ def yscale( *args, **kwargs):
|
|
|
258
258
|
assert _current_axes
|
|
259
259
|
_current_axes.set_yscale(*args, **kwargs)
|
|
260
260
|
|
|
261
|
-
def savefig(filename):
|
|
261
|
+
def savefig(filename, standalone=None, print_requirements=False):
|
|
262
262
|
_im = False
|
|
263
263
|
if filename.endswith(".png"):
|
|
264
264
|
if not TikzConfig.STANDALONE:
|
|
@@ -273,11 +273,11 @@ def savefig(filename):
|
|
|
273
273
|
if _im:
|
|
274
274
|
_current_figure._save_image(filename)
|
|
275
275
|
else:
|
|
276
|
-
_current_figure._save(filename)
|
|
276
|
+
_current_figure._save(filename, standalone=standalone, print_requirements=print_requirements)
|
|
277
277
|
|
|
278
|
-
def show():
|
|
278
|
+
def show(standalone=None, print_requirements=False):
|
|
279
279
|
assert _current_figure
|
|
280
|
-
_current_figure._save(f"{str(main_name()[1]).removesuffix('.py')}_{TikzConfig.SHOW_SAVENAME}{next_show_num()}.tex")
|
|
280
|
+
_current_figure._save(f"{str(main_name()[1]).removesuffix('.py')}_{TikzConfig.SHOW_SAVENAME}{next_show_num()}.tex", standalone=standalone, print_requirements=print_requirements)
|
|
281
281
|
clf()
|
|
282
282
|
|
|
283
283
|
def clf():
|
|
@@ -401,26 +401,43 @@ def fill_between(
|
|
|
401
401
|
y2: Optional[ArrayLike] = ...,
|
|
402
402
|
alpha: Optional[float] = ...,
|
|
403
403
|
color: Optional[ColorLike] = ...,
|
|
404
|
-
c: Optional[ColorLike] =
|
|
404
|
+
c: Optional[ColorLike] = ...,
|
|
405
|
+
label: Optional[str] = ...,
|
|
406
|
+
hatch: Optional[str] = ...,
|
|
407
|
+
hatch_color: Optional[ColorLike] = ...,
|
|
408
|
+
hatch_linewidth: Optional[float] = ...,
|
|
409
|
+
hatch_distance: Optional[float] = ...,
|
|
405
410
|
) -> None:
|
|
406
411
|
"""
|
|
407
412
|
Fill space between two plots (or a single plot and x-axis).
|
|
413
|
+
|
|
408
414
|
Parameters
|
|
409
415
|
----------
|
|
410
416
|
x,y1, y2 : ArrayLike or float (y2 optional)
|
|
411
417
|
Datapoints, if matched with existing plot, that line will be recycled to save tikz memory.
|
|
412
|
-
|
|
418
|
+
|
|
413
419
|
alpha: float, optional
|
|
414
420
|
Opacity
|
|
415
|
-
|
|
421
|
+
|
|
416
422
|
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
417
423
|
Fill color: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
418
424
|
|
|
419
425
|
label: str, optional
|
|
420
426
|
Legend entry
|
|
427
|
+
|
|
428
|
+
hatch: str, optional
|
|
429
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
430
|
+
|
|
431
|
+
hatch_color: ColorLike, optional
|
|
432
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
433
|
+
|
|
434
|
+
hatch_linewidth: float, optional
|
|
435
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
436
|
+
|
|
437
|
+
hatch_distance: float, optional
|
|
438
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
421
439
|
"""
|
|
422
440
|
...
|
|
423
|
-
|
|
424
441
|
def text(self, x: float, y: float, s: str, color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ..., fontsize: Optional[FontSize] = ..., on_top: Optional[bool] = ..., size: Optional[FontSize] = ..., backgroundcolor: Optional[ColorLike] = ..., horizontalalignment: Optional[str] = ..., ha: Optional[str] = ..., verticalalignment: Optional[str] = ..., va: Optional[str] = ..., rotation: Optional[Union[float, str]] = ..., label: Optional[str] = ...) -> None:
|
|
425
442
|
"""
|
|
426
443
|
Add text to the selected axis.
|
|
@@ -501,18 +518,81 @@ def loglog(self, x: ArrayLike = ..., y: ArrayLike = ..., base: Optional[float] =
|
|
|
501
518
|
def hist(
|
|
502
519
|
self,
|
|
503
520
|
x: Union[ArrayLike, Sequence[ArrayLike]],
|
|
504
|
-
bins: int =
|
|
505
|
-
density: bool = ...,
|
|
521
|
+
bins: int | Sequence[float] = 10,
|
|
506
522
|
*,
|
|
507
|
-
|
|
523
|
+
weight: ArrayLike | None = None,
|
|
524
|
+
density: bool = False,
|
|
525
|
+
cumulative: bool = False,
|
|
526
|
+
histtype: Literal["bar", "barstacked", "step", "stepfilled"] = "bar",
|
|
508
527
|
orientation: Literal["horizontal","vertical"] = "vertical",
|
|
509
|
-
rwidth:
|
|
510
|
-
range:
|
|
511
|
-
color:
|
|
512
|
-
|
|
513
|
-
|
|
528
|
+
rwidth: float | None = None,
|
|
529
|
+
range: Tuple[float,float] | None = None,
|
|
530
|
+
color: ColorLike = ...,
|
|
531
|
+
facecolor: ColorLike = ...,
|
|
532
|
+
fc: ColorLike = ...,
|
|
533
|
+
edgecolor: ColorLike = ...,
|
|
534
|
+
ec: ColorLike = ...,
|
|
535
|
+
align: Literal["left", "mid", "right"] = ...,
|
|
536
|
+
stacked: bool = False,
|
|
537
|
+
fill: bool = True,
|
|
538
|
+
hatch: str | None = None,
|
|
539
|
+
hatch_color: ColorLike | None = None,
|
|
540
|
+
hatch_linewidth: float | None = None,
|
|
541
|
+
hatch_distance: float | None = None,
|
|
542
|
+
#kwargs: Any,
|
|
543
|
+
) -> None:
|
|
514
544
|
"""
|
|
515
545
|
Draw histogram to the selected axis.
|
|
546
|
+
|
|
547
|
+
Parameters
|
|
548
|
+
----------
|
|
549
|
+
x: ArrayLike or sequence of ArrayLike
|
|
550
|
+
Data to be histogrammed. If a sequence of arrays is given, each array is histogrammed separately and the result is stacked (if stacked=True) or overlaid.
|
|
551
|
+
|
|
552
|
+
bins: int or sequence of float, optional
|
|
553
|
+
Number of bins or bin edges. If an integer is given, it defines the number of equal-width bins in the given range (10 by default). If a sequence is given, it defines the bin edges, including the rightmost edge.
|
|
554
|
+
|
|
555
|
+
density: bool, optional
|
|
556
|
+
If True, the histogram is normalized to form a probability density, i.e., the area under the histogram will sum to 1. Default is False.
|
|
557
|
+
|
|
558
|
+
cumulative: bool, optional
|
|
559
|
+
If True, the histogram is cumulative, i.e., each bin will contain the sum of all previous bins. Default is False.
|
|
560
|
+
|
|
561
|
+
histtype: {"bar", "barstacked", "step", "stepfilled"}, optional
|
|
562
|
+
The type of histogram to draw. "bar" (default) draws a traditional bar histogram, "barstacked" draws a stacked bar histogram, "step" draws a line plot that represents the histogram, and "stepfilled" draws a filled step plot.
|
|
563
|
+
|
|
564
|
+
orientation: {"horizontal", "vertical"}, optional
|
|
565
|
+
The orientation of the histogram. "vertical" (default) draws vertical bars, while "horizontal" draws horizontal bars.
|
|
566
|
+
|
|
567
|
+
rwidth: float, optional
|
|
568
|
+
The relative width of the bars as a fraction of the bin width. If None (default), the bars will be drawn with full width.
|
|
569
|
+
|
|
570
|
+
range: tuple of float, optional
|
|
571
|
+
The lower and upper range of the bins. If not provided, the range is automatically determined from the data.
|
|
572
|
+
|
|
573
|
+
color, facecolor, fc, edgecolor, ec: ColorLike, optional
|
|
574
|
+
The color of the bars. Can be a single color or a sequence of colors for multiple datasets. If not provided, the default color cycle is used.
|
|
575
|
+
|
|
576
|
+
align: {"left", "mid", "right"}, optional
|
|
577
|
+
The alignment of the bars. "mid" (default) centers the bars on the bin edges, "left" aligns the left edge of the bars with the bin edges, and "right" aligns the right edge of the bars with the bin edges.
|
|
578
|
+
|
|
579
|
+
stacked: bool, optional
|
|
580
|
+
If True, multiple datasets are stacked on top of each other. Default is False.
|
|
581
|
+
|
|
582
|
+
fill: bool, optional
|
|
583
|
+
If True (default), the bars are filled. If False, only the edges of the bars are drawn.
|
|
584
|
+
|
|
585
|
+
hatch: str, optional
|
|
586
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
587
|
+
|
|
588
|
+
hatch_color: ColorLike, optional
|
|
589
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
590
|
+
|
|
591
|
+
hatch_linewidth: float, optional
|
|
592
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
593
|
+
|
|
594
|
+
hatch_distance: float, optional
|
|
595
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
516
596
|
"""
|
|
517
597
|
...
|
|
518
598
|
|
|
@@ -708,7 +788,7 @@ def axhline(self, y:float, xmin:float=0, xmax:float=1, alpha:Optional[float] = .
|
|
|
708
788
|
"""
|
|
709
789
|
...
|
|
710
790
|
|
|
711
|
-
def axvspan(self, xmin:float, xmax:float, ymin:float=0, ymax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., linestyle:Optional[str] = ..., linewidth:Optional[float] = ..., label:Optional[str] = ...) -> None:
|
|
791
|
+
def axvspan(self, xmin:float, xmax:float, ymin:float=0, ymax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., linestyle:Optional[str] = ..., linewidth:Optional[float] = ..., label:Optional[str] = ..., hatch:Optional[str] = ..., hatch_color:Optional[ColorLike] = ..., hatch_linewidth:Optional[float] = ..., hatch_distance:Optional[float] = ...) -> None:
|
|
712
792
|
"""
|
|
713
793
|
Draw a vertical span to the selected axis between given x coordinates.
|
|
714
794
|
|
|
@@ -734,10 +814,22 @@ def axvspan(self, xmin:float, xmax:float, ymin:float=0, ymax:float=1, alpha:Opti
|
|
|
734
814
|
|
|
735
815
|
label: str, optional
|
|
736
816
|
Legend entry
|
|
817
|
+
|
|
818
|
+
hatch: str, optional
|
|
819
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
820
|
+
|
|
821
|
+
hatch_color: ColorLike, optional
|
|
822
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
823
|
+
|
|
824
|
+
hatch_linewidth: float, optional
|
|
825
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
826
|
+
|
|
827
|
+
hatch_distance: float, optional
|
|
828
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
737
829
|
"""
|
|
738
830
|
...
|
|
739
831
|
|
|
740
|
-
def axhspan(self, ymin:float, ymax:float, xmin:float=0, xmax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., linestyle:Optional[str] = ..., linewidth:Optional[float] = ..., label:Optional[str] = ...) -> None:
|
|
832
|
+
def axhspan(self, ymin:float, ymax:float, xmin:float=0, xmax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., linestyle:Optional[str] = ..., linewidth:Optional[float] = ..., label:Optional[str] = ..., hatch:Optional[str] = ..., hatch_color:Optional[ColorLike] = ..., hatch_linewidth:Optional[float] = ..., hatch_distance:Optional[float] = ...) -> None:
|
|
741
833
|
"""
|
|
742
834
|
Draw a horizontal span to the selected axis between given y coordinates.
|
|
743
835
|
|
|
@@ -763,6 +855,18 @@ def axhspan(self, ymin:float, ymax:float, xmin:float=0, xmax:float=1, alpha:Opti
|
|
|
763
855
|
|
|
764
856
|
label: str, optional
|
|
765
857
|
Legend entry
|
|
858
|
+
|
|
859
|
+
hatch: str, optional
|
|
860
|
+
The hatch pattern to use for filling the bars. Can be a string of characters that define the hatch pattern (e.g., '/', '\\', '|', '-', '+', 'x', '.', '*'). If not provided, no hatching is applied.
|
|
861
|
+
|
|
862
|
+
hatch_color: ColorLike, optional
|
|
863
|
+
The color of the hatch pattern. If not provided, the default color cycle is used.
|
|
864
|
+
|
|
865
|
+
hatch_linewidth: float, optional
|
|
866
|
+
The line width of the hatch pattern in points. If not provided, the default line width is used.
|
|
867
|
+
|
|
868
|
+
hatch_distance: float, optional
|
|
869
|
+
The distance between hatch lines in points. If not provided, the default distance is used.
|
|
766
870
|
"""
|
|
767
871
|
...
|
|
768
872
|
|
|
@@ -777,18 +881,36 @@ def minorticks_num(self, num: int) -> None:
|
|
|
777
881
|
Number of minor ticks between major ticks.
|
|
778
882
|
"""
|
|
779
883
|
|
|
780
|
-
def savefig(filename: str) -> None:
|
|
884
|
+
def savefig(filename: str, standalone: None | bool = None, print_requirements: bool = False) -> None:
|
|
781
885
|
"""
|
|
782
886
|
Save figure to .tex/.tikz file.
|
|
783
887
|
|
|
784
888
|
If no suitable extension is provided, '.tex' is appended. If using .png extension, the code generated will compile to a .png image.
|
|
889
|
+
|
|
890
|
+
Parameters
|
|
891
|
+
----------
|
|
892
|
+
filename: str
|
|
893
|
+
Name of the file to save the figure to. If no suitable extension is provided, '.tex' is appended. If using .png extension, the code generated will compile to a .png image.
|
|
894
|
+
|
|
895
|
+
standalone: bool, optional
|
|
896
|
+
If True, the generated .tex file will be a standalone document. If False, it will be a fragment that can be included in another document. If None (default), the behavior is determined by the global setting `TikzConfig.STANDALONE`.
|
|
897
|
+
|
|
898
|
+
print_requirements: bool, optional
|
|
899
|
+
If True, the required LaTeX packages will be printed to the console. Inhibited for standalone.
|
|
785
900
|
"""
|
|
786
901
|
...
|
|
787
902
|
|
|
788
|
-
def show() -> None:
|
|
903
|
+
def show(standalone: None | bool = None, print_requirements: bool = False) -> None:
|
|
789
904
|
"""
|
|
790
905
|
Save figure to autogenerated filename and clear it.
|
|
791
|
-
|
|
906
|
+
|
|
907
|
+
Parameters
|
|
908
|
+
----------
|
|
909
|
+
standalone: bool, optional
|
|
910
|
+
If True, the generated .tex file will be a standalone document. If False, it will be a fragment that can be included in another document. If None (default), the behavior is determined by the global setting `TikzConfig.STANDALONE`.
|
|
911
|
+
|
|
912
|
+
print_requirements: bool, optional
|
|
913
|
+
If True, the required LaTeX packages will be printed to the console. Inhibited for standalone."""
|
|
792
914
|
...
|
|
793
915
|
|
|
794
916
|
def clf() -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tikzplot42
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.7
|
|
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
|
|
@@ -717,13 +717,15 @@ Alternativley, download this package and install using: `pip install [path]`, wh
|
|
|
717
717
|
Instead of using `import matplotlib.pyplot (as plt)`, use `import tikzplot.plots (as plt)`.
|
|
718
718
|
|
|
719
719
|
## LaTeX requirements
|
|
720
|
+
All required packages are automatically detected and can be printed at save using kwarg `print_requirements=True` (for standalone files, preambule is automatically added).
|
|
720
721
|
- `\usepackage{tikz}`,
|
|
721
722
|
- `\usepackage{pgfplots}`,
|
|
722
723
|
- `\pgfplotsset{compat=1.18}` (may be lower, but compilation is not guaranteed),
|
|
723
724
|
- `\usepgfplotslibrary{fillbetween}` (if you use fill-between plots),
|
|
724
725
|
- `\usepgfplotslibrary{groupplots}` (recommended for best results, enabled by default, may be avoided by setting TikzConfig USE_GROUPPLOTS=False),
|
|
725
726
|
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False),
|
|
726
|
-
- `\usepgfplotslibrary{polar}` required for polar axis
|
|
727
|
+
- `\usepgfplotslibrary{polar}` required for polar axis,
|
|
728
|
+
- `\usetikzlibrary{patterns.meta}` for hatch patterns (available for fill_between, hist and axvspan/axhspan).
|
|
727
729
|
|
|
728
730
|
Export using `plt.savefig("example_graph.tex")` (recommended) or `plt.show()`.
|
|
729
731
|
Then use the generated file as `\input{example_graph.tex}`.
|
|
@@ -768,7 +770,7 @@ If axes and plot have different name for command with same effect, both are impl
|
|
|
768
770
|
There is a limited support for built-in styles (e.g. `plt.style.use("default")`), you may also define your own style using `plt.style.set_profile()`. Currently supported features are: color cycle (hex colors sequence), line width (in pt), grid (with matplotlib kwargs), background (latex style key=value), additional settings (raw latex code for optional arguments to axis: key=value).
|
|
769
771
|
|
|
770
772
|
#### Supported common **kwargs
|
|
771
|
-
- `color/c
|
|
773
|
+
- `color/c`,
|
|
772
774
|
- `linestyle/ls`,
|
|
773
775
|
- `linewidth/ls`,
|
|
774
776
|
- `fmt`,
|
|
@@ -790,6 +792,7 @@ For plot configurations (default sizes, paddings, etc.), use `from tikzplot impo
|
|
|
790
792
|
Currently supported parameters are listed with their default values in `src/tikzplot/config.py`.
|
|
791
793
|
|
|
792
794
|
## More features coming soon...
|
|
795
|
+
- bar plots,
|
|
793
796
|
- more developed styles,
|
|
794
797
|
- improved 3D plots (currently only basic support: plot, errorbar, fill_between, scatter, plot_wireframe, plot_surface),
|
|
795
798
|
- ...
|
|
@@ -13,13 +13,14 @@ ax0.hist(x, n_bins, density=True, histtype='bar', color=colors, label=colors)
|
|
|
13
13
|
ax0.legend(prop={'size': 10})
|
|
14
14
|
ax0.set_title('bars with legend')
|
|
15
15
|
|
|
16
|
-
ax1.hist(x, n_bins, density=True, histtype='bar', stacked=True)
|
|
16
|
+
ax1.hist(x, n_bins, density=True, histtype='bar', stacked=True, hatch=['+', '**', '..'], hatch_color='black', hatch_linewidth=0.7, label=["1", "2", "3"])
|
|
17
17
|
ax1.set_title('stacked bar')
|
|
18
|
+
ax1.legend()
|
|
18
19
|
|
|
19
|
-
ax2.hist(x, n_bins, histtype='step', stacked=True, fill=False)
|
|
20
|
+
ax2.hist(x, n_bins, histtype='step', stacked=True, fill=False, label=["1", "2", "3"])
|
|
20
21
|
ax2.set_title('stack step (unfilled)')
|
|
22
|
+
ax2.legend()
|
|
21
23
|
|
|
22
|
-
# Make a multiple-histogram of data-sets with different length.
|
|
23
24
|
x_multi = [np.random.randn(n) for n in [10000, 5000, 2000]]
|
|
24
25
|
ax3.hist(x_multi, n_bins, histtype='bar')
|
|
25
26
|
ax3.set_title('different sample sizes')
|
|
@@ -14,10 +14,11 @@ ax2.set_yscale("log")
|
|
|
14
14
|
ax2.step(x,y,".", ms=1,where="mid")
|
|
15
15
|
ax3.plot(y,y)
|
|
16
16
|
ax3.grid()
|
|
17
|
-
ax3.axvspan(3,50,0.1,0.8,c="b",alpha=0.3)
|
|
17
|
+
ax3.axvspan(3,50,0.1,0.8,c="b",alpha=0.3, label="span", hatch="\\", hatch_color="black")
|
|
18
|
+
ax3.legend()
|
|
18
19
|
ax4.plot(y,x)
|
|
19
20
|
ax1.set_xlabel(r"$x$")
|
|
20
21
|
ax1.set_ylabel(r"$y$")
|
|
21
22
|
ax2.grid(which="both")
|
|
22
23
|
|
|
23
|
-
plt.savefig("figure.tex")
|
|
24
|
+
plt.savefig("figure.tex", print_requirements=True)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import tikzplot.plots as plt
|
|
3
|
+
#import matplotlib.pyplot as plt
|
|
4
|
+
|
|
5
|
+
xs = np.linspace(0,5,20)
|
|
6
|
+
plt.plot(xs, xs, "b--", lw=2, label="line")
|
|
7
|
+
plt.fill_between(xs, np.sin(xs), xs, hatch=".", hatch_color="white", label="fill")
|
|
8
|
+
plt.legend()
|
|
9
|
+
plt.savefig("figure.tex")
|
tikzplot42-0.4.5/tests/test4.py
DELETED
|
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
|