tikzplot42 0.3.4__tar.gz → 0.3.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.
Files changed (42) hide show
  1. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/PKG-INFO +9 -5
  2. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/README.md +8 -4
  3. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/pyproject.toml +1 -1
  4. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/axes.py +148 -35
  5. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/axes.pyi +140 -13
  6. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/axes3d.py +2 -2
  7. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/config.py +1 -0
  8. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/config.pyi +1 -0
  9. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/elements.py +159 -80
  10. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/figure.py +81 -29
  11. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/figure.pyi +1 -0
  12. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/plots.py +20 -0
  13. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/plots.pyi +257 -12
  14. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/texts.py +6 -4
  15. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot42.egg-info/PKG-INFO +9 -5
  16. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test10.py +3 -3
  17. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test2.py +4 -0
  18. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test3.py +1 -0
  19. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test7.py +0 -5
  20. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/LICENSE +0 -0
  21. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/setup.cfg +0 -0
  22. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/__init__.py +0 -0
  23. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/__init__.pyi +0 -0
  24. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/colorbar.py +0 -0
  25. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/colorbar.pyi +0 -0
  26. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/colors.py +0 -0
  27. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/colors.pyi +0 -0
  28. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/elements.pyi +0 -0
  29. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/latex_special.py +0 -0
  30. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/py.typed +0 -0
  31. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/state.py +0 -0
  32. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot/state.pyi +0 -0
  33. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot42.egg-info/SOURCES.txt +0 -0
  34. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot42.egg-info/dependency_links.txt +0 -0
  35. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot42.egg-info/requires.txt +0 -0
  36. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/src/tikzplot42.egg-info/top_level.txt +0 -0
  37. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test1.py +0 -0
  38. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test4.py +0 -0
  39. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test5.py +0 -0
  40. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test6.py +0 -0
  41. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test8.py +0 -0
  42. {tikzplot42-0.3.4 → tikzplot42-0.3.7}/tests/test9.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tikzplot42
3
- Version: 0.3.4
3
+ Version: 0.3.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
@@ -737,12 +737,15 @@ Some basic plot commands are already implemented with commonly used arguments:
737
737
  - `semilogx()/semilogy()`,
738
738
  - `errorbar()`,
739
739
  - `stem()`,
740
- - `fill-between()`,
740
+ - `fill_between()`,
741
741
  - `hlines()/vlines()`,
742
- - `historgam()`,
742
+ - `histogram()`,
743
743
  - `step()`,
744
744
  - `imshow()`,
745
- - `text()`.
745
+ - `text()`,
746
+ - `magnify()` (used to magnify part of a plot, but Tikz cannot handle `fill_between` if this one is used, which is a long known issue),
747
+ - `axvline()/axhline()`,
748
+ - `axvspan()/axhspan()` (background span).
746
749
 
747
750
  #### Figures
748
751
  - `plt.figure()` (currently only to give you figure object or to set `figsize`),
@@ -775,7 +778,8 @@ If axes and plot have different name for command with same effect, both are impl
775
778
  #### Colorbars
776
779
  Colorbars and colormaps are implemented a bit differently than in matplotlib (simplified):
777
780
  - if you use `imshow()`, you may use its return in `Colorbar()` (which you have to import as `from tikzplot import Colorbar`),
778
- - you may use `Colorbar(axis, cmap, lower, upper, ...)` for manual colorbar. Additional kwargs may also be used by `imshow()` return.
781
+ - you may use `Colorbar(axis, cmap, lower, upper, ...)` for manual colorbar. Additional kwargs may also be used by `imshow()` return,
782
+ - note that only one colorbar/colormap per axis is allowed (also if you use `scatter` with colormap/colorbar).
779
783
 
780
784
  #### TikzConfig
781
785
  For plot configurations (default sizes, paddings, etc.), use `from tikzplot import TikzConfig`:
@@ -35,12 +35,15 @@ Some basic plot commands are already implemented with commonly used arguments:
35
35
  - `semilogx()/semilogy()`,
