tikzplot42 0.4.5__tar.gz → 0.4.6__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.6}/PKG-INFO +1 -1
  2. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/pyproject.toml +1 -1
  3. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/axes.py +23 -10
  4. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/axes.pyi +99 -3
  5. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/elements.py +62 -6
  6. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/plots.pyi +118 -14
  7. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot42.egg-info/PKG-INFO +1 -1
  8. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test13.py +4 -3
  9. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test2.py +2 -1
  10. tikzplot42-0.4.6/tests/test4.py +9 -0
  11. tikzplot42-0.4.5/tests/test4.py +0 -8
  12. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/LICENSE +0 -0
  13. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/README.md +0 -0
  14. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/setup.cfg +0 -0
  15. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/__init__.py +0 -0
  16. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/__init__.pyi +0 -0
  17. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/axes3d.py +0 -0
  18. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/axes3d.pyi +0 -0
  19. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/colorbar.py +0 -0
  20. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/colorbar.pyi +0 -0
  21. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/colors.py +0 -0
  22. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/config.py +0 -0
  23. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/config.pyi +0 -0
  24. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/elements.pyi +0 -0
  25. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/figure.py +0 -0
  26. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/figure.pyi +0 -0
  27. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/latex_special.py +0 -0
  28. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/plots.py +0 -0
  29. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/py.typed +0 -0
  30. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/state.py +0 -0
  31. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/styles.py +0 -0
  32. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/styles.pyi +0 -0
  33. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot/texts.py +0 -0
  34. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot42.egg-info/SOURCES.txt +0 -0
  35. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot42.egg-info/dependency_links.txt +0 -0
  36. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot42.egg-info/requires.txt +0 -0
  37. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/src/tikzplot42.egg-info/top_level.txt +0 -0
  38. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test1.py +0 -0
  39. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test10.py +0 -0
  40. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test11.py +0 -0
  41. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test12.py +0 -0
  42. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test3.py +0 -0
  43. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test5.py +0 -0
  44. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test6.py +0 -0
  45. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test7.py +0 -0
  46. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test8.py +0 -0
  47. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/tests/test9.py +0 -0
  48. {tikzplot42-0.4.5 → tikzplot42-0.4.6}/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.6
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
@@ -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.6"
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:
@@ -222,7 +222,7 @@ class BaseAxes:
222
222
  self._plot([xs[i]]*2, [ymins[i], ymaxs[i]], None, None, None, c=colorss[i], ls=lss[i])
223
223
 
224
224
  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"}
225
+ 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
226
  kwargs = self._check_kwargs("hist", kws, **kwargs)
227
227
  if isinstance(x, (list, tuple)) and len(x) > 0 and isinstance(x[0], (list, tuple, _np.ndarray)):
228
228
  try:
@@ -246,7 +246,7 @@ class BaseAxes:
246
246
 
247
247
  stack = kwargs.pop("stacked", False)
248
248
  datas = {}
