tikzplot42 0.2.8__py3-none-any.whl
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.
- tikzplot/__init__.py +5 -0
- tikzplot/__init__.pyi +5 -0
- tikzplot/axes.py +717 -0
- tikzplot/axes.pyi +445 -0
- tikzplot/axes3d.py +566 -0
- tikzplot/colorbar.py +261 -0
- tikzplot/colorbar.pyi +128 -0
- tikzplot/colors.py +58 -0
- tikzplot/colors.pyi +1 -0
- tikzplot/config.py +101 -0
- tikzplot/config.pyi +95 -0
- tikzplot/elements.py +641 -0
- tikzplot/elements.pyi +11 -0
- tikzplot/figure.py +285 -0
- tikzplot/figure.pyi +27 -0
- tikzplot/latex_special.py +62 -0
- tikzplot/plots.py +175 -0
- tikzplot/plots.pyi +314 -0
- tikzplot/py.typed +0 -0
- tikzplot/state.py +24 -0
- tikzplot/state.pyi +3 -0
- tikzplot42-0.2.8.dist-info/METADATA +780 -0
- tikzplot42-0.2.8.dist-info/RECORD +26 -0
- tikzplot42-0.2.8.dist-info/WHEEL +5 -0
- tikzplot42-0.2.8.dist-info/licenses/LICENSE +674 -0
- tikzplot42-0.2.8.dist-info/top_level.txt +1 -0
tikzplot/axes3d.py
ADDED
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
import numpy as _np
|
|
2
|
+
import matplotlib.pyplot as _plt
|
|
3
|
+
|
|
4
|
+
from .elements import Graph3
|
|
5
|
+
from .config import TikzConfig
|
|
6
|
+
#from .state import _next_imshow_num, main_name
|
|
7
|
+
from .latex_special import tex_text
|
|
8
|
+
|
|
9
|
+
class Axes3:
|
|
10
|
+
def __init__(self, nrows, ncols, index, fig):
|
|
11
|
+
self._elements = []
|
|
12
|
+
self._axis_options = {"grid": "major"}
|
|
13
|
+
self._axis_args = set()
|
|
14
|
+
self._legend_on = False
|
|
15
|
+
self._xticks = True
|
|
16
|
+
self._yticks = True
|
|
17
|
+
self._fig = None
|
|
18
|
+
if TikzConfig.USE_DECIMAL_COMMA:
|
|
19
|
+
self._axis_args.add("/pgf/number format/use comma")
|
|
20
|
+
|
|
21
|
+
self._add_legend = ""
|
|
22
|
+
|
|
23
|
+
self._left = False
|
|
24
|
+
self._neigh = None
|
|
25
|
+
|
|
26
|
+
self._nrows = nrows
|
|
27
|
+
self._ncols = ncols
|
|
28
|
+
self._index = index - 1
|
|
29
|
+
self._row = self._index // self._ncols
|
|
30
|
+
self._col = self._index - self._row * self._ncols
|
|
31
|
+
|
|
32
|
+
self._fig = fig
|
|
33
|
+
|
|
34
|
+
self._defcol_counter = 0
|
|
35
|
+
self._colorbar = ""
|
|
36
|
+
self._cbar_h = False
|
|
37
|
+
|
|
38
|
+
def _posit_string(): # returns neighbour, neighbour corner, anchor
|
|
39
|
+
i = self._index
|
|
40
|
+
if i == 0:
|
|
41
|
+
return None
|
|
42
|
+
if self._col == 0:
|
|
43
|
+
self._neigh = i - self._ncols
|
|
44
|
+
self._left = True
|
|
45
|
+
return self._neigh, "south", "north"
|
|
46
|
+
self._neigh = i - 1
|
|
47
|
+
return self._neigh, "east", "west"
|
|
48
|
+
|
|
49
|
+
self._axis_options["alias" if TikzConfig.USE_GROUPPLOTS else "name"] = f"p{index-1}"
|
|
50
|
+
pos = _posit_string()
|
|
51
|
+
if pos is not None and not TikzConfig.USE_GROUPPLOTS:
|
|
52
|
+
self._axis_options["at"] = f"{{(p{self._neigh}.{pos[1]})}}"
|
|
53
|
+
self._axis_options["anchor"] = pos[2]
|
|
54
|
+
|
|
55
|
+
self._width = None
|
|
56
|
+
self._height = None
|
|
57
|
+
if self._fig._get_width():
|
|
58
|
+
self._width= f"{self._fig._get_width() / ncols}cm"
|
|
59
|
+
if self._fig._get_height():
|
|
60
|
+
self._height = f"{self._fig._get_height() / nrows}cm"
|
|
61
|
+
|
|
62
|
+
def _plot(self, xs, ys, zs, zdir="z", settings=None, xerr=None, yerr=None, zerr=None, **style):
|
|
63
|
+
if isinstance(zs, (float,int)):
|
|
64
|
+
zs = [zs] * len(xs)
|
|
65
|
+
if zdir == "y":
|
|
66
|
+
xs, ys, zs = ys, zs, xs
|
|
67
|
+
elif zdir == "x":
|
|
68
|
+
xs, ys, zs = zs, xs, ys
|
|
69
|
+
e = Graph3(self, (xs, ys, zs), settings, xerr=xerr, yerr=yerr, zerr=zerr, **style)
|
|
70
|
+
self._elements.append(e)
|
|
71
|
+
return e
|
|
72
|
+
|
|
73
|
+
def _check_kwargs(self, func, allowed, **kwargs):
|
|
74
|
+
blacklist = set(kwargs) - allowed
|
|
75
|
+
for b in blacklist:
|
|
76
|
+
raise Warning(f"Ignoring unknown kwarg for {func}: {b}")
|
|
77
|
+
return {k: v for k, v in kwargs.items() if k in allowed}
|
|
78
|
+
|
|
79
|
+
def plot(self, xs, ys, zs, zdir="z", **kwargs):
|
|
80
|
+
kws = {"fmt", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "marker", "markersize", "ms", "label"}
|
|
81
|
+
kwargs = self._check_kwargs("plot", kws, **kwargs)
|
|
82
|
+
if isinstance(zs, (int, float)):
|
|
83
|
+
zs = [zs] * len(xs)
|
|
84
|
+
return self._plot(xs, ys, zs, zdir, **kwargs)
|
|
85
|
+
|
|
86
|
+
def scatter(self, xs, ys, zs=0, zdir="z", *args, **kwargs):
|
|
87
|
+
kws = {"fmt", "alpha", "color", "c", "marker", "markersize", "s", "label"}
|
|
88
|
+
kwargs = self._check_kwargs("scatter", kws, **kwargs)
|
|
89
|
+
if isinstance(zs, (int, float)):
|
|
90
|
+
zs = [zs] * len(xs)
|
|
91
|
+
if "s" in kwargs:
|
|
92
|
+
kwargs["ms"] = kwargs.pop("s")
|
|
93
|
+
return self._plot(xs, ys, zs, zdir, **kwargs, ls="")
|
|
94
|
+
|
|
95
|
+
def plot_surface(self, X, Y, Z, **kwargs):
|
|
96
|
+
kws = {"alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "label"}
|
|
97
|
+
kwargs = self._check_kwargs("plot", kws, **kwargs)
|
|
98
|
+
return self._plot(X, Y, Z, settings=["surf", f"mesh/rows={X.shape[0]}"] , **kwargs)
|
|
99
|
+
|
|
100
|
+
def plot_wireframe(self, X, Y, Z, **kwargs):
|
|
101
|
+
kws = {"alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "label"}
|
|
102
|
+
kwargs = self._check_kwargs("plot", kws, **kwargs)
|
|
103
|
+
return self._plot(X, Y, Z, settings=["mesh", f"mesh/rows={X.shape[0]}"] , **kwargs)
|
|
104
|
+
|
|
105
|
+
def errorbar(self, x, y, z, zerr=None, yerr=None, xerr=None, **kwargs):
|
|
106
|
+
kws = {"fmt", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "marker", "markersize", "ms", "label"}
|
|
107
|
+
kwargs = self._check_kwargs("errorbar", kws, **kwargs)
|
|
108
|
+
return self._plot(x, y, z, xerr=xerr,yerr=yerr, zerr=zerr, **kwargs)
|
|
109
|
+
|
|
110
|
+
"""def stem(self, x, y, z, **kwargs):
|
|
111
|
+
kws = {"orientation", "linefmt", "markerfmt", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "marker", "markersize", "ms", "label"}
|
|
112
|
+
kwargs = self._check_kwargs("stem", kws, **kwargs)
|
|
113
|
+
if "linefmt" in kwargs:
|
|
114
|
+
kwargs["fmt"] = kwargs.pop("linefmt")
|
|
115
|
+
orinet = "z"
|
|
116
|
+
if "orientation" in kwargs:
|
|
117
|
+
orinet = kwargs.pop("orientation")
|
|
118
|
+
return self._plot(x,y,z,settings=[f"{orinet}comb"], **kwargs)"""
|
|
119
|
+
|
|
120
|
+
def fill_between(self, x1, y1, z1, x2, y2, z2, **kwargs):
|
|
121
|
+
kws = {"fmt", "alpha", "color", "c", "label"}
|
|
122
|
+
kwargs = self._check_kwargs("fill_between", kws, **kwargs)
|
|
123
|
+
def _check_instance(xs, ys, zs, pname):
|
|
124
|
+
for el in self._elements:
|
|
125
|
+
if el._check_equal(xs,ys,zs):
|
|
126
|
+
return el._try_set_pname(pname)
|
|
127
|
+
return None
|
|
128
|
+
name1 = self._fig._get_free_path_name()
|
|
129
|
+
name2 = self._fig._get_free_path_name()
|
|
130
|
+
if isinstance(y1, (int, float)):
|
|
131
|
+
y1 = _np.asarray([y1] * len(x1))
|
|
132
|
+
if isinstance(z1, (int, float)):
|
|
133
|
+
z1 = _np.asarray([z1] * len(x1))
|
|
134
|
+
inst = _check_instance(x1,y1,z1,name1)
|
|
135
|
+
if inst is None:
|
|
136
|
+
self._plot(x1,y1,z1,path_name=name1, alpha=0)
|
|
137
|
+
else:
|
|
138
|
+
name1 = inst
|
|
139
|
+
|
|
140
|
+
if y2 is not None:
|
|
141
|
+
if isinstance(y2, (int, float)):
|
|
142
|
+
y2 = _np.asarray([y2] * len(x2))
|
|
143
|
+
if isinstance(z2, (int, float)):
|
|
144
|
+
z2 = _np.asarray([z2] * len(x2))
|
|
145
|
+
inst = _check_instance(x2,y2,z2,name2)
|
|
146
|
+
if inst is None:
|
|
147
|
+
self._plot(x2,y2,z2,path_name=name2, alpha=0)
|
|
148
|
+
else:
|
|
149
|
+
name2 = inst
|
|
150
|
+
"""else:
|
|
151
|
+
xs = [min(x), max(x)]
|
|
152
|
+
ys = [0,0]
|
|
153
|
+
inst = _check_instance(xs,ys,name2)
|
|
154
|
+
if inst is None:
|
|
155
|
+
self._plot(xs,ys,path_name=name2, alpha=0)
|
|
156
|
+
else:
|
|
157
|
+
name2 = inst"""
|
|
158
|
+
e = Graph3(self, f"fill between [of={name1} and {name2}]",settings=None, xerr=None, yerr=None, zerr=None, **kwargs)
|
|
159
|
+
self._elements.append(e)
|
|
160
|
+
return e
|
|
161
|
+
|
|
162
|
+
"""def hist(self, x, bins=10, density=False,**kwargs):
|
|
163
|
+
#kws = {"alpha", "color", "c", "label"}
|
|
164
|
+
#kwargs = self._check_kwargs("hist", kws, **kwargs)
|
|
165
|
+
try:
|
|
166
|
+
iter(x)
|
|
167
|
+
iter(x[0])
|
|
168
|
+
datasets = x
|
|
169
|
+
except:
|
|
170
|
+
datasets = [x]
|
|
171
|
+
all_data = _np.concatenate(datasets)
|
|
172
|
+
edges = _np.histogram_bin_edges(all_data, bins=bins)
|
|
173
|
+
for data in datasets:
|
|
174
|
+
counts, _ = _np.histogram(data, edges, density=density)
|
|
175
|
+
centers = (edges[:-1] + edges[1:]) / 2
|
|
176
|
+
widths = edges[1:] - edges[:-1]
|
|
177
|
+
settings = []
|
|
178
|
+
if "orientation" in kwargs and kwargs["orientation"] == "horizontal":
|
|
179
|
+
settings.append("xbar")
|
|
180
|
+
else:
|
|
181
|
+
settings.append("ybar")
|
|
182
|
+
settings.append("fill")
|
|
183
|
+
if "rwidth" in kwargs:
|
|
184
|
+
settings.append(f"bar width={widths.mean()*kwargs["rwidth"]}")
|
|
185
|
+
else:
|
|
186
|
+
settings[0] += " interval"
|
|
187
|
+
if "range" in kwargs:
|
|
188
|
+
if settings[0] == "xbar":
|
|
189
|
+
self.set_ylim(kwargs["range"])
|
|
190
|
+
else:
|
|
191
|
+
self.set_xlim(kwargs["range"])
|
|
192
|
+
if "cumulative" in kwargs and kwargs["cumulative"]:
|
|
193
|
+
counts = _np.cumsum(counts)
|
|
194
|
+
|
|
195
|
+
return self._plot(centers, counts, settings=settings, **kwargs)"""
|
|
196
|
+
|
|
197
|
+
def set_title(self, title):
|
|
198
|
+
self._axis_options["title"] = f"{{{tex_text(title)}}}"
|
|
199
|
+
|
|
200
|
+
def set_xlabel(self, label):
|
|
201
|
+
self._axis_options["xlabel"] = f"{{{tex_text(label)}}}"
|
|
202
|
+
|
|
203
|
+
def set_ylabel(self, label):
|
|
204
|
+
self._axis_options["ylabel"] = f"{{{tex_text(label)}}}"
|
|
205
|
+
|
|
206
|
+
def set_zlabel(self, label):
|
|
207
|
+
self._axis_options["zlabel"] = f"{{{tex_text(label)}}}"
|
|
208
|
+
|
|
209
|
+
def set_xlim(self, *args, **kwargs):
|
|
210
|
+
left = None
|
|
211
|
+
right = None
|
|
212
|
+
for k in kwargs:
|
|
213
|
+
if k not in ["left", "right"]:
|
|
214
|
+
print(f"Invalid argument {kwargs.pop(k)} in ylim")
|
|
215
|
+
|
|
216
|
+
if len(args) == 1:
|
|
217
|
+
left, right = args[0]
|
|
218
|
+
elif len(args) == 2:
|
|
219
|
+
left, right = args
|
|
220
|
+
elif len(args) > 2:
|
|
221
|
+
raise ValueError("set_xlim accepts at most 2 positional arguments")
|
|
222
|
+
|
|
223
|
+
if "left" in kwargs:
|
|
224
|
+
left = kwargs["left"]
|
|
225
|
+
if "right" in kwargs:
|
|
226
|
+
right = kwargs["right"]
|
|
227
|
+
|
|
228
|
+
if left is not None:
|
|
229
|
+
self._axis_options["xmin"] = left
|
|
230
|
+
if right is not None:
|
|
231
|
+
self._axis_options["xmax"] = right
|
|
232
|
+
|
|
233
|
+
def set_ylim(self, *args, **kwargs):
|
|
234
|
+
bottom = None
|
|
235
|
+
top = None
|
|
236
|
+
for k in kwargs:
|
|
237
|
+
if k not in ["bottom", "top"]:
|
|
238
|
+
print(f"Invalid argument {kwargs.pop(k)} in ylim")
|
|
239
|
+
|
|
240
|
+
if len(args) == 1:
|
|
241
|
+
bottom, top = args[0]
|
|
242
|
+
elif len(args) == 2:
|
|
243
|
+
bottom, top = args
|
|
244
|
+
elif len(args) > 2:
|
|
245
|
+
raise ValueError("set_ylim accepts at most 2 positional arguments")
|
|
246
|
+
|
|
247
|
+
if "bottom" in kwargs:
|
|
248
|
+
bottom = kwargs["bottom"]
|
|
249
|
+
if "top" in kwargs:
|
|
250
|
+
top = kwargs["top"]
|
|
251
|
+
|
|
252
|
+
if bottom is not None:
|
|
253
|
+
self._axis_options["ymin"] = bottom
|
|
254
|
+
if top is not None:
|
|
255
|
+
self._axis_options["ymax"] = top
|
|
256
|
+
|
|
257
|
+
def set_zlim(self, *args, **kwargs):
|
|
258
|
+
bottom = None
|
|
259
|
+
top = None
|
|
260
|
+
for k in kwargs:
|
|
261
|
+
if k not in ["bottom", "top"]:
|
|
262
|
+
print(f"Invalid argument {kwargs.pop(k)} in zlim")
|
|
263
|
+
|
|
264
|
+
if len(args) == 1:
|
|
265
|
+
bottom, top = args[0]
|
|
266
|
+
elif len(args) == 2:
|
|
267
|
+
bottom, top = args
|
|
268
|
+
elif len(args) > 2:
|
|
269
|
+
raise ValueError("set_zlim accepts at most 2 positional arguments")
|
|
270
|
+
|
|
271
|
+
if "bottom" in kwargs:
|
|
272
|
+
bottom = kwargs["bottom"]
|
|
273
|
+
if "top" in kwargs:
|
|
274
|
+
top = kwargs["top"]
|
|
275
|
+
|
|
276
|
+
if bottom is not None:
|
|
277
|
+
self._axis_options["zmin"] = bottom
|
|
278
|
+
if top is not None:
|
|
279
|
+
self._axis_options["zmax"] = top
|
|
280
|
+
|
|
281
|
+
def set_xscale(self, *args, **kwargs):
|
|
282
|
+
kws = {"base"}
|
|
283
|
+
kwargs = self._check_kwargs("set_xscale", kws, **kwargs)
|
|
284
|
+
if "log" in args:
|
|
285
|
+
self._axis_options["xmode"] = "log"
|
|
286
|
+
if "base" in kwargs:
|
|
287
|
+
self._axis_options["log basis x"] = kwargs["base"]
|
|
288
|
+
|
|
289
|
+
def set_yscale(self, *args, **kwargs):
|
|
290
|
+
kws = {"base"}
|
|
291
|
+
kwargs = self._check_kwargs("set_yscale", kws, **kwargs)
|
|
292
|
+
if "log" in args:
|
|
293
|
+
self._axis_options["ymode"] = "log"
|
|
294
|
+
if "base" in kwargs:
|
|
295
|
+
self._axis_options["log basis y"] = kwargs["base"]
|
|
296
|
+
|
|
297
|
+
def set_zscale(self, *args, **kwargs):
|
|
298
|
+
kws = {"base"}
|
|
299
|
+
kwargs = self._check_kwargs("set_zscale", kws, **kwargs)
|
|
300
|
+
if "log" in args:
|
|
301
|
+
self._axis_options["zmode"] = "log"
|
|
302
|
+
if "base" in kwargs:
|
|
303
|
+
self._axis_options["log basis z"] = kwargs["base"]
|
|
304
|
+
|
|
305
|
+
def set_xticks(self, ticks, labels=None):
|
|
306
|
+
if ticks:
|
|
307
|
+
s_ticks = map(str, ticks)
|
|
308
|
+
self._axis_options["xtick"]=f"{{{','.join(s_ticks)}}}"
|
|
309
|
+
if labels and len(labels)==len(ticks):
|
|
310
|
+
self._axis_options["xticklabels"]=f"{{{tex_text(','.join(labels))}}}"
|
|
311
|
+
elif labels is not None and len(labels) == 0:
|
|
312
|
+
self._axis_options["xticklabels"]=r"{}"
|
|
313
|
+
else:
|
|
314
|
+
self._axis_options["xticks"]=r"{}"
|
|
315
|
+
self._xticks = False
|
|
316
|
+
|
|
317
|
+
def set_yticks(self, ticks, labels=None):
|
|
318
|
+
if ticks:
|
|
319
|
+
s_ticks = map(str, ticks)
|
|
320
|
+
self._axis_options["ytick"]=f"{{{','.join(s_ticks)}}}"
|
|
321
|
+
if labels and len(labels)==len(ticks):
|
|
322
|
+
self._axis_options["yticklabels"]=f"{{{tex_text(','.join(labels))}}}"
|
|
323
|
+
elif labels is not None and len(labels) == 0:
|
|
324
|
+
self._axis_options["yticklabels"]=r"{}"
|
|
325
|
+
else:
|
|
326
|
+
self._axis_options["yticks"]=r"{}"
|
|
327
|
+
self._yticks = False
|
|
328
|
+
|
|
329
|
+
def set_zticks(self, ticks, labels=None):
|
|
330
|
+
if ticks:
|
|
331
|
+
s_ticks = map(str, ticks)
|
|
332
|
+
self._axis_options["ztick"]=f"{{{','.join(s_ticks)}}}"
|
|
333
|
+
if labels and len(labels)==len(ticks):
|
|
334
|
+
self._axis_options["zticklabels"]=f"{{{tex_text(','.join(labels))}}}"
|
|
335
|
+
elif labels is not None and len(labels) == 0:
|
|
336
|
+
self._axis_options["zticklabels"]=r"{}"
|
|
337
|
+
else:
|
|
338
|
+
self._axis_options["zticks"]=r"{}"
|
|
339
|
+
self._zticks = False
|
|
340
|
+
|
|
341
|
+
def set_xticklabels(self, labels):
|
|
342
|
+
if labels:
|
|
343
|
+
self._axis_options["xticklabels"]=f"{{{tex_text(','.join(labels))}}}"
|
|
344
|
+
else:
|
|
345
|
+
self._axis_options["xticklabels"]=r"{}"
|
|
346
|
+
|
|
347
|
+
def set_yticklabels(self, labels):
|
|
348
|
+
if labels:
|
|
349
|
+
self._axis_options["yticklabels"]=f"{{{tex_text(','.join(labels))}}}"
|
|
350
|
+
else:
|
|
351
|
+
self._axis_options["yticklabels"]=r"{}"
|
|
352
|
+
|
|
353
|
+
def set_zticklabels(self, labels):
|
|
354
|
+
if labels:
|
|
355
|
+
self._axis_options["zticklabels"]=f"{{{tex_text(','.join(labels))}}}"
|
|
356
|
+
else:
|
|
357
|
+
self._axis_options["zticklabels"]=r"{}"
|
|
358
|
+
|
|
359
|
+
_LEGEND_LOC_MAP = ["best", "upper right", "upper left", "lower_left", "lower right", "right", "center left", "center right", "lower center", "upper center", "center"]
|
|
360
|
+
_ANCHOR_MAP = {"top": "north", "bottom": "south", "upper": "north", "lower": "south", "left": "west", "right": "east", "center": "center"}
|
|
361
|
+
|
|
362
|
+
def legend(self, *args, **kwargs):
|
|
363
|
+
if "loc" in kwargs:
|
|
364
|
+
loc = kwargs["loc"]
|
|
365
|
+
lx = ly = posit = None
|
|
366
|
+
if isinstance(loc, tuple):
|
|
367
|
+
try:
|
|
368
|
+
lx,ly=float(loc[0]), float(loc[1])
|
|
369
|
+
posit = "south west"
|
|
370
|
+
except: print(f"Error parsing legend location: {loc}")
|
|
371
|
+
else:
|
|
372
|
+
if isinstance(loc, int):
|
|
373
|
+
loc = self._LEGEND_LOC_MAP[loc]
|
|
374
|
+
posit = " ".join([self._ANCHOR_MAP[k] for k in self._ANCHOR_MAP if k in str(loc)])
|
|
375
|
+
if "center" in posit:
|
|
376
|
+
if "north" in posit or "south" in posit or "west" in posit or "east" in posit:
|
|
377
|
+
posit = posit.replace("center", "")
|
|
378
|
+
lx, ly = 0.5, 0.5
|
|
379
|
+
if "north" in posit:
|
|
380
|
+
ly = 1 - TikzConfig.LEGEND_REL_Y
|
|
381
|
+
elif "south" in posit:
|
|
382
|
+
ly = TikzConfig.LEGEND_REL_Y
|
|
383
|
+
if "west" in posit:
|
|
384
|
+
lx = TikzConfig.LEGEND_REL_X
|
|
385
|
+
elif "east" in posit:
|
|
386
|
+
lx = 1 - TikzConfig.LEGEND_REL_X
|
|
387
|
+
|
|
388
|
+
legend_string = []
|
|
389
|
+
if lx is not None and ly is not None:
|
|
390
|
+
legend_string.append(r"at={(" + f"{lx},{ly}" + r")}")
|
|
391
|
+
if len(posit):
|
|
392
|
+
legend_string.append(r"anchor=" + posit)
|
|
393
|
+
else: print(posit)
|
|
394
|
+
self._axis_options["legend style"] = f"{{{','.join(legend_string)}}}"
|
|
395
|
+
self._legend_on = True
|
|
396
|
+
if "ncols" in kwargs:
|
|
397
|
+
self._axis_options["legend columns"] = kwargs["ncols"]
|
|
398
|
+
if len(args) == 2:
|
|
399
|
+
self._add_legend = args
|
|
400
|
+
elif len(args) == 1:
|
|
401
|
+
labs = args[0]
|
|
402
|
+
if len(labs) > len(self._elements):
|
|
403
|
+
print("Legend: more labels than elements")
|
|
404
|
+
else:
|
|
405
|
+
for i in range(len(labs)):
|
|
406
|
+
self._elements[i]._set_label(tex_text(labs[i]))
|
|
407
|
+
|
|
408
|
+
def view_init(self, elev=None, azim=None, roll=None):
|
|
409
|
+
if elev == None:
|
|
410
|
+
elev = TikzConfig.DEFAULT_3D_ELEV
|
|
411
|
+
if azim == None:
|
|
412
|
+
azim = TikzConfig.DEFAULT_3D_AZIM
|
|
413
|
+
if roll == None:
|
|
414
|
+
roll = TikzConfig.DEFAULT_3D_ROLL
|
|
415
|
+
self._axis_options["view"] = f"{{{90+azim}}}{{{elev}}}"
|
|
416
|
+
self._axis_options["rotate around z"] = f"{{{roll}}}"
|
|
417
|
+
|
|
418
|
+
def _add_legend_entries(self):
|
|
419
|
+
if self._add_legend == "": return ""
|
|
420
|
+
axs, labs = self._add_legend
|
|
421
|
+
output = ""
|
|
422
|
+
if len(axs) != len(labs):
|
|
423
|
+
print("Legend: different number of plots and labels, ignoring.")
|
|
424
|
+
return ""
|
|
425
|
+
for i in range(len(axs)):
|
|
426
|
+
output += f"\n\\addlegendimage{{{axs[i]._style_string()}}}"
|
|
427
|
+
output += f"\n\\addlegendentry{{{tex_text(labs[i])}}}"
|
|
428
|
+
return output
|
|
429
|
+
|
|
430
|
+
def _content_tex(self, filename):
|
|
431
|
+
ouptut = "\n".join(e._to_tex(filename) for e in self._elements)
|
|
432
|
+
ouptut += self._add_legend_entries()
|
|
433
|
+
return ouptut
|
|
434
|
+
|
|
435
|
+
def _get_hard_range(self,which):
|
|
436
|
+
arg = f"{which[0]}mode"
|
|
437
|
+
mode = "lin"
|
|
438
|
+
if arg in self._axis_options:
|
|
439
|
+
mode = self._axis_options[arg]
|
|
440
|
+
if which in self._axis_options:
|
|
441
|
+
for e in self._elements:
|
|
442
|
+
e._filter(which, self._axis_options[which])
|
|
443
|
+
return (self._axis_options[which], mode)
|
|
444
|
+
return None, mode
|
|
445
|
+
|
|
446
|
+
def _get_range(self, which):
|
|
447
|
+
arg = f"{which[0]}mode"
|
|
448
|
+
mode = "lin"
|
|
449
|
+
if arg in self._axis_options:
|
|
450
|
+
mode = self._axis_options[arg]
|
|
451
|
+
if which in self._axis_options:
|
|
452
|
+
for e in self._elements:
|
|
453
|
+
e._filter(which, self._axis_options[which])
|
|
454
|
+
return (self._axis_options[which], True, mode)
|
|
455
|
+
if "min" in which:
|
|
456
|
+
return (min([e._get_erange(which) for e in self._elements]), False, mode)
|
|
457
|
+
return (max([e._get_erange(which) for e in self._elements]), False, mode)
|
|
458
|
+
|
|
459
|
+
def _set_range(self, which, value):
|
|
460
|
+
self._axis_options[which] = value
|
|
461
|
+
for e in self._elements:
|
|
462
|
+
e._filter(which, value)
|
|
463
|
+
|
|
464
|
+
def _num_points(self):
|
|
465
|
+
return [e._num_points() for e in self._elements]
|
|
466
|
+
|
|
467
|
+
def _reduce_points(self, limit):
|
|
468
|
+
logx, logy = False, False
|
|
469
|
+
if "xmode" in self._axis_options and self._axis_options["xmode"] == "log":
|
|
470
|
+
logx = True
|
|
471
|
+
if "ymode" in self._axis_options and self._axis_options["ymode"] == "log":
|
|
472
|
+
logy = True
|
|
473
|
+
for e in self._elements:
|
|
474
|
+
e._reduce_points(limit, logx, logy)
|
|
475
|
+
|
|
476
|
+
def _add_col(self, r,g,b):
|
|
477
|
+
self._fig._add_col(r,g,b)
|
|
478
|
+
|
|
479
|
+
def _update_size(self):
|
|
480
|
+
if self._fig._get_width():
|
|
481
|
+
self._width= f"{self._fig._get_width() / self._ncols}cm"
|
|
482
|
+
if self._fig._get_height():
|
|
483
|
+
self._height = f"{self._fig._get_height() / self._nrows}cm"
|
|
484
|
+
|
|
485
|
+
def grid(self, visible=True, which="major"):
|
|
486
|
+
|
|
487
|
+
if not visible:
|
|
488
|
+
self._axis_options["grid"] = "none"
|
|
489
|
+
return
|
|
490
|
+
|
|
491
|
+
if which == "major":
|
|
492
|
+
self._axis_options["grid"] = "major"
|
|
493
|
+
|
|
494
|
+
elif which == "minor":
|
|
495
|
+
self._axis_options["minor grid style"] = "{dotted}"
|
|
496
|
+
self._axis_options["grid"] = "both"
|
|
497
|
+
|
|
498
|
+
elif which == "both":
|
|
499
|
+
self._axis_options["grid"] = "both"
|
|
500
|
+
|
|
501
|
+
def _axis_option_string(self):
|
|
502
|
+
self._update_size()
|
|
503
|
+
if self._width:
|
|
504
|
+
self._axis_options["width"] = self._width
|
|
505
|
+
if self._height:
|
|
506
|
+
self._axis_options["height"] = self._height
|
|
507
|
+
if not TikzConfig.USE_GROUPPLOTS:
|
|
508
|
+
if self._left:
|
|
509
|
+
self._axis_options["yshift"] = f"-{self._fig._get_spacing(self._row, self._col)}cm"
|
|
510
|
+
else:
|
|
511
|
+
self._axis_options["xshift"] = f"{self._fig._get_spacing(self._row, self._col)}cm"
|
|
512
|
+
axis_opt_str = ""
|
|
513
|
+
if self._axis_args:
|
|
514
|
+
axis_opt_str += ",\n".join(self._axis_args)
|
|
515
|
+
#if TikzConfig.SCHOOL_AXIS:
|
|
516
|
+
# 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}},"
|
|
517
|
+
if self._axis_options:
|
|
518
|
+
if axis_opt_str: axis_opt_str += ",\n"
|
|
519
|
+
axis_opt_str += ",\n".join(f"{k}={v}" for k, v in self._axis_options.items())
|
|
520
|
+
axis_opt_str += self._colorbar
|
|
521
|
+
return axis_opt_str
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def _margins(self):
|
|
525
|
+
left = TikzConfig.LEFT_PADDING * self._yticks + TikzConfig.Y_LABEL_PADDING * ("ylabel" in self._axis_options)
|
|
526
|
+
right = TikzConfig.RIGHT_PADDING + TikzConfig.CBAR_X_MARGIN * (self._colorbar != "" and not self._cbar_h)
|
|
527
|
+
top = TikzConfig.TOP_PADDING + TikzConfig.TITLE_PADDING * ("title" in self._axis_options)
|
|
528
|
+
bottom = TikzConfig.BOTTOM_PADDING * self._xticks + TikzConfig.X_LABEL_PADDING * ("xlabel" in self._axis_options) + TikzConfig.CBAR_Y_MARGIN * (self._colorbar != "" and self._cbar_h)
|
|
529
|
+
|
|
530
|
+
return left, right, top, bottom
|
|
531
|
+
|
|
532
|
+
def _get_row(self):
|
|
533
|
+
return self._row
|
|
534
|
+
def _get_col(self):
|
|
535
|
+
return self._col
|
|
536
|
+
def _get_nrows(self):
|
|
537
|
+
return self._nrows
|
|
538
|
+
def _get_ncols(self):
|
|
539
|
+
return self._ncols
|
|
540
|
+
def _get_defcol(self):
|
|
541
|
+
self._defcol_counter += 1
|
|
542
|
+
return self._defcol_counter - 1
|
|
543
|
+
def _show_colorbar(self, cbar, horizontal=False):
|
|
544
|
+
self._colorbar = ",\n" + cbar
|
|
545
|
+
self._cbar_h = horizontal
|
|
546
|
+
def _get_index(self):
|
|
547
|
+
return self._index
|
|
548
|
+
|
|
549
|
+
def _to_tex(self, filename):
|
|
550
|
+
lines = []
|
|
551
|
+
if TikzConfig.USE_GROUPPLOTS:
|
|
552
|
+
lines.append("\\nextgroupplot")
|
|
553
|
+
lines.append(f"[{self._axis_option_string()}]")
|
|
554
|
+
lines.append(self._content_tex(filename))
|
|
555
|
+
else:
|
|
556
|
+
lines.append("\\begin{axis}")
|
|
557
|
+
lines.append(f"[{self._axis_option_string()}]")
|
|
558
|
+
lines.append(self._content_tex(filename))
|
|
559
|
+
lines.append("\\end{axis}")
|
|
560
|
+
return lines, []
|
|
561
|
+
|
|
562
|
+
def set(self, **kwargs):
|
|
563
|
+
defined = {"title": self.set_title, "xlim": self.set_xlim, "xlabel": self.set_xlabel, "xscale": self.set_xscale, "xticklabels": self.set_xticklabels, "xticks": self.set_xticks, "ylim": self.set_ylim, "ylabel": self.set_ylabel, "yscale": self.set_yscale, "yticklabels": self.set_yticklabels, "yticks": self.set_yticks, "zlim": self.set_zlim, "zlabel": self.set_zlabel, "zscale": self.set_zscale, "zticklabels": self.set_zticklabels, "zticks": self.set_zticks}
|
|
564
|
+
for attr in defined:
|
|
565
|
+
if attr in kwargs:
|
|
566
|
+
defined[attr](kwargs.pop(attr))
|