36
36
  - `errorbar()`,
37
37
  - `stem()`,
38
- - `fill-between()`,
38
+ - `fill_between()`,
39
39
  - `hlines()/vlines()`,
40
- - `historgam()`,
40
+ - `histogram()`,
41
41
  - `step()`,
42
42
  - `imshow()`,
43
- - `text()`.
43
+ - `text()`,
44
+ - `magnify()` (used to magnify part of a plot, but Tikz cannot handle `fill_between` if this one is used, which is a long known issue),
45
+ - `axvline()/axhline()`,
46
+ - `axvspan()/axhspan()` (background span).
44
47
 
45
48
  #### Figures
46
49
  - `plt.figure()` (currently only to give you figure object or to set `figsize`),
@@ -73,7 +76,8 @@ If axes and plot have different name for command with same effect, both are impl
73
76
  #### Colorbars
74
77
  Colorbars and colormaps are implemented a bit differently than in matplotlib (simplified):
75
78
  - if you use `imshow()`, you may use its return in `Colorbar()` (which you have to import as `from tikzplot import Colorbar`),
76
- - you may use `Colorbar(axis, cmap, lower, upper, ...)` for manual colorbar. Additional kwargs may also be used by `imshow()` return.
79
+ - you may use `Colorbar(axis, cmap, lower, upper, ...)` for manual colorbar. Additional kwargs may also be used by `imshow()` return,
80
+ - note that only one colorbar/colormap per axis is allowed (also if you use `scatter` with colormap/colorbar).
77
81
 
78
82
  #### TikzConfig
79
83
  For plot configurations (default sizes, paddings, etc.), use `from tikzplot import TikzConfig`:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tikzplot42"
7
- version = "0.3.4"
7
+ version = "0.3.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" }
@@ -17,15 +17,25 @@ class BaseAxes:
17
17
  self._yticks = True
18
18
  self._fig = None
19
19
  if TikzConfig.USE_DECIMAL_COMMA:
20
- self._axis_args.add("/pgf/number format/use comma")
20
+ self._axis_args.add(f"/pgf/number format/.cd, use comma, 1000 sep={{{TikzConfig.THOUSANDS_SEP}}}")
21
+ else:
22
+ self._axis_args.add(f"/pgf/number format/.cd, 1000 sep={{{TikzConfig.THOUSANDS_SEP}}}")
21
23
 
22
24
  self._add_legend = ""
25
+ self._coordinates = {}
26
+ self._cmap_bar = None
27
+
28
+ self._ext_ymin = False
29
+ self._ext_ymax = False
23
30
 
24
31
  def _plot(self, x, y, settings=None, xerr=None, yerr=None, **style):
25
32
  if not isinstance(self, Secondary) and self._polar:
26
33
  x = _np.rad2deg(x)
27
34
  e = Graph(self, (x, y), settings, xerr=xerr, yerr=yerr, **style)
28
- self._elements.append(e)
35
+ if TikzConfig.USE_GROUPPLOTS and ("axvspan" == settings or "axhspan" == settings):
36
+ self._elements.insert(0, e)
37
+ else:
38
+ self._elements.append(e)
29
39
  return e
30
40
 
31
41
  def _check_kwargs(self, func, allowed, **kwargs):
@@ -71,6 +81,10 @@ class BaseAxes:
71
81
  vmin = kwargs.pop("vmin", min(c))
72
82
  vmax = kwargs.pop("vmax", max(c))
73
83
  kwargs["cmap"] = Colorbar(cmap=cmap, lower=vmin, upper=vmax)
84
+ if self._cmap_bar and self._cmap_bar != kwargs["cmap"]:
85
+ raise Warning("Multiple colormaps on same axis! Only one per axis is allowed.")
86
+ else:
87
+ self._cmap_bar = kwargs["cmap"]
74
88
  except: pass
75
89
 
76
90
  return self._plot(x, y, **kwargs, ls="", settings=["scatter"])
