tikzplot42 0.4.5__tar.gz → 0.4.7__tar.gz

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