tikzplot42 0.3.0__tar.gz → 0.3.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.3.0 → tikzplot42-0.3.3}/PKG-INFO +10 -3
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/README.md +9 -2
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/pyproject.toml +1 -1
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/axes.py +73 -26
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/axes.pyi +88 -6
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/axes3d.py +7 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/colorbar.py +1 -1
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/config.py +2 -1
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/config.pyi +1 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/elements.py +89 -28
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/plots.py +25 -10
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/plots.pyi +85 -19
- tikzplot42-0.3.3/src/tikzplot/texts.py +119 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot42.egg-info/PKG-INFO +10 -3
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot42.egg-info/SOURCES.txt +2 -0
- tikzplot42-0.3.3/tests/test10.py +24 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test2.py +1 -1
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test7.py +1 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/LICENSE +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/setup.cfg +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/__init__.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/__init__.pyi +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/colorbar.pyi +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/colors.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/colors.pyi +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/elements.pyi +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/figure.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/figure.pyi +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/latex_special.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/py.typed +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/state.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot/state.pyi +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot42.egg-info/dependency_links.txt +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot42.egg-info/requires.txt +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/src/tikzplot42.egg-info/top_level.txt +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test1.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test3.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test4.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test5.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test6.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test8.py +0 -0
- {tikzplot42-0.3.0 → tikzplot42-0.3.3}/tests/test9.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tikzplot42
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.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
|
|
@@ -705,6 +705,10 @@ A clean version of PltToTikz, this time as Python package. Easy to use: only rep
|
|
|
705
705
|
|
|
706
706
|
Please let me know if you find any bugs or unexpected behaviour. Examples may be found in repository under `tests/` directory.
|
|
707
707
|
|
|
708
|
+
<p align="center">
|
|
709
|
+
<img src="https://github.com/ZanAmb/TikzPlot/blob/main/tests/demo.png" width="60%">
|
|
710
|
+
</p>
|
|
711
|
+
|
|
708
712
|
# Installation
|
|
709
713
|
NEW: PyPI: `pip install tikzplot42`.
|
|
710
714
|
Alternativley, download this package and install using: `pip install [path]`, where [path] is the path to the directory, containing `pyproject.toml`.
|
|
@@ -718,7 +722,8 @@ Instead of using `import matplotlib.pyplot (as plt)`, use `import tikzplot.plots
|
|
|
718
722
|
- `\pgfplotsset{compat=1.18}` (may be lower, but compilation is not guaranteed),
|
|
719
723
|
- `\usepgfplotslibrary{fillbetween}` (if you use fill-between plots),
|
|
720
724
|
- `\usepgfplotslibrary{groupplots}` (recommended for best results, enabled by default, may be avoided by setting TikzConfig USE_GROUPPLOTS=False),
|
|
721
|
-
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False)
|
|
725
|
+
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False),
|
|
726
|
+
- `\usepgfplotslibrary{polar}` required for polar axis.
|
|
722
727
|
|
|
723
728
|
Export using `plt.savefig("example_graph.tex")` (recommended) or `plt.show()`.
|
|
724
729
|
Then use the generated file as `\input{example_graph.tex}`.
|
|
@@ -735,7 +740,9 @@ Some basic plot commands are already implemented with commonly used arguments:
|
|
|
735
740
|
- `fill-between()`,
|
|
736
741
|
- `hlines()/vlines()`,
|
|
737
742
|
- `historgam()`,
|
|
738
|
-
- `
|
|
743
|
+
- `step()`,
|
|
744
|
+
- `imshow()`,
|
|
745
|
+
- `text()`.
|
|
739
746
|
|
|
740
747
|
#### Figures
|
|
741
748
|
- `plt.figure()` (currently only to give you figure object or to set `figsize`),
|
|
@@ -3,6 +3,10 @@ A clean version of PltToTikz, this time as Python package. Easy to use: only rep
|
|
|
3
3
|
|
|
4
4
|
Please let me know if you find any bugs or unexpected behaviour. Examples may be found in repository under `tests/` directory.
|
|
5
5
|
|
|
6
|
+
<p align="center">
|
|
7
|
+
<img src="https://github.com/ZanAmb/TikzPlot/blob/main/tests/demo.png" width="60%">
|
|
8
|
+
</p>
|
|
9
|
+
|
|
6
10
|
# Installation
|
|
7
11
|
NEW: PyPI: `pip install tikzplot42`.
|
|
8
12
|
Alternativley, download this package and install using: `pip install [path]`, where [path] is the path to the directory, containing `pyproject.toml`.
|
|
@@ -16,7 +20,8 @@ Instead of using `import matplotlib.pyplot (as plt)`, use `import tikzplot.plots
|
|
|
16
20
|
- `\pgfplotsset{compat=1.18}` (may be lower, but compilation is not guaranteed),
|
|
17
21
|
- `\usepgfplotslibrary{fillbetween}` (if you use fill-between plots),
|
|
18
22
|
- `\usepgfplotslibrary{groupplots}` (recommended for best results, enabled by default, may be avoided by setting TikzConfig USE_GROUPPLOTS=False),
|
|
19
|
-
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False)
|
|
23
|
+
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False),
|
|
24
|
+
- `\usepgfplotslibrary{polar}` required for polar axis.
|
|
20
25
|
|
|
21
26
|
Export using `plt.savefig("example_graph.tex")` (recommended) or `plt.show()`.
|
|
22
27
|
Then use the generated file as `\input{example_graph.tex}`.
|
|
@@ -33,7 +38,9 @@ Some basic plot commands are already implemented with commonly used arguments:
|
|
|
33
38
|
- `fill-between()`,
|
|
34
39
|
- `hlines()/vlines()`,
|
|
35
40
|
- `historgam()`,
|
|
36
|
-
- `
|
|
41
|
+
- `step()`,
|
|
42
|
+
- `imshow()`,
|
|
43
|
+
- `text()`.
|
|
37
44
|
|
|
38
45
|
#### Figures
|
|
39
46
|
- `plt.figure()` (currently only to give you figure object or to set `figsize`),
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tikzplot42"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.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" }
|
|
@@ -2,7 +2,9 @@ import numpy as _np
|
|
|
2
2
|
import matplotlib.pyplot as _plt
|
|
3
3
|
|
|
4
4
|
from .elements import Graph
|
|
5
|
+
from .texts import Text
|
|
5
6
|
from .config import TikzConfig
|
|
7
|
+
from .colorbar import Colorbar
|
|
6
8
|
from .state import _next_imshow_num, main_name
|
|
7
9
|
from .latex_special import tex_text
|
|
8
10
|
|
|
@@ -20,6 +22,8 @@ class BaseAxes:
|
|
|
20
22
|
self._add_legend = ""
|
|
21
23
|
|
|
22
24
|
def _plot(self, x, y, settings=None, xerr=None, yerr=None, **style):
|
|
25
|
+
if not isinstance(self, Secondary) and self._polar:
|
|
26
|
+
x = _np.rad2deg(x)
|
|
23
27
|
e = Graph(self, (x, y), settings, xerr=xerr, yerr=yerr, **style)
|
|
24
28
|
self._elements.append(e)
|
|
25
29
|
return e
|
|
@@ -44,14 +48,33 @@ class BaseAxes:
|
|
|
44
48
|
return self._plot(x,y,fmt=fmt, **kwargs)
|
|
45
49
|
|
|
46
50
|
def scatter(self, x, y, *args, **kwargs):
|
|
47
|
-
kws = {"fmt", "alpha", "color", "c", "marker", "markersize", "s", "label"}
|
|
51
|
+
kws = {"fmt", "alpha", "color", "c", "marker", "markersize", "s", "label", "cmap", "vmin", "vmax"}
|
|
48
52
|
kwargs = self._check_kwargs("scatter", kws, **kwargs)
|
|
49
53
|
|
|
50
54
|
if "s" in kwargs:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
s = kwargs.pop("s")
|
|
56
|
+
if not isinstance(s, (int, float)):
|
|
57
|
+
s = [i/50 for i in s]
|
|
58
|
+
else:
|
|
59
|
+
s /= 50
|
|
60
|
+
kwargs["ms"] = s
|
|
54
61
|
|
|
62
|
+
try:
|
|
63
|
+
c = kwargs.get("c", kwargs.get("color", None))
|
|
64
|
+
if len(c) == len(x):
|
|
65
|
+
if isinstance(c[0], (int, float)):
|
|
66
|
+
if "cmap" not in kwargs:
|
|
67
|
+
kwargs["cmap"] = Colorbar(cmap="viridis", lower=min(c), upper=max(c))
|
|
68
|
+
else:
|
|
69
|
+
cmap = kwargs["cmap"]
|
|
70
|
+
if isinstance(cmap, str):
|
|
71
|
+
vmin = kwargs.pop("vmin", min(c))
|
|
72
|
+
vmax = kwargs.pop("vmax", max(c))
|
|
73
|
+
kwargs["cmap"] = Colorbar(cmap=cmap, lower=vmin, upper=vmax)
|
|
74
|
+
except: pass
|
|
75
|
+
|
|
76
|
+
return self._plot(x, y, **kwargs, ls="", settings=["scatter"])
|
|
77
|
+
|
|
55
78
|
def semilogy(self, x, y, *args, **kwargs):
|
|
56
79
|
kws = {"fmt", "base", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "marker", "markersize", "ms", "label"}
|
|
57
80
|
kwargs = self._check_kwargs("semilogy", kws, **kwargs)
|
|
@@ -188,6 +211,16 @@ class BaseAxes:
|
|
|
188
211
|
counts = _np.cumsum(counts)
|
|
189
212
|
|
|
190
213
|
return self._plot(centers, counts, settings=settings, **kwargs)
|
|
214
|
+
|
|
215
|
+
def step(self, x, y, *args, **kwargs):
|
|
216
|
+
kws = {"fmt", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "marker", "markersize", "ms", "label", "where"}
|
|
217
|
+
kwargs = self._check_kwargs("step", kws, **kwargs)
|
|
218
|
+
WHERE_DICT = {"pre": "left", "post": "right", "mid": "mid"}
|
|
219
|
+
where = WHERE_DICT.get(kwargs.pop("where", "pre"), None)
|
|
220
|
+
settings = [f"const plot mark {where}"]
|
|
221
|
+
if len(args) == 1:
|
|
222
|
+
kwargs["fmt"] = args[0]
|
|
223
|
+
return self._plot(x,y,settings=settings, **kwargs)
|
|
191
224
|
|
|
192
225
|
def set_ylabel(self, label):
|
|
193
226
|
self._axis_options["ylabel"] = f"{{{tex_text(label)}}}"
|
|
@@ -292,6 +325,12 @@ class BaseAxes:
|
|
|
292
325
|
for i in range(len(labs)):
|
|
293
326
|
self._elements[i]._set_label(tex_text(labs[i]))
|
|
294
327
|
|
|
328
|
+
def text(self, x, y, s, **kwargs):
|
|
329
|
+
kws = {"alpha", "color", "c", "fontsize", "size", "backgroundcolor", "horizontalalignment", "ha", "verticalalignment", "va", "rotation", "label"}
|
|
330
|
+
kwargs = self._check_kwargs("text", kws, **kwargs)
|
|
331
|
+
txt = Text(self, x, y, s, **kwargs)
|
|
332
|
+
self._elements.append(txt)
|
|
333
|
+
|
|
295
334
|
def _add_legend_entries(self):
|
|
296
335
|
if self._add_legend == "": return ""
|
|
297
336
|
axs, labs = self._add_legend
|
|
@@ -468,7 +507,7 @@ class Axes(BaseAxes):
|
|
|
468
507
|
#kws = {"fmt", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "marker", "markersize", "ms", "label"}
|
|
469
508
|
#kwargs = self._check_kwargs("imshow", kws, **kwargs)
|
|
470
509
|
self._imshow = (args, kwargs)
|
|
471
|
-
self._axis_args.add("axis on top")
|
|
510
|
+
#self._axis_args.add("axis on top")
|
|
472
511
|
self._axis_options["enlargelimits"] = "false"
|
|
473
512
|
#self._fig._add_global("\\pgfplotsset{set layers}")
|
|
474
513
|
data = args[0]
|
|
@@ -486,7 +525,6 @@ class Axes(BaseAxes):
|
|
|
486
525
|
self._axis_options["title"] = f"{{{tex_text(title)}}}"
|
|
487
526
|
|
|
488
527
|
def grid(self, visible=True, which="major", **kwargs):
|
|
489
|
-
|
|
490
528
|
if not visible:
|
|
491
529
|
self._axis_options["grid"] = "none"
|
|
492
530
|
return
|
|
@@ -512,7 +550,7 @@ class Axes(BaseAxes):
|
|
|
512
550
|
kwargs = self._check_kwargs("grid", accepted_kwargs, **kwargs)
|
|
513
551
|
g = Graph(self, None, None, None, None, **kwargs)._style_string()
|
|
514
552
|
self._axis_options[f"{selector}grid style"] = f"{{{g}}}"
|
|
515
|
-
|
|
553
|
+
|
|
516
554
|
def set_minorticks_num(self, num):
|
|
517
555
|
self._axis_options["minor tick num"] = num
|
|
518
556
|
|
|
@@ -616,7 +654,8 @@ class Axes(BaseAxes):
|
|
|
616
654
|
if TikzConfig.SCHOOL_AXIS:
|
|
617
655
|
axis_opt_str += f",\n axis lines=middle,\n xlabel style={{at={{(ticklabel* cs:{1+TikzConfig.SCHOOL_AXIS_LABEL_MARGIN})}},anchor=north}},\n ylabel style={{at={{(ticklabel* cs:{1+TikzConfig.SCHOOL_AXIS_LABEL_MARGIN})}},anchor=east}}"
|
|
618
656
|
if TikzConfig.USE_GROUPPLOTS:
|
|
619
|
-
axis_opt_str += f",\n set layers,\n axis line style={{on layer=axis foreground}}"
|
|
657
|
+
#axis_opt_str += f",\n set layers,\n axis line style={{on layer=axis foreground}}"
|
|
658
|
+
axis_opt_str += f",\n axis on top"
|
|
620
659
|
if self._axis_options:
|
|
621
660
|
if axis_opt_str: axis_opt_str += ",\n"
|
|
622
661
|
axis_opt_str += ",\n".join(f"{k}={v}" for k, v in self._axis_options.items())
|
|
@@ -654,23 +693,31 @@ class Axes(BaseAxes):
|
|
|
654
693
|
def _to_tex(self, filename):
|
|
655
694
|
lines = []
|
|
656
695
|
lines2 = []
|
|
657
|
-
if TikzConfig.USE_GROUPPLOTS:
|
|
658
|
-
lines.append("\\nextgroupplot")
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
696
|
+
if self._polar and TikzConfig.USE_GROUPPLOTS:
|
|
697
|
+
lines.append(f"\\nextgroupplot[alias={self._axis_options['alias']}, width={self._width}, height={self._height}, hide axis]")
|
|
698
|
+
lines2.append("\\begin{polaraxis}")
|
|
699
|
+
lines2.append(f"[{self._axis_option_string()}]")
|
|
700
|
+
lines2.append(self._content_tex(filename))
|
|
701
|
+
lines2.append("\\end{polaraxis}")
|
|
702
|
+
else:
|
|
703
|
+
if TikzConfig.USE_GROUPPLOTS:
|
|
704
|
+
lines.append("\\nextgroupplot")
|
|
705
|
+
if self._polar:
|
|
706
|
+
lines.append("\\begin{polaraxis}")
|
|
707
|
+
elif not TikzConfig.USE_GROUPPLOTS:
|
|
708
|
+
lines.append("\\begin{axis}")
|
|
709
|
+
lines.append(f"[{self._axis_option_string()}]")
|
|
710
|
+
lines.append(self._content_tex(filename))
|
|
711
|
+
if self._polar:
|
|
712
|
+
lines.append("\\end{polaraxis}")
|
|
713
|
+
elif not TikzConfig.USE_GROUPPLOTS:
|
|
714
|
+
|
|
715
|
+
lines.append("\\end{axis}")
|
|
716
|
+
if self._secondary_y is not None:
|
|
717
|
+
lines2.append("\\begin{axis}")
|
|
718
|
+
lines2.append(f"[{self._secondary_y._axis_option_string()}]")
|
|
719
|
+
lines2.append(self._secondary_y._content_tex(filename))
|
|
720
|
+
lines2.append("\\end{axis}")
|
|
674
721
|
return lines, lines2
|
|
675
722
|
|
|
676
723
|
def set(self, **kwargs):
|
|
@@ -690,7 +737,7 @@ class Secondary(BaseAxes):
|
|
|
690
737
|
self._axis_options["axis x line"] = "none"
|
|
691
738
|
self._axis_options["at"] = f"{{({primary._axis_options['alias' if 'alias' in primary._axis_options else 'name']}.south west)}}"
|
|
692
739
|
self._axis_options["anchor"] = "south west"
|
|
693
|
-
self._axis_options["y label style"] = r"{at={(
|
|
740
|
+
self._axis_options["y label style"] = r"{at={(" + str(TikzConfig.SEC_YLABEL_LOC[0]) + "," + str(TikzConfig.SEC_YLABEL_LOC[1]) + ")}, rotate=180}"
|
|
694
741
|
|
|
695
742
|
self._fig = primary._fig
|
|
696
743
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
from typing import Any, Optional, Sequence, Tuple, Union, Literal
|
|
2
2
|
import numpy as np
|
|
3
|
+
from .colorbar import Colorbar
|
|
3
4
|
|
|
4
5
|
ArrayLike = Union[Sequence[float], np.ndarray]
|
|
5
6
|
ColorLike = Union[str, Sequence[float]]
|
|
6
7
|
LineStyle = Literal["-", "--", "-.", ":", "solid", "dashed", "dashdot", "none", ""]
|
|
7
8
|
MarkerStyle = Literal["o", "s", "^", "v", "x", "+", ".", "*", "None", ""]
|
|
9
|
+
FontSize = Literal["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"]
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class BaseAxes:
|
|
@@ -45,8 +47,8 @@ class BaseAxes:
|
|
|
45
47
|
"""
|
|
46
48
|
...
|
|
47
49
|
|
|
48
|
-
def scatter(self, x: ArrayLike = ..., y: ArrayLike = ..., fmt: Optional[str] = ..., *,alpha: Optional[float] = ..., color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ...,
|
|
49
|
-
marker: Optional[MarkerStyle] = ..., markersize: Optional[float] = ..., s: Optional[float] = ..., label:Optional[str]
|
|
50
|
+
def scatter(self, x: ArrayLike = ..., y: ArrayLike = ..., fmt: Optional[str] = ..., *,alpha: Optional[float] = ..., color: Optional[Union[Sequence[ColorLike], ColorLike]] = ..., c: Optional[ColorLike] = ...,
|
|
51
|
+
marker: Optional[MarkerStyle] = ..., markersize: Optional[Union[Sequence[float], float]] = ..., s: Optional[Union[Sequence[float], float]] = ..., label:Optional[str]=..., cmap: Optional[Union[str, Colorbar]], vmin: Optional[float] = ..., vmax: Optional[float] = ...) -> None:
|
|
50
52
|
"""
|
|
51
53
|
Draw a scatter plot to the selected axis.
|
|
52
54
|
|
|
@@ -61,8 +63,9 @@ class BaseAxes:
|
|
|
61
63
|
alpha: float, optional
|
|
62
64
|
Opacity
|
|
63
65
|
|
|
64
|
-
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
65
|
-
color of line and markers: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
66
|
+
color or c: array like or single: all matplotlib color formats (without X11/xkcd) or float for colormap, optional
|
|
67
|
+
color of line and markers: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible. Note that if the sequence if of the same length as x, it will be interpreted as color sequence for each point, otherwise it will be interpreted as a single color for all points.
|
|
68
|
+
|
|
66
69
|
|
|
67
70
|
label: str, optional
|
|
68
71
|
Legned entry
|
|
@@ -70,8 +73,14 @@ class BaseAxes:
|
|
|
70
73
|
marker: str, optional
|
|
71
74
|
Marker type
|
|
72
75
|
|
|
73
|
-
markersize or s: float, optional
|
|
74
|
-
Mark size in pt
|
|
76
|
+
markersize or s: ArrayLike or float, optional
|
|
77
|
+
Mark size in pt (or in 1/50 pt for s), if a sequence of same length as x, it will be interpreted as size for each point, otherwise it will be interpreted as a single size for all points.
|
|
78
|
+
|
|
79
|
+
cmap: str or Colorbar, optional
|
|
80
|
+
Colormap for scatter points, if color is given as float or sequence of floats. Can be a colormap name or a Colorbar object.
|
|
81
|
+
|
|
82
|
+
vmin, vmax: float, optional
|
|
83
|
+
Colorbar limits for scatter points, if color is given sequence of floats and cmap is given as string, otherwise ignored. If cmap is given as str and no vmin or vmax is provided, they will be set to the min and max of color sequence.
|
|
75
84
|
"""
|
|
76
85
|
...
|
|
77
86
|
def semilogy(self, x: ArrayLike = ..., y: ArrayLike = ..., base: Optional[float] = 10, fmt: Optional[str] = ...,*, alpha: Optional[float] = ..., color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ...,
|
|
@@ -202,6 +211,41 @@ class BaseAxes:
|
|
|
202
211
|
|
|
203
212
|
"""
|
|
204
213
|
...
|
|
214
|
+
|
|
215
|
+
def text(self, x: float, y: float, s: str, color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ..., fontsize: Optional[FontSize] = ..., 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:
|
|
216
|
+
"""
|
|
217
|
+
Add text to the selected axis.
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
x,y: float
|
|
222
|
+
Text position in axis coordinates
|
|
223
|
+
|
|
224
|
+
s: str
|
|
225
|
+
Text content (LaTeX format)
|
|
226
|
+
|
|
227
|
+
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
228
|
+
Text color: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
229
|
+
|
|
230
|
+
fontsize or size: FontSize, optional
|
|
231
|
+
Font size
|
|
232
|
+
|
|
233
|
+
backgroundcolor: all matplotlib color formats (without X11/xkcd), optional
|
|
234
|
+
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
|
|
235
|
+
|
|
236
|
+
horizontalalignment or ha: {"center", "left", "right"}, optional
|
|
237
|
+
Horizontal alignment of text
|
|
238
|
+
|
|
239
|
+
verticalalignment or va: {"center", "top", "bottom"}, optional
|
|
240
|
+
Vertical alignment of text
|
|
241
|
+
|
|
242
|
+
rotation: float or {"vertical", "horizontal"}, optional
|
|
243
|
+
Rotation angle in degrees or preset rotation
|
|
244
|
+
|
|
245
|
+
label: str, optional
|
|
246
|
+
Legend entry
|
|
247
|
+
"""
|
|
248
|
+
...
|
|
205
249
|
def hlines(
|
|
206
250
|
self,
|
|
207
251
|
y: Union[float, Sequence[float]],
|
|
@@ -231,6 +275,44 @@ class BaseAxes:
|
|
|
231
275
|
Draw histogram to the selected axis.
|
|
232
276
|
"""
|
|
233
277
|
...
|
|
278
|
+
|
|
279
|
+
def step(self, x: ArrayLike, y: ArrayLike, *args: Any, where: Literal["pre","post","mid"] = "pre", **kwargs: Any) -> None:
|
|
280
|
+
"""
|
|
281
|
+
Draw a step plot to the selected axis.
|
|
282
|
+
|
|
283
|
+
Parameters
|
|
284
|
+
----------
|
|
285
|
+
x,y : ArrayLike or float
|
|
286
|
+
Datapoints
|
|
287
|
+
|
|
288
|
+
where: {"pre", "post", "mid"}, default "pre"
|
|
289
|
+
Define where the steps should be placed: before the value (pre), after the value (post), or centered on the value (mid).
|
|
290
|
+
|
|
291
|
+
fmt: str, optional
|
|
292
|
+
Style
|
|
293
|
+
|
|
294
|
+
alpha: float, optional
|
|
295
|
+
Opacity
|
|
296
|
+
|
|
297
|
+
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
298
|
+
color of line and markers: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
299
|
+
|
|
300
|
+
label: str, optional
|
|
301
|
+
Legned entry
|
|
302
|
+
|
|
303
|
+
linestyle or ls: str, optional
|
|
304
|
+
Line style
|
|
305
|
+
|
|
306
|
+
linewidth or lw: float, optional
|
|
307
|
+
Line width in pt
|
|
308
|
+
|
|
309
|
+
marker: str, optional
|
|
310
|
+
Marker type
|
|
311
|
+
|
|
312
|
+
markersize or ms: float, optional
|
|
313
|
+
Mark size in pt
|
|
314
|
+
"""
|
|
315
|
+
...
|
|
234
316
|
|
|
235
317
|
def set_ylabel(self, label: str) -> None:
|
|
236
318
|
"""
|
|
@@ -2,6 +2,7 @@ import numpy as _np
|
|
|
2
2
|
import matplotlib.pyplot as _plt
|
|
3
3
|
|
|
4
4
|
from .elements import Graph3
|
|
5
|
+
from .texts import Text3
|
|
5
6
|
from .config import TikzConfig
|
|
6
7
|
#from .state import _next_imshow_num, main_name
|
|
7
8
|
from .latex_special import tex_text
|
|
@@ -193,6 +194,12 @@ class Axes3:
|
|
|
193
194
|
counts = _np.cumsum(counts)
|
|
194
195
|
|
|
195
196
|
return self._plot(centers, counts, settings=settings, **kwargs)"""
|
|
197
|
+
|
|
198
|
+
def text(self, x, y, z, s, **kwargs):
|
|
199
|
+
kws = {"alpha", "color", "c", "fontsize", "size", "backgroundcolor", "horizontalalignment", "ha", "verticalalignment", "va", "rotation", "label"}
|
|
200
|
+
kwargs = self._check_kwargs("text", kws, **kwargs)
|
|
201
|
+
txt = Text3(self, x, y, z, s, **kwargs)
|
|
202
|
+
self._elements.append(txt)
|
|
196
203
|
|
|
197
204
|
def set_title(self, title):
|
|
198
205
|
self._axis_options["title"] = f"{{{tex_text(title)}}}"
|
|
@@ -100,7 +100,7 @@ class _Colorbar:
|
|
|
100
100
|
'Spectral': [(0.6196, 0.0039, 0.2588), (0.9981, 0.9992, 0.746), (0.3686, 0.3098, 0.6353)],
|
|
101
101
|
'coolwarm': [(0.2298, 0.2987, 0.7537), (0.8674, 0.8644, 0.8626), (0.7057, 0.0156, 0.1502)],
|
|
102
102
|
'bwr': [(0.0, 0.0, 1.0), (1.0, 0.9961, 0.9961), (1.0, 0.0, 0.0)],
|
|
103
|
-
|
|
103
|
+
'seismic': [(0.0, 0.0, 0.3), (0.0, 0.0, 0.6953), (0.1451, 0.1451, 1.0), (0.7098, 0.7098, 1.0), (1.0, 0.7098, 0.7098), (1.0, 0.1451, 0.1451), (0.7824, 0.0, 0.0), (0.5, 0.0, 0.0)],
|
|
104
104
|
|
|
105
105
|
'twilight': [(0.8858, 0.85, 0.888), (0.5383, 0.678, 0.7711), (0.3732, 0.3814, 0.706), (0.2867, 0.0824, 0.3933), (0.3154, 0.0794, 0.2681), (0.6457, 0.2616, 0.3125), (0.7905, 0.5983, 0.4862), (0.8857, 0.85, 0.8857)],
|
|
106
106
|
'twilight_shifted': [(0.1874, 0.0771, 0.2162), (0.36, 0.2069, 0.6029), (0.4114, 0.5368, 0.7467), (0.7387, 0.796, 0.8214), (0.8399, 0.7604, 0.7137), (0.7388, 0.4205, 0.3491), (0.4981, 0.1357, 0.3141), (0.1849, 0.0794, 0.2131)],
|
|
@@ -21,11 +21,12 @@ class _TikzConfig:
|
|
|
21
21
|
self.X_LABEL_PADDING: float = 0.6
|
|
22
22
|
self.XTICK_PADDING: float = 0.7
|
|
23
23
|
self.YTICK_PADDING: float = 0.7
|
|
24
|
+
self.SEC_YLABEL_LOC: tuple[float, float] = (1.2, 0.5)
|
|
24
25
|
|
|
25
26
|
self.DEFAULT_WIDTH: float = 12
|
|
26
27
|
self.DEFAULT_HEIGHT: float = 10
|
|
27
28
|
|
|
28
|
-
self.SHARED_AXIS_REL_MARGIN: float = 0.
|
|
29
|
+
self.SHARED_AXIS_REL_MARGIN: float = 0.08
|
|
29
30
|
|
|
30
31
|
self.SAVE_DATAPOINTS: bool = True
|
|
31
32
|
self.DATAPOINTS_DIR: str = "datapoints" # ignored if SAVE_DATAPOINTS == False
|
|
@@ -38,7 +38,7 @@ class BaseGraph:
|
|
|
38
38
|
if self._style_str != None:
|
|
39
39
|
return self._style_str
|
|
40
40
|
opts = []
|
|
41
|
-
|
|
41
|
+
cmap = None
|
|
42
42
|
def match_ls(input):
|
|
43
43
|
if input in self._LINE_MAP.keys():
|
|
44
44
|
return self._LINE_MAP[input]
|
|
@@ -65,6 +65,10 @@ class BaseGraph:
|
|
|
65
65
|
r,g,b=ccode
|
|
66
66
|
self._axes._add_col(r,g,b)
|
|
67
67
|
return f"c{r:.3f}{g:.3f}{b:.3f}".replace(".", "")
|
|
68
|
+
|
|
69
|
+
if "scatter" in self._settings:
|
|
70
|
+
if "cmap" in self._style:
|
|
71
|
+
cmap = self._style["cmap"]
|
|
68
72
|
|
|
69
73
|
if "fmt" in self._style:
|
|
70
74
|
fmt = self._style["fmt"]
|
|
@@ -83,42 +87,38 @@ class BaseGraph:
|
|
|
83
87
|
if ls:
|
|
84
88
|
opts.append(ls)
|
|
85
89
|
|
|
86
|
-
if "c" in self._style:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if sel_col:
|
|
93
|
-
opts.append(f"color={{{sel_col}}}")
|
|
94
|
-
if "ls" in self._style:
|
|
95
|
-
ls = self._style["ls"]
|
|
96
|
-
if ls == "":
|
|
97
|
-
opts.append("only marks")
|
|
90
|
+
if "c" in self._style or "color" in self._style:
|
|
91
|
+
if "scatter" in self._settings and self._colors is not None:
|
|
92
|
+
if isinstance(self._colors[0], (int, float)):
|
|
93
|
+
self._colors = [match_color(cmap.color(p)) for p in self._colors]
|
|
94
|
+
else:
|
|
95
|
+
self._colors = [match_color(p) for p in self._colors]
|
|
98
96
|
else:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
c = self._style.get("c", self._style.get("color"))
|
|
98
|
+
sel_col = match_color(c)
|
|
99
|
+
if sel_col:
|
|
100
|
+
opts.append(f"color={{{sel_col}}}")
|
|
101
|
+
|
|
102
|
+
if "ls" in self._style or "linestyle" in self._style:
|
|
103
|
+
ls = self._style.get("ls", self._style.get("linestyle"))
|
|
104
104
|
if ls == "":
|
|
105
105
|
opts.append("only marks")
|
|
106
106
|
else:
|
|
107
107
|
sel_ls = match_ls(ls)
|
|
108
108
|
if sel_ls:
|
|
109
109
|
opts.append(sel_ls)
|
|
110
|
-
if "lw" in self._style:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
if "lw" in self._style or "linewidth" in self._style:
|
|
111
|
+
if "scatter" in self._settings:
|
|
112
|
+
lw = self._style.get("lw", self._style.get("linewidth"))
|
|
113
|
+
opts.append(f"line width={lw}pt")
|
|
114
114
|
if "marker" in self._style:
|
|
115
115
|
sel_mark = match_mark(self._style['marker'])
|
|
116
116
|
if sel_mark:
|
|
117
117
|
opts.append(f"mark={sel_mark}")
|
|
118
|
-
if "ms" in self._style:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
if "ms" in self._style or "markersize" in self._style:
|
|
119
|
+
ms = self._style.get("ms", self._style.get("markersize"))
|
|
120
|
+
if not ("scatter" in self._settings and self._sizes is not None):
|
|
121
|
+
opts.append(f"mark size={ms}pt")
|
|
122
122
|
if "markerfmt" in self._style:
|
|
123
123
|
col = list(set(self._COLOR_MAP.keys()) & set(fmt))
|
|
124
124
|
if col:
|
|
@@ -162,6 +162,20 @@ class BaseGraph:
|
|
|
162
162
|
if self._path_name: self._settings.append(f"name path={self._path_name}")
|
|
163
163
|
if self._settings:
|
|
164
164
|
opts = self._settings + opts
|
|
165
|
+
if "scatter" in self._settings and (self._colors is not None or self._sizes is not None):
|
|
166
|
+
last = 0
|
|
167
|
+
for i in range(len(self._x)):
|
|
168
|
+
st = ""
|
|
169
|
+
if self._colors is not None:
|
|
170
|
+
st = f"color={{{self._colors[i]}}},"
|
|
171
|
+
if self._sizes is not None:
|
|
172
|
+
st += f"mark size={self._sizes[i]:.9f}pt"
|
|
173
|
+
if st not in self._st_dict:
|
|
174
|
+
self._st_dict[st] = "s" + str(last+1)
|
|
175
|
+
last += 1
|
|
176
|
+
self._p_dict[i] = self._st_dict[st]
|
|
177
|
+
opts.append("point meta=explicit symbolic")
|
|
178
|
+
opts.append(f"scatter/classes={{\n" + ',\n'.join(f"{v}={{{k}}}" for k,v in self._st_dict.items()) + "\n}")
|
|
165
179
|
self._style_str = ",\n".join(str(o) for o in opts)
|
|
166
180
|
return self._style_str
|
|
167
181
|
|
|
@@ -196,12 +210,21 @@ class Graph(BaseGraph):
|
|
|
196
210
|
super().__init__()
|
|
197
211
|
self._axes = axes
|
|
198
212
|
self._classic = False
|
|
213
|
+
self._style = style
|
|
214
|
+
if settings is not None:
|
|
215
|
+
self._settings = settings
|
|
216
|
+
if "scatter" in self._settings:
|
|
217
|
+
self._st_dict = {}
|
|
218
|
+
self._p_dict = {}
|
|
219
|
+
self._colors = None
|
|
220
|
+
self._sizes = None
|
|
199
221
|
if isinstance(coordinates, tuple):
|
|
200
222
|
self._classic = True
|
|
201
223
|
x,y=coordinates
|
|
202
224
|
self._x = np.asarray(x)
|
|
203
225
|
self._y = np.asarray(y)
|
|
204
226
|
mask = np.isfinite(self._x) & np.isfinite(self._y)
|
|
227
|
+
n0 = len(self._x)
|
|
205
228
|
self._x = self._x[mask]
|
|
206
229
|
self._y = self._y[mask]
|
|
207
230
|
n = len(self._x)
|
|
@@ -212,11 +235,28 @@ class Graph(BaseGraph):
|
|
|
212
235
|
|
|
213
236
|
if self._yerr is not None:
|
|
214
237
|
self._yerr = np.asarray(self._yerr)[mask]
|
|
238
|
+
|
|
239
|
+
if "scatter" in self._settings:
|
|
240
|
+
c = self._style.get("c", self._style.get("color", None))
|
|
241
|
+
if c is not None:
|
|
242
|
+
try:
|
|
243
|
+
if len(c) == n0:
|
|
244
|
+
self._colors = np.asarray(c)[mask]
|
|
245
|
+
except: pass
|
|
246
|
+
s = self._style.get("ms", self._style.get("markersize", None))
|
|
247
|
+
if s is not None:
|
|
248
|
+
try:
|
|
249
|
+
if len(s) == n0:
|
|
250
|
+
self._sizes = np.asarray(s)[mask]
|
|
251
|
+
except: pass
|
|
252
|
+
if self._colors is None and self._sizes is None:
|
|
253
|
+
self._settings.remove("scatter")
|
|
254
|
+
else:
|
|
255
|
+
if self._colors is None:
|
|
256
|
+
self._colors = style.get("c", style.get("color", self._axes._get_defcol())) * np.ones(len(self._x))
|
|
215
257
|
else:
|
|
216
258
|
self._special = coordinates
|
|
217
|
-
self._style = style
|
|
218
259
|
self._label = None
|
|
219
|
-
self._settings = settings
|
|
220
260
|
if self._settings == None: self._settings = []
|
|
221
261
|
|
|
222
262
|
self._opacity = 1
|
|
@@ -236,6 +276,9 @@ class Graph(BaseGraph):
|
|
|
236
276
|
cols += ["yerrminus", "yerrplus"]
|
|
237
277
|
else:
|
|
238
278
|
cols.append("yerror")
|
|
279
|
+
if "scatter" in self._settings:
|
|
280
|
+
if self._p_dict:
|
|
281
|
+
cols.append("label")
|
|
239
282
|
return " ".join(cols)
|
|
240
283
|
|
|
241
284
|
def _rows(self):
|
|
@@ -252,6 +295,9 @@ class Graph(BaseGraph):
|
|
|
252
295
|
line += list(self._yerr[i])
|
|
253
296
|
else:
|
|
254
297
|
line.append(self._yerr[i])
|
|
298
|
+
if "scatter" in self._settings:
|
|
299
|
+
if self._p_dict:
|
|
300
|
+
line.append(self._p_dict[i])
|
|
255
301
|
rows.append(" ".join(str(v) for v in line))
|
|
256
302
|
return "\n".join(rows)
|
|
257
303
|
|
|
@@ -266,6 +312,8 @@ class Graph(BaseGraph):
|
|
|
266
312
|
table_opts += ",x error=xerror"
|
|
267
313
|
if self._yerr is not None:
|
|
268
314
|
table_opts += ",y error=yerror"
|
|
315
|
+
if "scatter" in self._settings and self._p_dict:
|
|
316
|
+
table_opts += ",meta=label"
|
|
269
317
|
datapoints = f"{header}\n{rows}\n"
|
|
270
318
|
if TikzConfig.SAVE_DATAPOINTS:
|
|
271
319
|
datapoints = self._save_data(datapoints, filename)
|
|
@@ -275,6 +323,8 @@ class Graph(BaseGraph):
|
|
|
275
323
|
return f"\\addplot [forget plot,\n{style}] table [{table_opts}] {{{datapoints}}};"
|
|
276
324
|
return ""
|
|
277
325
|
elif TikzConfig.SAVE_DATAPOINTS or not (TikzConfig.SAVE_DATAPOINTS and not TikzConfig.UPDATE_STYLE_ONLY):
|
|
326
|
+
if self._label and self._axes._legend_on:
|
|
327
|
+
return f"\\addplot [{style}] {self._special};\\addlegendentry{{{self._label}}}"
|
|
278
328
|
return f"\\addplot [forget plot,\n{style}] {self._special};"
|
|
279
329
|
else:
|
|
280
330
|
return ""
|
|
@@ -330,6 +380,12 @@ class Graph(BaseGraph):
|
|
|
330
380
|
if self._yerr is not None:
|
|
331
381
|
self._yerr = self._yerr[mask]
|
|
332
382
|
|
|
383
|
+
if "scatter" in self._settings:
|
|
384
|
+
if self._colors is not None:
|
|
385
|
+
self._colors = self._colors[mask]
|
|
386
|
+
if self._sizes is not None:
|
|
387
|
+
self._sizes = self._sizes[mask]
|
|
388
|
+
|
|
333
389
|
def _check_equal(self, x,y):
|
|
334
390
|
if self._classic:
|
|
335
391
|
return np.array_equal(np.asarray(x),self._x) and np.array_equal(np.asarray(y),self._y)
|
|
@@ -397,6 +453,11 @@ class Graph(BaseGraph):
|
|
|
397
453
|
self._xerr = self._xerr[mask]
|
|
398
454
|
if self._yerr is not None:
|
|
399
455
|
self._yerr = self._yerr[mask]
|
|
456
|
+
if "scatter" in self._settings:
|
|
457
|
+
if self._colors is not None:
|
|
458
|
+
self._colors = self._colors[mask]
|
|
459
|
+
if self._sizes is not None:
|
|
460
|
+
self._sizes = self._sizes[mask]
|
|
400
461
|
|
|
401
462
|
class Graph3(BaseGraph):
|
|
402
463
|
def __init__(self, axes, coordinates, settings=None, xerr=None, yerr=None, zerr=None, path_name=None, **style):
|
|
@@ -101,26 +101,26 @@ def plot(*args, **kwargs):
|
|
|
101
101
|
_ensure_axes()
|
|
102
102
|
_current_axes.plot(*args, **kwargs)
|
|
103
103
|
|
|
104
|
-
def scatter(
|
|
104
|
+
def scatter(*args, **kwargs):
|
|
105
105
|
_ensure_axes()
|
|
106
|
-
_current_axes.scatter(
|
|
106
|
+
_current_axes.scatter(*args, **kwargs)
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
def loglog(
|
|
109
|
+
def loglog(*args, **kwargs):
|
|
110
110
|
_ensure_axes()
|
|
111
|
-
_current_axes.loglog(
|
|
111
|
+
_current_axes.loglog(*args, **kwargs)
|
|
112
112
|
|
|
113
|
-
def semilogx(
|
|
113
|
+
def semilogx(*args, **kwargs):
|
|
114
114
|
_ensure_axes()
|
|
115
|
-
_current_axes.semilogx(
|
|
115
|
+
_current_axes.semilogx(*args, **kwargs)
|
|
116
116
|
|
|
117
|
-
def semilogy(
|
|
117
|
+
def semilogy(*args, **kwargs):
|
|
118
118
|
_ensure_axes()
|
|
119
|
-
_current_axes.semilogy(
|
|
119
|
+
_current_axes.semilogy(*args, **kwargs)
|
|
120
120
|
|
|
121
|
-
def errorbar(
|
|
121
|
+
def errorbar(*args, **kwargs):
|
|
122
122
|
_ensure_axes()
|
|
123
|
-
_current_axes.errorbar(
|
|
123
|
+
_current_axes.errorbar(*args, **kwargs)
|
|
124
124
|
|
|
125
125
|
def stem(*args, **kwargs):
|
|
126
126
|
_ensure_axes()
|
|
@@ -130,6 +130,10 @@ def fill_between(*args, **kwargs):
|
|
|
130
130
|
_ensure_axes()
|
|
131
131
|
_current_axes.fill_between(*args, **kwargs)
|
|
132
132
|
|
|
133
|
+
def text(*args, **kwargs):
|
|
134
|
+
_ensure_axes()
|
|
135
|
+
_current_axes.text(*args, **kwargs)
|
|
136
|
+
|
|
133
137
|
def hlines(*args, **kwargs):
|
|
134
138
|
_ensure_axes()
|
|
135
139
|
_current_axes.hlines(*args, **kwargs)
|
|
@@ -142,6 +146,14 @@ def imshow(*args, **kwargs):
|
|
|
142
146
|
_ensure_axes()
|
|
143
147
|
return _current_axes.imshow(*args, **kwargs)
|
|
144
148
|
|
|
149
|
+
def hist(*args, **kwargs):
|
|
150
|
+
_ensure_axes()
|
|
151
|
+
return _current_axes.hist(*args, **kwargs)
|
|
152
|
+
|
|
153
|
+
def step(*args, **kwargs):
|
|
154
|
+
_ensure_axes()
|
|
155
|
+
return _current_axes.step(*args, **kwargs)
|
|
156
|
+
|
|
145
157
|
def xticks(*args, **kwargs):
|
|
146
158
|
_ensure_axes()
|
|
147
159
|
_current_axes.set_xticks(*args, **kwargs)
|
|
@@ -173,3 +185,6 @@ def clf():
|
|
|
173
185
|
def gca():
|
|
174
186
|
_ensure_axes()
|
|
175
187
|
return _current_axes
|
|
188
|
+
|
|
189
|
+
def tight_layout():
|
|
190
|
+
pass
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
from typing import Any, Optional, Tuple, Union, Sequence, Literal
|
|
4
4
|
import numpy as np
|
|
5
5
|
|
|
6
|
-
from .config import TikzConfig
|
|
6
|
+
from .config import TikzConfig
|
|
7
|
+
from .colorbar import Colorbar
|
|
7
8
|
from .figure import Figure as Figure
|
|
8
9
|
from .state import main_name as main_name, next_show_num as next_show_num
|
|
9
10
|
from .axes import Axes
|
|
@@ -12,6 +13,7 @@ ArrayLike = Union[Sequence[float], np.ndarray]
|
|
|
12
13
|
ColorLike = Union[str, Sequence[float]]
|
|
13
14
|
LineStyle = Literal["-", "--", "-.", ":", "solid", "dashed", "dashdot", "none", ""]
|
|
14
15
|
MarkerStyle = Literal["o", "s", "^", "v", "x", "+", ".", "*", "None", ""]
|
|
16
|
+
FontSize = Literal["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"]
|
|
15
17
|
|
|
16
18
|
# --- Figure / Axes creation ---
|
|
17
19
|
|
|
@@ -238,15 +240,8 @@ def errorbar(self, x: ArrayLike = ..., y: ArrayLike = ..., yerr: Optional[ArrayL
|
|
|
238
240
|
Mark size in pt
|
|
239
241
|
"""
|
|
240
242
|
...
|
|
241
|
-
def scatter(
|
|
242
|
-
|
|
243
|
-
*,
|
|
244
|
-
alpha: Optional[float] = ...,
|
|
245
|
-
color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ...,
|
|
246
|
-
marker: Optional[MarkerStyle] = ...,
|
|
247
|
-
markersize: Optional[float] = ..., ms: Optional[float] = ...,
|
|
248
|
-
label: Optional[str] = ...
|
|
249
|
-
) -> None:
|
|
243
|
+
def scatter(self, x: ArrayLike = ..., y: ArrayLike = ..., fmt: Optional[str] = ..., *,alpha: Optional[float] = ..., color: Optional[Union[Sequence[ColorLike], ColorLike]] = ..., c: Optional[ColorLike] = ...,
|
|
244
|
+
marker: Optional[MarkerStyle] = ..., markersize: Optional[Union[Sequence[float], float]] = ..., s: Optional[Union[Sequence[float], float]] = ..., label:Optional[str]=..., cmap: Optional[Union[str, Colorbar]], vmin: Optional[float] = ..., vmax: Optional[float] = ...) -> None:
|
|
250
245
|
"""
|
|
251
246
|
Draw a scatter plot to the selected axis.
|
|
252
247
|
|
|
@@ -254,24 +249,23 @@ def scatter(
|
|
|
254
249
|
----------
|
|
255
250
|
x,y : ArrayLike or float
|
|
256
251
|
Datapoints
|
|
257
|
-
|
|
258
252
|
fmt: str, optional
|
|
259
253
|
Style
|
|
260
|
-
|
|
261
254
|
alpha: float, optional
|
|
262
255
|
Opacity
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
color of line and markers: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
266
|
-
|
|
256
|
+
color or c: array like or single: all matplotlib color formats (without X11/xkcd) or float for colormap, optional
|
|
257
|
+
color of line and markers: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible. Note that if the sequence if of the same length as x, it will be interpreted as color sequence for each point, otherwise it will be interpreted as a single color for all points.
|
|
267
258
|
label: str, optional
|
|
268
259
|
Legned entry
|
|
269
260
|
|
|
270
261
|
marker: str, optional
|
|
271
262
|
Marker type
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
263
|
+
markersize or s: ArrayLike or float, optional
|
|
264
|
+
Mark size in pt (or in 1/50 pt for s), if a sequence of same length as x, it will be interpreted as size for each point, otherwise it will be interpreted as a single size for all points.
|
|
265
|
+
cmap: str or Colorbar, optional
|
|
266
|
+
Colormap for scatter points, if color is given as float or sequence of floats. Can be a colormap name or a Colorbar object.
|
|
267
|
+
vmin, vmax: float, optional
|
|
268
|
+
Colorbar limits for scatter points, if color is given sequence of floats and cmap is given as string, otherwise ignored. If cmap is given as str and no vmin or vmax is provided, they will be set to the min and max of color sequence.
|
|
275
269
|
"""
|
|
276
270
|
...
|
|
277
271
|
|
|
@@ -367,6 +361,32 @@ def fill_between(
|
|
|
367
361
|
"""
|
|
368
362
|
...
|
|
369
363
|
|
|
364
|
+
def text(self, x: float, y: float, s: str, color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ..., fontsize: Optional[FontSize] = ..., 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:
|
|
365
|
+
"""
|
|
366
|
+
Add text to the selected axis.
|
|
367
|
+
Parameters
|
|
368
|
+
----------
|
|
369
|
+
x,y: float
|
|
370
|
+
Text position in axis coordinates
|
|
371
|
+
s: str
|
|
372
|
+
Text content (LaTeX format)
|
|
373
|
+
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
374
|
+
Text color: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
375
|
+
fontsize or size: FontSize, optional
|
|
376
|
+
Font size
|
|
377
|
+
backgroundcolor: all matplotlib color formats (without X11/xkcd), optional
|
|
378
|
+
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
|
|
379
|
+
horizontalalignment or ha: {"center", "left", "right"}, optional
|
|
380
|
+
Horizontal alignment of text
|
|
381
|
+
verticalalignment or va: {"center", "top", "bottom"}, optional
|
|
382
|
+
Vertical alignment of text
|
|
383
|
+
rotation: float or {"vertical", "horizontal"}, optional
|
|
384
|
+
Rotation angle in degrees or preset rotation
|
|
385
|
+
label: str, optional
|
|
386
|
+
Legend entry
|
|
387
|
+
"""
|
|
388
|
+
...
|
|
389
|
+
|
|
370
390
|
def loglog(self, x: ArrayLike = ..., y: ArrayLike = ..., base: Optional[float] = 10, fmt: Optional[str] = ...,*, alpha: Optional[float] = ..., color: Optional[ColorLike] = ..., c: Optional[ColorLike] = ...,
|
|
371
391
|
linestyle: Optional[LineStyle] = ..., ls: Optional[LineStyle] = ..., linewidth: Optional[float]= ..., lw: Optional[float] = ...,
|
|
372
392
|
marker: Optional[MarkerStyle] = ..., markersize: Optional[float] = ..., ms: Optional[float] = ...) -> None:
|
|
@@ -399,6 +419,52 @@ def loglog(self, x: ArrayLike = ..., y: ArrayLike = ..., base: Optional[float] =
|
|
|
399
419
|
"""
|
|
400
420
|
...
|
|
401
421
|
|
|
422
|
+
def hist(
|
|
423
|
+
self,
|
|
424
|
+
x: Union[ArrayLike, Sequence[ArrayLike]],
|
|
425
|
+
bins: int = ...,
|
|
426
|
+
density: bool = ...,
|
|
427
|
+
*,
|
|
428
|
+
cumulative: bool = ...,
|
|
429
|
+
orientation: Literal["horizontal","vertical"] = "vertical",
|
|
430
|
+
rwidth: Optional[float] = ...,
|
|
431
|
+
range: Optional[Tuple[float,float]] = ...,
|
|
432
|
+
color: Optional[ColorLike] = ...,
|
|
433
|
+
**kwargs: Any
|
|
434
|
+
) -> None:
|
|
435
|
+
"""
|
|
436
|
+
Draw histogram to the selected axis.
|
|
437
|
+
"""
|
|
438
|
+
...
|
|
439
|
+
def step(self, x: ArrayLike, y: ArrayLike, *args: Any, where: Literal["pre","post","mid"] = "pre", **kwargs: Any) -> None:
|
|
440
|
+
"""
|
|
441
|
+
Draw a step plot to the selected axis.
|
|
442
|
+
Parameters
|
|
443
|
+
----------
|
|
444
|
+
x,y : ArrayLike or float
|
|
445
|
+
Datapoints
|
|
446
|
+
where: {"pre", "post", "mid"}, default "pre"
|
|
447
|
+
Define where the steps should be placed: before the value (pre), after the value (post), or centered on the value (mid).
|
|
448
|
+
fmt: str, optional
|
|
449
|
+
Style
|
|
450
|
+
alpha: float, optional
|
|
451
|
+
Opacity
|
|
452
|
+
color or c: all matplotlib color formats (without X11/xkcd), optional
|
|
453
|
+
color of line and markers: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
|
|
454
|
+
label: str, optional
|
|
455
|
+
Legned entry
|
|
456
|
+
linestyle or ls: str, optional
|
|
457
|
+
Line style
|
|
458
|
+
linewidth or lw: float, optional
|
|
459
|
+
Line width in pt
|
|
460
|
+
|
|
461
|
+
marker: str, optional
|
|
462
|
+
Marker type
|
|
463
|
+
markersize or ms: float, optional
|
|
464
|
+
Mark size in pt
|
|
465
|
+
"""
|
|
466
|
+
...
|
|
467
|
+
|
|
402
468
|
def hlines(
|
|
403
469
|
self,
|
|
404
470
|
y: Union[float, Sequence[float]],
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from .colors import _tex_color
|
|
2
|
+
|
|
3
|
+
class Text:
|
|
4
|
+
def __init__(self, ax, x, y, s, **kwargs):
|
|
5
|
+
self._axes = ax
|
|
6
|
+
self._x = x
|
|
7
|
+
self._y = y
|
|
8
|
+
self._s = s
|
|
9
|
+
self._kwargs = kwargs
|
|
10
|
+
self._color = False
|
|
11
|
+
self._opacity = 1
|
|
12
|
+
self._fsize = None
|
|
13
|
+
self._label = kwargs.get("label", None)
|
|
14
|
+
self._visible = True
|
|
15
|
+
|
|
16
|
+
_FONT_SIZES = {"xx-small": r"\tiny", "x-small": r"\scriptsize", "small": r"\footnotesize", "medium": r"\normalsize", "large": r"\large", "x-large": r"\Large", "xx-large": r"\LARGE"}
|
|
17
|
+
|
|
18
|
+
def match_color(self, input):
|
|
19
|
+
self._has_color = True
|
|
20
|
+
ccode, op = _tex_color(input)
|
|
21
|
+
if not isinstance(op, bool):
|
|
22
|
+
self._opacity = op
|
|
23
|
+
if isinstance(ccode, str):
|
|
24
|
+
return ccode
|
|
25
|
+
r,g,b=ccode
|
|
26
|
+
self._axes._add_col(r,g,b)
|
|
27
|
+
return f"c{r:.3f}{g:.3f}{b:.3f}".replace(".", "")
|
|
28
|
+
|
|
29
|
+
def _style_string(self):
|
|
30
|
+
output = []
|
|
31
|
+
if "color" in self._kwargs or "c" in self._kwargs:
|
|
32
|
+
self._color = self.match_color(self._kwargs.get("color") or self._kwargs.get("c"))
|
|
33
|
+
if "alpha" in self._kwargs:
|
|
34
|
+
self._opacity = self._kwargs["alpha"]
|
|
35
|
+
if "fontsize" in self._kwargs or "size" in self._kwargs:
|
|
36
|
+
size = self._kwargs.get('fontsize') or self._kwargs.get('size')
|
|
37
|
+
if size in self._FONT_SIZES:
|
|
38
|
+
self._fsize = self._FONT_SIZES[size]
|
|
39
|
+
else:
|
|
40
|
+
raise ValueError(f"Font size {size} not recognized. Valid sizes are: {', '.join(self._FONT_SIZES.keys())}")
|
|
41
|
+
if "backgroundcolor" in self._kwargs:
|
|
42
|
+
bg_color = self.match_color(self._kwargs["backgroundcolor"])
|
|
43
|
+
output.append(f"fill={bg_color}")
|
|
44
|
+
if "horizontalalignment" in self._kwargs or "ha" in self._kwargs:
|
|
45
|
+
ha = self._kwargs.get("horizontalalignment") or self._kwargs.get("ha")
|
|
46
|
+
if ha in {"center", "left", "right"}:
|
|
47
|
+
if ha in {"left", "right"}:
|
|
48
|
+
output.append(ha)
|
|
49
|
+
else:
|
|
50
|
+
raise ValueError(f"Horizontal alignment {ha} not recognized. Valid options are: center, left, right.")
|
|
51
|
+
if "verticalalignment" in self._kwargs or "va" in self._kwargs:
|
|
52
|
+
va = self._kwargs.get("verticalalignment") or self._kwargs.get("va")
|
|
53
|
+
if va in {"center", "top", "bottom"}:
|
|
54
|
+
if va == "top":
|
|
55
|
+
output.append("above")
|
|
56
|
+
elif va == "bottom":
|
|
57
|
+
output.append("below")
|
|
58
|
+
else:
|
|
59
|
+
raise ValueError(f"Vertical alignment {va} not recognized. Valid options are: center, top, bottom.")
|
|
60
|
+
if "rotation" in self._kwargs:
|
|
61
|
+
if isinstance(self._kwargs["rotation"], str):
|
|
62
|
+
if self._kwargs["rotation"] == "vertical":
|
|
63
|
+
output.append("rotate=90")
|
|
64
|
+
elif self._kwargs["rotation"] == "horizontal":
|
|
65
|
+
pass
|
|
66
|
+
elif isinstance(self._kwargs["rotation"], (int, float)):
|
|
67
|
+
output.append(f"rotate={self._kwargs['rotation']}")
|
|
68
|
+
else:
|
|
69
|
+
raise ValueError(f"Rotation value {self._kwargs['rotation']} not recognized. Valid options are: vertical, horizontal, or a numeric angle.")
|
|
70
|
+
if self._opacity < 1:
|
|
71
|
+
output.insert(0,f"opacity={self._opacity}")
|
|
72
|
+
if self._color:
|
|
73
|
+
output.insert(0,f"color={self._color}")
|
|
74
|
+
return ", ".join(output)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _to_tex(self, _):
|
|
78
|
+
if self._visible:
|
|
79
|
+
return f"\\node[{self._style_string()}] at (axis cs:{self._x},{self._y}) {{{self._fsize or ''}{self._s}}};"
|
|
80
|
+
else:
|
|
81
|
+
return ""
|
|
82
|
+
|
|
83
|
+
def _set_label(self, label):
|
|
84
|
+
self._label = label
|
|
85
|
+
|
|
86
|
+
def _filter(self, which, value):
|
|
87
|
+
if (which == "xmin" and self._x < value) or (which == "xmax" and self._x > value) or (which == "ymin" and self._y < value) or (which == "ymax" and self._y > value):
|
|
88
|
+
self._visible = False
|
|
89
|
+
|
|
90
|
+
def _get_erange(self, which):
|
|
91
|
+
if which in {"xmin", "xmax"}:
|
|
92
|
+
return self._x
|
|
93
|
+
elif which in {"ymin", "ymax"}:
|
|
94
|
+
return self._y
|
|
95
|
+
|
|
96
|
+
def _num_points(self):
|
|
97
|
+
return 1
|
|
98
|
+
|
|
99
|
+
def _reduce_points(self, max_points):
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
class Text3(Text):
|
|
103
|
+
def __init__(self, ax, x, y, z, s, **kwargs):
|
|
104
|
+
super().__init__(ax, x, y, s, **kwargs)
|
|
105
|
+
self._z = z
|
|
106
|
+
|
|
107
|
+
def _to_tex(self, _):
|
|
108
|
+
if self._visible:
|
|
109
|
+
return f"\\node[{self._style_string()}] at (axis cs:{self._x},{self._y},{self._z}) {{{self._fsize or ''}{self._s}}};"
|
|
110
|
+
else:
|
|
111
|
+
return ""
|
|
112
|
+
|
|
113
|
+
def _get_erange(self, which):
|
|
114
|
+
if which in {"xmin", "xmax"}:
|
|
115
|
+
return self._x
|
|
116
|
+
elif which in {"ymin", "ymax"}:
|
|
117
|
+
return self._y
|
|
118
|
+
elif which in {"zmin", "zmax"}:
|
|
119
|
+
return self._z
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tikzplot42
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.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
|
|
@@ -705,6 +705,10 @@ A clean version of PltToTikz, this time as Python package. Easy to use: only rep
|
|
|
705
705
|
|
|
706
706
|
Please let me know if you find any bugs or unexpected behaviour. Examples may be found in repository under `tests/` directory.
|
|
707
707
|
|
|
708
|
+
<p align="center">
|
|
709
|
+
<img src="https://github.com/ZanAmb/TikzPlot/blob/main/tests/demo.png" width="60%">
|
|
710
|
+
</p>
|
|
711
|
+
|
|
708
712
|
# Installation
|
|
709
713
|
NEW: PyPI: `pip install tikzplot42`.
|
|
710
714
|
Alternativley, download this package and install using: `pip install [path]`, where [path] is the path to the directory, containing `pyproject.toml`.
|
|
@@ -718,7 +722,8 @@ Instead of using `import matplotlib.pyplot (as plt)`, use `import tikzplot.plots
|
|
|
718
722
|
- `\pgfplotsset{compat=1.18}` (may be lower, but compilation is not guaranteed),
|
|
719
723
|
- `\usepgfplotslibrary{fillbetween}` (if you use fill-between plots),
|
|
720
724
|
- `\usepgfplotslibrary{groupplots}` (recommended for best results, enabled by default, may be avoided by setting TikzConfig USE_GROUPPLOTS=False),
|
|
721
|
-
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False)
|
|
725
|
+
- `\usepackage{xcolor}` (recommended for best colors, works without but needs change of TikzConfig USE_XCOLOR=False),
|
|
726
|
+
- `\usepgfplotslibrary{polar}` required for polar axis.
|
|
722
727
|
|
|
723
728
|
Export using `plt.savefig("example_graph.tex")` (recommended) or `plt.show()`.
|
|
724
729
|
Then use the generated file as `\input{example_graph.tex}`.
|
|
@@ -735,7 +740,9 @@ Some basic plot commands are already implemented with commonly used arguments:
|
|
|
735
740
|
- `fill-between()`,
|
|
736
741
|
- `hlines()/vlines()`,
|
|
737
742
|
- `historgam()`,
|
|
738
|
-
- `
|
|
743
|
+
- `step()`,
|
|
744
|
+
- `imshow()`,
|
|
745
|
+
- `text()`.
|
|
739
746
|
|
|
740
747
|
#### Figures
|
|
741
748
|
- `plt.figure()` (currently only to give you figure object or to set `figsize`),
|
|
@@ -22,12 +22,14 @@ src/tikzplot/plots.pyi
|
|
|
22
22
|
src/tikzplot/py.typed
|
|
23
23
|
src/tikzplot/state.py
|
|
24
24
|
src/tikzplot/state.pyi
|
|
25
|
+
src/tikzplot/texts.py
|
|
25
26
|
src/tikzplot42.egg-info/PKG-INFO
|
|
26
27
|
src/tikzplot42.egg-info/SOURCES.txt
|
|
27
28
|
src/tikzplot42.egg-info/dependency_links.txt
|
|
28
29
|
src/tikzplot42.egg-info/requires.txt
|
|
29
30
|
src/tikzplot42.egg-info/top_level.txt
|
|
30
31
|
tests/test1.py
|
|
32
|
+
tests/test10.py
|
|
31
33
|
tests/test2.py
|
|
32
34
|
tests/test3.py
|
|
33
35
|
tests/test4.py
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Example from official matplotlib documentation
|
|
2
|
+
|
|
3
|
+
import tikzplot.plots as plt
|
|
4
|
+
import numpy as np
|
|
5
|
+
#from tikzplot import Colorbar
|
|
6
|
+
#from tikzplot import TikzConfig
|
|
7
|
+
|
|
8
|
+
#TikzConfig.modifyParam(USE_GROUPPLOTS=False)
|
|
9
|
+
|
|
10
|
+
# Fixing random state for reproducibility
|
|
11
|
+
#np.random.seed(19680801)
|
|
12
|
+
|
|
13
|
+
# Compute areas and colors
|
|
14
|
+
N = 150
|
|
15
|
+
r = 2 * np.random.rand(N)
|
|
16
|
+
theta = 2 * np.pi * np.random.rand(N)
|
|
17
|
+
area = 200 * r**2
|
|
18
|
+
colors = theta
|
|
19
|
+
|
|
20
|
+
fig = plt.figure(figsize=(6, 6))
|
|
21
|
+
ax = fig.add_subplot(projection='polar')
|
|
22
|
+
#cbar = Colorbar(cmap='hsv', lower=0, upper=max(theta))
|
|
23
|
+
c = ax.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75)
|
|
24
|
+
plt.savefig("figure.tex")
|
|
@@ -24,6 +24,7 @@ fig, axs = plt.subplots(3,2)
|
|
|
24
24
|
ax = axs[0, 0]
|
|
25
25
|
ax.plot(x, y, color="blue", lw=1.5, label="sin(x)")
|
|
26
26
|
ax.plot(x, y2, ls="--", color="red", label="cos(x)")
|
|
27
|
+
ax.text(1.5, 0.5, r"text $\alpha$", color="blue", ha="center", va="center", backgroundcolor="cyan", rotation=30)
|
|
27
28
|
ax.grid()
|
|
28
29
|
ax.legend(loc="upper right")
|
|
29
30
|
|
|
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
|