@@ -176,6 +190,28 @@ class BaseAxes:
176
190
  return self._plot([xmins[i], xmaxs[i]], [ys[i]]*2, None, None, None, c=colorss[i], ls=lss[i], label=kwargs["label"])
177
191
  else:
178
192
  return self._plot([xmins[i], xmaxs[i]], [ys[i]]*2, None, None, None, c=colorss[i], ls=lss[i])
193
+
194
+ def vlines(self, x, ymin, ymax, colors="k", linestyles="solid", **kwargs):
195
+ kws = {"label"}
196
+ kwargs = self._check_kwargs("vlines", kws, **kwargs)
197
+ def _pad_or_truncate(some_list, target_len):
198
+ return some_list[:target_len] + [some_list[-1]]*(target_len - len(some_list))
199
+ def _to_list(x):
200
+ if x is None:
201
+ return []
202
+ if isinstance(x, (int, float, str)):
203
+ return [x]
204
+ return list(x)
205
+ xs = _to_list(x)
206
+ ymins = _pad_or_truncate(_to_list(ymin), len(xs))
207
+ ymaxs = _pad_or_truncate(_to_list(ymax), len(xs))
208
+ colorss = _pad_or_truncate(_to_list(colors), len(xs))
209
+ lss = _pad_or_truncate(_to_list(linestyles), len(xs))
210
+ for i in range(len(xs)):
211
+ if i == 0 and "label" in kwargs:
212
+ self._plot([xs[i]]*2, [ymins[i], ymaxs[i]], None, None, None, c=colorss[i], ls=lss[i], label=kwargs["label"])
213
+ else:
214
+ self._plot([xs[i]]*2, [ymins[i], ymaxs[i]], None, None, None, c=colorss[i], ls=lss[i])
179
215
 
180
216
  def hist(self, x, bins=10, density=False,**kwargs):
181
217
  #kws = {"alpha", "color", "c", "label"}
@@ -221,6 +257,40 @@ class BaseAxes:
221
257
  if len(args) == 1:
222
258
  kwargs["fmt"] = args[0]
223
259
  return self._plot(x,y,settings=settings, **kwargs)
260
+
261
+ def axvline(self, x, ymin=0, ymax=0, **kwargs):
262
+ kws = {"fmt", "base", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "label"}
263
+ kwargs = self._check_kwargs("axvline", kws, **kwargs)
264
+ self._ext_ymin = self._ext_ymax = True
265
+ self._plot(x, (ymin, ymax), settings="axvline", **kwargs)
266
+
267
+ def axhline(self, y, xmin=0, xmax=0, **kwargs):
268
+ kws = {"fmt", "base", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "label"}
269
+ kwargs = self._check_kwargs("axhline", kws, **kwargs)
270
+ if isinstance(self, Secondary):
271
+ self._primary._ext_xmin = self._primary._ext_xmax = True
272
+ else:
273
+ self._ext_xmin = self._ext_xmax = True
274
+ self._plot((xmin, xmax), y, settings="axhline", **kwargs)
275
+
276
+ def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
277
+ kws = {"c", "color", "alpha", "label"}
278
+ kwargs = self._check_kwargs("axvspan", kws, **kwargs)
279
+ self._ext_ymin = self._ext_ymax = True
280
+ if TikzConfig.USE_GROUPPLOTS:
281
+ self._axis_args.add("set layers")
282
+ self._plot([xmin, xmax], [ymin, ymax], settings="axvspan", **kwargs)
283
+
284
+ def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
285
+ kws = {"c", "color", "alpha", "label"}
286
+ kwargs = self._check_kwargs("axhspan", kws, **kwargs)
287
+ if isinstance(self, Secondary):
288
+ self._primary._ext_xmin = self._primary._ext_xmax = True
289
+ else:
290
+ self._ext_xmin = self._ext_xmax = True
291
+ if TikzConfig.USE_GROUPPLOTS:
292
+ self._axis_args.add("set layers")
293
+ self._plot([xmin, xmax], [ymin, ymax], settings="axhspan", **kwargs)
224
294
 
225
295
  def set_ylabel(self, label):