249
- for kw in ["color", "c", "facecolor", "fc", "edgecolor", "ec", "label"]:
249
+ for kw in ["color", "c", "facecolor", "fc", "edgecolor", "ec", "label", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"]:
250
250
  if kw in kwargs:
251
251
  if isinstance(kwargs[kw], (list)):
252
252
  if len(kwargs[kw]) != len(datasets):
@@ -299,17 +299,29 @@ class BaseAxes:
299
299
  old_counts = _np.zeros(len(edges), dtype=_np.float64)
300
300
  totals, _ = _np.histogram(all_data, edges, density=False, weights=kwargs.get("weights", None), range=kwargs.get("range", None))
301
301
  tot_sum = totals.sum()
302
+ align_offset = 0
303
+ if "align" in kwargs:
304
+ if kwargs["align"] not in ["left", "mid", "right"]:
305
+ raise Warning(f"Invalid align value: {kwargs['align']}. Must be 'left', 'mid', or 'right'.")
306
+ if kwargs["align"] == "left":
307
+ align_offset = -widths.mean()/2
308
+ elif kwargs["align"] == "mid":
309
+ align_offset = 0
310
+ elif kwargs["align"] == "right":
311
+ align_offset = widths.mean()/2
302
312
  for i in range(len(datasets)):
303
313
  data = datasets[i]
304
314
  settings = base_settings.copy()
305
315
  kws = datas.get(i, {})
306
316
  if "label" in kws:
307
- if "xbar" in settings or "xbar interval" in settings:
317
+ if "xbar" in settings:
308
318
  settings["xbar legend"] = None
309
- else:
319
+ elif "xbar interval" in settings:
320
+ settings["xbar interval legend"] = None
321
+ elif "ybar" in settings:
310
322
  settings["ybar legend"] = None
311
- else:
312
- settings["forget plot"] = None
323
+ else:
324
+ settings["ybar interval legend"] = None
313
325
  fill = kws.pop("facecolor", kws.pop("fc", kws.pop("color", kws.pop("c", None))))
314
326
  draw = kws.pop("edgecolor", kws.pop("ec", None))
315
327
  if fill:
@@ -325,7 +337,7 @@ class BaseAxes:
325
337
  if "rwidth" in kwargs:
326
338
  xs = [edges[0] + widths[0]*(1-kwargs["rwidth"])/2]
327
339
  new_counts = []
328
- for j in range(len(widths)): # Changed 'i' to 'j' to avoid overwriting dataset index 'i'
340
+ for j in range(len(widths)):
329
341
  xs.append(xs[-1] + widths[j]*kwargs["rwidth"])
330
342
  new_counts.append(counts[j])
331
343
  if j < len(counts)-1:
@@ -339,6 +351,7 @@ class BaseAxes:
339
351
  xs = (edges[:-1] + edges[1:]) / 2
340
352
  if offset > 0:
341
353
  settings["bar shift"] = f"{offset*(i - len(datasets)/2 + 0.5)}"
354
+ xs = xs + align_offset * _np.ones_like(xs)
342
355
  if "cumulative" in kwargs and kwargs["cumulative"]:
343
356
  counts = _np.cumsum(counts)
344
357
  if stack:
@@ -386,7 +399,7 @@ class BaseAxes:
386
399
  self._plot((xmin, xmax), y, settings={"axhline": None}, **kwargs)
387
400
 
388
401
  def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
389
- kws = {"c", "color", "alpha", "label"}
402
+ kws = {"c", "color", "alpha", "label", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"}
390
403
  kwargs = self._check_kwargs("axvspan", kws, **kwargs)
391
404
  self._ext_ymin = self._ext_ymax = True
392
405
  if TikzConfig.USE_GROUPPLOTS:
@@ -394,7 +407,7 @@ class BaseAxes:
394
407
  self._plot([xmin, xmax], [ymin, ymax], settings={"axvspan": None}, **kwargs)
395
408
 
396
409
  def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
397
- kws = {"c", "color", "alpha", "label"}
410
+ kws = {"c", "color", "alpha", "label", "hatch", "hatch_color", "hatch_linewidth", "hatch_distance"}
398
411
  kwargs = self._check_kwargs("axhspan", kws, **kwargs)
399
412
  if isinstance(self, Secondary):
400
413
  self._primary._ext_xmin = self._primary._ext_xmax = True
@@ -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,49 @@ 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
+ def match_hatch(input):
177
+ chars = list(input)
178
+ hatches = []
179
+ while chars:
180
+ if chars[0] in self._HATCH_MAP.keys():
181
+ hatches.append(self._HATCH_MAP[chars[0]])
182
+ chars.pop(0)
183
+ elif len(chars) > 1 and chars[0] + chars[1] in self._HATCH_MAP.keys():
184
+ hatches.append(self._HATCH_MAP[chars[0] + chars[1]])
185
+ chars.pop(0)
186
+ chars.pop(0)
187
+ else:
188
+ raise ValueError(f"Unrecognized hatch pattern {input}")
189
+ return hatches
190
+ hatch = match_hatch(self._style["hatch"])
191
+ hatch_args = {}
192
+ hatch_color = match_color(self._style.get("hatch_color", "black"))
193
+ if "hatch_linewidth" in self._style:
194
+ hatch_args["line width"] = f"{self._style['hatch_linewidth']}pt"
195
+ if "hatch_distance" in self._style:
196
+ hatch_args["distance"] = f"{self._style['hatch_distance']}"
197
+ opts["postaction"] = []
198
+ types = [list(h.keys())[0] for h in hatch]
199
+ duplicated_hatchs = set(k for k in types if types.count(k) > 1)
200
+ dhs = duplicated_hatchs.copy()
201
+ hatch = [h for h in hatch if list(h.keys())[0] not in duplicated_hatchs or duplicated_hatchs.remove(list(h.keys())[0])]
202
+ for i in range(len(hatch)):
203
+ h = hatch[i]
204
+ h_type = list(h.keys())[0]
205
+ h_args = {"distance": 3.0} | h[h_type] | hatch_args
206
+ if h_type in dhs:
207
+ h_args["distance"] = f"{h_args.get('distance', 3.0)/2}"
208
+ if h_type in ["Dots", "Stars", "Hatch"]:
209
+ if h_type in ["Dots", "Stars"] and "line width" in h_args:
210
+ h_args["radius"] = f"{h_args.pop('line width')}"
211
+ if h_args.get("angle", 0) != 0:
212
+ h_args["xshift"] = f"{0.5 * float(h_args.get('distance', 0)) / np.sin(np.radians(h_args.get('angle', 0)))}"
213
+ else:
214
+ h_args["yshift"] = f"{0.5 * float(h_args.get('distance', 0)) / np.cos(np.radians(h_args.get('angle', 0)))}"
215
+ opts["postaction"].append(f"pattern={{{h_type}[{', '.join(f'{k}={v}' for k,v in h_args.items())}]}}, pattern color={hatch_color}")
216
+
170
217
  if self._classic:
171
218
  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
219
  opts["error bars/.cd"] = None
@@ -206,7 +253,16 @@ class BaseGraph:
206
253
  self._p_dict[i] = self._st_dict[st]
207
254
  opts["point meta"] = "explicit symbolic"
208
255
  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)
256
+ self._style_str = ""
257
+ for o in opts:
258
+ if opts[o] is None:
259
+ self._style_str += f"{o},\n"
260
+ elif isinstance(opts[o], list):
261
+ for q in opts[o]:
262
+ self._style_str += f"{o}={{{q}}},\n"
263
+ else:
264
+ self._style_str += f"{o}={opts[o]},\n"
265
+ self._style_str.removesuffix(",\n")
210
266
  return self._style_str
211
267
 
212
268
  def _save_data(self, points, filename):
@@ -378,9 +434,9 @@ class Graph(BaseGraph):
378
434
  rect = f"\\fill[{style}] (axis cs:{self._x[0]}, {lower}) rectangle (axis cs:{self._x[1]}, {upper});"
379
435
  if self._label and self._axes._legend_on:
380
436
  if label_opts:
381
- rect += f"\\addlegendentry[{label_opts}]{{{self._label}}}"
437
+ rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry[{label_opts}]{{{self._label}}}"
382
438
  else:
383
- rect += f"\\addlegendentry{{{self._label}}}"
439
+ rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry{{{self._label}}}"
384
440
  if TikzConfig.USE_GROUPPLOTS:
385
441
  return f"\\begin{{pgfonlayer}}{{axis background}}{rect}\\end{{pgfonlayer}}"
386
442
  return rect
@@ -393,9 +449,9 @@ class Graph(BaseGraph):
393
449
  rect = f"\\fill[{style}] (axis cs:{lower}, {self._y[0]}) rectangle (axis cs:{upper}, {self._y[1]});"
394
450
  if self._label and self._axes._legend_on:
395
451
  if label_opts:
396
- rect += f"\\addlegendentry[{label_opts}]{{{self._label}}}"
452
+ rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry[{label_opts}]{{{self._label}}}"
397
453
  else:
398
- rect += f"\\addlegendentry{{{self._label}}}"
454
+ rect += f"\\addlegendimage{{area legend, {style}}}\\addlegendentry{{{self._label}}}"
399
455
  if TikzConfig.USE_GROUPPLOTS:
400
456
  return f"\\begin{{pgfonlayer}}{{axis background}}{rect}\\end{{pgfonlayer}}"
401
457
  return rect
@@ -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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tikzplot42
3
- Version: 0.4.5
3
+ Version: 0.4.6
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
@@ -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,7 +14,8 @@ 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$")
@@ -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
File without changes