226
296
  self._axis_options["ylabel"] = f"{{{tex_text(label)}}}"
@@ -331,6 +401,13 @@ class BaseAxes:
331
401
  txt = Text(self, x, y, s, **kwargs)
332
402
  self._elements.append(txt)
333
403
 
404
+ def magnify(self, x_p, y_p, x_m, y_m, zoom, size, **kwargs):
405
+ kws = {"shape", "connect"}
406
+ kwargs = self._check_kwargs("magnify", kws, **kwargs)
407
+ n = self._fig._add_spy(zoom, size, **kwargs)
408
+ self._coordinates.update({f"spypoint{n}": (x_p,y_p)})
409
+ self._coordinates.update({f"spyviewr{n}": (x_m,y_m)})
410
+
334
411
  def _add_legend_entries(self):
335
412
  if self._add_legend == "": return ""
336
413
  axs, labs = self._add_legend
@@ -346,6 +423,9 @@ class BaseAxes:
346
423
  def _content_tex(self, filename):
347
424
  ouptut = "\n".join(e._to_tex(filename) for e in self._elements)
348
425
  ouptut += self._add_legend_entries()
426
+ for coord in self._coordinates:
427
+ x,y = self._coordinates[coord]
428
+ ouptut += f"\n\\coordinate ({coord}) at ({x},{y});"
349
429
  return ouptut
350
430
 
351
431
  def _get_hard_range(self,which):
@@ -364,13 +444,20 @@ class BaseAxes:
364
444
  mode = "lin"
365
445
  if arg in self._axis_options:
366
446
  mode = self._axis_options[arg]
447
+ common = self._elements.copy()
448
+ if "x" in which and isinstance(self,Axes) and self._secondary_y:
449
+ common += self._secondary_y._elements
367
450
  if which in self._axis_options:
368
- for e in self._elements:
451
+ for e in common:
369
452
  e._filter(which, self._axis_options[which])
370
453
  return (self._axis_options[which], True, mode)
454
+ values = [e._get_erange(which) for e in common]
455
+ values = [v for v in values if v is not None]
456
+ if not values:
457
+ return (None, False, mode)
371
458
  if "min" in which:
372
- return (min([e._get_erange(which) for e in self._elements]), False, mode)
373
- return (max([e._get_erange(which) for e in self._elements]), False, mode)
459
+ return (min(values), False, mode)
460
+ return (max(values), False, mode)
374
461
 
375
462
  def _get_limit(self, which):
376
463
  arg = f"{which[0]}mode"
@@ -387,6 +474,15 @@ class BaseAxes:
387
474
 
388
475
  def _set_range(self, which, value):
389
476
  self._axis_options[which] = value
477
+ if isinstance(self, Axes):
478
+ if which == "xmin":
479
+ self._ext_xmin = True
480
+ if which == "xmax":
481
+ self._ext_xmax = True
482
+ if which == "ymin":
483
+ self._ext_ymin = True
484
+ if which == "ymax":
485
+ self._ext_ymax = True
390
486
  for e in self._elements:
391
487
  e._filter(which, value)
392
488
 
@@ -427,6 +523,9 @@ class Axes(BaseAxes):
427
523
  self._cbar_h = False
428
524
  self._polar = polar
429
525
 
526
+ self._ext_xmin = False
527
+ self._ext_xmax = False
528
+
430
529
  def _posit_string(): # returns neighbour, neighbour corner, anchor
431
530
  i = self._index
432
531
  if i == 0:
@@ -481,28 +580,6 @@ class Axes(BaseAxes):
481
580
  self._axis_options["log basis x"] = kwargs["base"]
482
581
  return self._plot(x, y, **kwargs)
483
582
 
484
- def vlines(self, x, ymin, ymax, colors="k", linestyles="solid", **kwargs):
485
- kws = {"label"}
486
- kwargs = self._check_kwargs("vlines", kws, **kwargs)
487
- def _pad_or_truncate(some_list, target_len):
488
- return some_list[:target_len] + [some_list[-1]]*(target_len - len(some_list))
489
- def _to_list(x):
490
- if x is None:
491
- return []
492
- if isinstance(x, (int, float, str)):
493
- return [x]
494
- return list(x)
495
- xs = _to_list(x)
496
- ymins = _pad_or_truncate(_to_list(ymin), len(xs))
497
- ymaxs = _pad_or_truncate(_to_list(ymax), len(xs))
498
- colorss = _pad_or_truncate(_to_list(colors), len(xs))
499
- lss = _pad_or_truncate(_to_list(linestyles), len(xs))
500
- for i in range(len(xs)):
501
- if i == 0 and "label" in kwargs:
502
- self._plot([xs[i]]*2, [ymins[i], ymaxs[i]], None, None, None, c=colorss[i], ls=lss[i], label=kwargs["label"])
503
- else:
504
- self._plot([xs[i]]*2, [ymins[i], ymaxs[i]], None, None, None, c=colorss[i], ls=lss[i])
505
-
506
583
  def imshow(self, *args, **kwargs):
507
584
  #kws = {"fmt", "alpha", "color", "c", "linestyle", "ls", "linewidth", "lw", "marker", "markersize", "ms", "label"}
508
585
  #kwargs = self._check_kwargs("imshow", kws, **kwargs)
@@ -610,6 +687,7 @@ class Axes(BaseAxes):
610
687
  if self._polar:
611
688
  raise Exception("Cannot create twinx() on polar plot.")
612
689
  self._secondary_y = Secondary(self)
690
+ self._ext_xmin = self._ext_xmax = True
613
691
  return self._secondary_y
614
692
 
615
693
  def _export_imshow(self, *args, **kwargs):
@@ -653,13 +731,38 @@ class Axes(BaseAxes):
653
731
  axis_opt_str += ",\n".join(self._axis_args)
654
732
  if TikzConfig.SCHOOL_AXIS:
655
733
  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}}"
734
+ if ("xmin" in self._axis_options and self._axis_options["xmin"] == 0) or ("xmax" in self._axis_options and self._axis_options["xmax"] == 0):
735
+ self._axis_options["extra x ticks"] = r"{0}"
736
+ if ("ymin" in self._axis_options and self._axis_options["ymin"] == 0) or ("ymax" in self._axis_options and self._axis_options["ymax"] == 0):
737
+ self._axis_options["extra y ticks"] = r"{0}"
656
738
  if TikzConfig.USE_GROUPPLOTS:
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"
739
+ if TikzConfig.SCHOOL_AXIS:
740
+ axis_opt_str += f",\n set layers,\n axis line style={{on layer=axis foreground}}"
741
+ else:
742
+ axis_opt_str += f",\n axis on top"
743
+ if self._ext_xmin or self._ext_xmax:
744
+ lower = self._get_range("xmin")
745
+ upper = self._get_range("xmax")
746
+ xm, xM = self._fig._range_setting(lower[0], upper[0], lower[2])
747
+ if self._ext_xmin:
748
+ self._axis_options["xmin"] = self._fig._next_limname("xmin", self._axis_options.get("xmin", xm))
749
+ if self._ext_xmax:
750
+ self._axis_options["xmax"] = self._fig._next_limname("xmax", self._axis_options.get("xmax", xM))
751
+ if self._ext_ymin or self._ext_ymax:
752
+ lower = self._get_range("ymin")
753
+ upper = self._get_range("ymax")
754
+ ym, yM = self._fig._range_setting(lower[0], upper[0], lower[2])
755
+ if self._ext_ymin:
756
+ self._axis_options["ymin"] = self._fig._next_limname("ymin", self._axis_options.get("ymin", ym))
757
+ if self._ext_ymax:
758
+ self._axis_options["ymax"] = self._fig._next_limname("ymax", self._axis_options.get("ymax", yM))
659
759
  if self._axis_options:
660
760
  if axis_opt_str: axis_opt_str += ",\n"
661
761
  axis_opt_str += ",\n".join(f"{k}={v}" for k, v in self._axis_options.items())
662
- axis_opt_str += self._colorbar
762
+ if self._colorbar:
763
+ axis_opt_str += self._colorbar
764
+ elif self._cmap_bar:
765
+ axis_opt_str += f",\n colormap={self._cmap_bar._generate_tex_colormap(self._cmap_bar._cmap)}"
663
766
  return axis_opt_str
664
767
 
665
768
 
@@ -690,27 +793,27 @@ class Axes(BaseAxes):
690
793
  def _get_index(self):
691
794
  return self._index
692
795
 
693
- def _to_tex(self, filename):
796
+ def _to_tex(self, filename, single):
694
797
  lines = []
695
798
  lines2 = []
696
- if self._polar and TikzConfig.USE_GROUPPLOTS:
799
+ if self._polar and TikzConfig.USE_GROUPPLOTS and not single:
697
800
  lines.append(f"\\nextgroupplot[alias={self._axis_options['alias']}, width={self._width}, height={self._height}, hide axis]")
698
801
  lines2.append("\\begin{polaraxis}")
699
802
  lines2.append(f"[{self._axis_option_string()}]")
700
803
  lines2.append(self._content_tex(filename))
701
804
  lines2.append("\\end{polaraxis}")
702
805
  else:
703
- if TikzConfig.USE_GROUPPLOTS:
806
+ if TikzConfig.USE_GROUPPLOTS and not single:
704
807
  lines.append("\\nextgroupplot")
705
808
  if self._polar:
706
809
  lines.append("\\begin{polaraxis}")
707
- elif not TikzConfig.USE_GROUPPLOTS:
810
+ elif not TikzConfig.USE_GROUPPLOTS or (TikzConfig.USE_GROUPPLOTS and single):
708
811
  lines.append("\\begin{axis}")
709
812
  lines.append(f"[{self._axis_option_string()}]")
710
813
  lines.append(self._content_tex(filename))
711
814
  if self._polar:
712
815
  lines.append("\\end{polaraxis}")
713
- elif not TikzConfig.USE_GROUPPLOTS:
816
+ elif not TikzConfig.USE_GROUPPLOTS or (TikzConfig.USE_GROUPPLOTS and single):
714
817
 
715
818
  lines.append("\\end{axis}")
716
819
  if self._secondary_y is not None:
@@ -749,6 +852,16 @@ class Secondary(BaseAxes):
749
852
  axis_opt_str = ""
750
853
  if self._axis_args:
751
854
  axis_opt_str += ",\n".join(self._axis_args)
855
+ if self._ext_ymin or self._ext_ymax:
856
+ lower = self._get_range("ymin")
857
+ upper = self._get_range("ymax")
858
+ ym, yM = self._fig._range_setting(lower[0], upper[0], lower[2])
859
+ if self._ext_ymin:
860
+ self._axis_options["ymin"] = self._fig._next_limname("ymin", self._axis_options.get("ymin", ym))
861
+ if self._ext_ymax:
862
+ self._axis_options["ymax"] = self._fig._next_limname("ymax", self._axis_options.get("ymax", yM))
863
+ self._axis_options["xmin"] = self._primary._axis_options["xmin"]
864
+ self._axis_options["xmax"] = self._primary._axis_options["xmax"]
752
865
  if self._axis_options:
753
866
  if axis_opt_str: axis_opt_str += ",\n"
754
867
  axis_opt_str += ",\n".join(f"{k}={v}" for k, v in self._axis_options.items())
@@ -258,6 +258,18 @@ class BaseAxes:
258
258
  Draw horizontal lines to the selected axis.
259
259
  """
260
260
  ...
261
+ def vlines(
262
+ self,
263
+ x: Union[float, Sequence[float]],
264
+ ymin: Union[float, Sequence[float]],
265
+ ymax: Union[float, Sequence[float]],
266
+ colors: Union[str, Sequence[str]] = "k",
267
+ linestyles: Union[str, Sequence[str]] = "solid",
268
+ ) -> None:
269
+ """
270
+ Draw vertical lines to the selected axis.
271
+ """
272
+ ...
261
273
  def hist(
262
274
  self,
263
275
  x: Union[ArrayLike, Sequence[ArrayLike]],
@@ -313,6 +325,132 @@ class BaseAxes:
313
325
  Mark size in pt
314
326
  """
315
327
  ...
328
+
329
+ def axvline(self, x:float, ymin:float=0, ymax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., linestyle:Optional[str] = ..., linewidth:Optional[float] = ..., label:Optional[str] = ...) -> None:
330
+ """
331
+ Draw a vertical line to the selected axis at given x coordinate.
332
+
333
+ Parameters
334
+ ----------
335
+ x: float
336
+ X coordinate of the line(s)
337
+
338
+ ymin, ymax: float, optional
339
+ Y relative coordinate of the lower and upper end of the line
340
+
341
+ alpha: float, optional
342
+ Opacity
343
+
344
+ color or c: all matplotlib color formats (without X11/xkcd), optional
345
+ color of line: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
346
+
347
+ linestyle or ls: str, optional
348
+ Line style
349
+
350
+ linewidth or lw: float, optional
351
+ Line width in pt
352
+
353
+ label: str, optional
354
+ Legend entry
355
+ """
356
+
357
+ def axhline(self, y:float, xmin:float=0, xmax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., linestyle:Optional[str] = ..., linewidth:Optional[float] = ..., label:Optional[str] = ...) -> None:
358
+ """
359
+ Draw a horizontal line to the selected axis at given y coordinate.
360
+
361
+ Parameters
362
+ ----------
363
+ y: float
364
+ Y coordinate of the line(s)
365
+
366
+ xmin, xmax: float, optional
367
+ X relative coordinate of the left and right end of the line
368
+
369
+ alpha: float, optional
370
+ Opacity
371
+
372
+ color or c: all matplotlib color formats (without X11/xkcd), optional
373
+ color of line: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
374
+
375
+ linestyle or ls: str, optional
376
+ Line style
377
+
378
+ linewidth or lw: float, optional
379
+ Line width in pt
380
+
381
+ label: str, optional
382
+ Legend entry
383
+ """
384
+
385
+ def axvspan(self, xmin:float, xmax:float, ymin:float=0, ymax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., label:Optional[str] = ...) -> None:
386
+ """
387
+ Draw a background vertical span to the selected axis between given x coordinates.
388
+
389
+ Parameters
390
+ ----------
391
+ xmin, xmax: float
392
+ X coordinates of the left and right end of the span
393
+
394
+ ymin, ymax: float, optional
395
+ Y relative coordinate of the lower and upper end of the span
396
+
397
+ alpha: float, optional
398
+ Opacity
399
+
400
+ color or c: all matplotlib color formats (without X11/xkcd), optional
401
+ color of line: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
402
+
403
+ label: str, optional
404
+ Legend entry
405
+ """
406
+
407
+ def axhspan(self, ymin:float, ymax:float, xmin:float=0, xmax:float=1, alpha:Optional[float] = ..., color:Optional[ColorLike] = ..., label:Optional[str] = ...) -> None:
408
+ """
409
+ Draw a background horizontal span to the selected axis between given y coordinates.
410
+
411
+ Parameters
412
+ ----------
413
+ ymin, ymax: float
414
+ Y coordinates of the lower and upper end of the span
415
+
416
+ xmin, xmax: float, optional
417
+ X relative coordinate of the left and right end of the span
418
+
419
+ alpha: float, optional
420
+ Opacity
421
+
422
+ color or c: all matplotlib color formats (without X11/xkcd), optional
423
+ color of line: RGB/RGBA (tuple), HEX (str), grayscale (float), single-char (str), name (str), default cycle ("CX", X int), none for invisible
424
+
425
+ label: str, optional
426
+ Legend entry
427
+ """
428
+
429
+ def magnify(self, x_p: float, y_p: float, x_m: float, y_m: float, zoom: float, size: float, **kwargs) -> int:
430
+ """
431
+ Add a spyviewer to the selected axis.
432
+
433
+ Parameters
434
+ ----------
435
+ x_p, y_p: float
436
+ Spy point coordinates in axis units
437
+
438
+ x_m, y_m: float
439
+ Spy view coordinates in cm
440
+
441
+ zoom: float
442
+ Spy zoom
443
+
444
+ size: float
445
+ Spy viewer size in cm
446
+
447
+ shape: {"circle"}, optional
448
+ Spy shape, default square
449
+
450
+ connect: bool, optional
451
+ Connect spy point and view with a line, default False
452
+ """
453
+ ...
316
454
 
317
455
  def set_ylabel(self, label: str) -> None:
318
456
  """
@@ -342,13 +480,14 @@ class BaseAxes:
342
480
  ...
343
481
  def legend(self, *args: Any, loc: Optional[Union[int,str,Tuple[float,float]]] = ...) -> None:
344
482
  """
345
- Show legend for the selected axis.
483
+ Show legend for the selected axis. Despite arguments requires at least one plotted element on the axis (not necesarily with label) to show up (LaTeX does not allow legend on empty axis).
346
484
 
347
485
  Parameters
348
486
  ----------
349
487
  *args:
350
488
  - single arg: list/tuple, optional: list of labels to assign to axis elements (in given order assigned to plotted elements in the order of plotting). If label is used on any of the elements, the original label is overwritten.
351
489
  - two args: list/tuple, optional: element, label - assign labels to plots (use references of plots which are returned in plot commands). In case that a plot already has a label, both will be displayed. This is the only option to merge the legend entries for double-axis (twinx) plots.
490
+
352
491
  loc: int, str or tuple, optional
353
492
  Location of legend (as in matplotlib: 1 - upper right, 2 - upper left, ... or with tuple of relative coordinates).
354
493
 
@@ -441,18 +580,6 @@ class Axes(BaseAxes):
441
580
  Mark size in pt
442
581
  """
443
582
  ...
444
- def vlines(
445
- self,
446
- x: Union[float, Sequence[float]],
447
- ymin: Union[float, Sequence[float]],
448
- ymax: Union[float, Sequence[float]],
449
- colors: Union[str, Sequence[str]] = "k",
450
- linestyles: Union[str, Sequence[str]] = "solid",
451
- ) -> None:
452
- """
453
- Draw vertical lines to the selected axis.
454
- """
455
- ...
456
583
  def imshow(self, *args: Any, cmap: Optional[str] = ...) -> Tuple[Any, str, float, float]:
457
584
  """
458
585
  Draw image to the selected axis from array. Uses matplotlib imshow() to export to PDF, then inputs the image to the axis. Return may be used to initialize Colorbar().
@@ -553,9 +553,9 @@ class Axes3:
553
553
  def _get_index(self):
554
554
  return self._index
555
555
 
556
- def _to_tex(self, filename):
556
+ def _to_tex(self, filename, single):
557
557
  lines = []
558
- if TikzConfig.USE_GROUPPLOTS:
558
+ if TikzConfig.USE_GROUPPLOTS and not single:
559
559
  lines.append("\\nextgroupplot")
560
560
  lines.append(f"[{self._axis_option_string()}]")
561
561
  lines.append(self._content_tex(filename))
@@ -6,6 +6,7 @@ class _TikzConfig:
6
6
  def __init__(self):
7
7
 
8
8
  self.USE_DECIMAL_COMMA: bool = False
9
+ self.THOUSANDS_SEP: str = ""
9
10
 
10
11
  self.LEGEND_REL_X: float = 0.03
11
12
  self.LEGEND_REL_Y: float = 0.03
@@ -7,6 +7,7 @@ from typing import TypedDict, Unpack, Any, ClassVar, Protocol
7
7
 
8
8
  class _ConfigParams(TypedDict, total=False):
9
9
  USE_DECIMAL_COMMA: bool
10
+ THOUSANDS_SEP: str
10
11
 
11
12
  LEGEND_REL_X: float
12
13
  LEGEND_REL_Y: float