kaxe 1.4.9.dev0__tar.gz → 1.5.0__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 (134) hide show
  1. {kaxe-1.4.9.dev0/src/kaxe.egg-info → kaxe-1.5.0}/PKG-INFO +1 -1
  2. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/pyproject.toml +1 -1
  3. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/__init__.py +1 -0
  4. kaxe-1.5.0/src/kaxe/objects/d2/inequality.py +216 -0
  5. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/map.py +88 -4
  6. {kaxe-1.4.9.dev0 → kaxe-1.5.0/src/kaxe.egg-info}/PKG-INFO +1 -1
  7. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/SOURCES.txt +3 -1
  8. kaxe-1.5.0/tests/test_5.py +15 -0
  9. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/LICENSE +0 -0
  10. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/MANIFEST.in +0 -0
  11. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/README.md +0 -0
  12. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/setup.cfg +0 -0
  13. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/__init__.py +0 -0
  14. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/__init__.py +0 -0
  15. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/bar.py +0 -0
  16. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/box.py +0 -0
  17. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/pie.py +0 -0
  18. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/qqplot.py +0 -0
  19. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/__init__.py +0 -0
  20. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/axis.py +0 -0
  21. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/bounds.py +0 -0
  22. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/color.py +0 -0
  23. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/backend.py +0 -0
  24. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/camera.py +0 -0
  25. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/helper.py +0 -0
  26. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/hud.py +0 -0
  27. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/__init__.py +0 -0
  28. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/color.py +0 -0
  29. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/line.py +0 -0
  30. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/point.py +0 -0
  31. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/pointer.py +0 -0
  32. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/triangle.py +0 -0
  33. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/openglrender.py +0 -0
  34. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/translator.py +0 -0
  35. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/draw.py +0 -0
  36. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/fileloader.py +0 -0
  37. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/helper.py +0 -0
  38. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/legend.py +0 -0
  39. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/line.py +0 -0
  40. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/marker.py +0 -0
  41. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/profiler.py +0 -0
  42. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/round.py +0 -0
  43. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/shapes.py +0 -0
  44. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/styles.py +0 -0
  45. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/svg.py +0 -0
  46. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/svg_pdf.py +0 -0
  47. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/symbol.py +0 -0
  48. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/text.py +0 -0
  49. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/window.py +0 -0
  50. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/data/__init__.py +0 -0
  51. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/data/excel.py +0 -0
  52. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/__init__.py +0 -0
  53. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/_lazy.py +0 -0
  54. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/arrow.py +0 -0
  55. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/bubble.py +0 -0
  56. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/contour.py +0 -0
  57. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/equation.py +0 -0
  58. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/fill.py +0 -0
  59. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/function.py +0 -0
  60. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/parameter.py +0 -0
  61. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/pillar.py +0 -0
  62. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/point.py +0 -0
  63. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/__init__.py +0 -0
  64. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/base.py +0 -0
  65. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/function.py +0 -0
  66. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/mesh.py +0 -0
  67. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/point.py +0 -0
  68. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/potato.py +0 -0
  69. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/function.py +0 -0
  70. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/legend.py +0 -0
  71. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/mapdata.py +0 -0
  72. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/point.py +0 -0
  73. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/text.py +0 -0
  74. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/__init__.py +0 -0
  75. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/_lazy.py +0 -0
  76. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/box.py +0 -0
  77. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/constants.py +0 -0
  78. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/__init__.py +0 -0
  79. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/axes.py +0 -0
  80. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/geometry.py +0 -0
  81. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/plot3d.py +0 -0
  82. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/variants.py +0 -0
  83. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/double.py +0 -0
  84. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/empty.py +0 -0
  85. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/grid.py +0 -0
  86. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/log.py +0 -0
  87. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/polar.py +0 -0
  88. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/standard.py +0 -0
  89. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/themes.py +0 -0
  90. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/zoom.py +0 -0
  91. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/zoom_connector.py +0 -0
  92. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/__init__.py +0 -0
  93. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/__init__.py +0 -0
  94. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf +0 -0
  95. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf +0 -0
  96. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-semibold.ttf +0 -0
  97. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-semiboldoblique.ttf +0 -0
  98. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.classical-serif-italic.ttf +0 -0
  99. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf +0 -0
  100. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-bolditalic.ttf +0 -0
  101. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-italic.ttf +0 -0
  102. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf +0 -0
  103. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-bold.ttf +0 -0
  104. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-boldoblique.ttf +0 -0
  105. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-demi-condensed-demicondensed.ttf +0 -0
  106. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-medium.ttf +0 -0
  107. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-oblique.ttf +0 -0
  108. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-bold.ttf +0 -0
  109. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-bolditalic.ttf +0 -0
  110. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-boldslanted.ttf +0 -0
  111. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-romanslanted.ttf +0 -0
  112. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf +0 -0
  113. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-roman.ttf +0 -0
  114. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-upright-italic-uprightitalic.ttf +0 -0
  115. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bold.ttf +0 -0
  116. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bolditalic.ttf +0 -0
  117. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-italic.ttf +0 -0
  118. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-light.ttf +0 -0
  119. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-lightoblique.ttf +0 -0
  120. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-regular.ttf +0 -0
  121. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-italic.ttf +0 -0
  122. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-medium.ttf +0 -0
  123. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/readme.txt +0 -0
  124. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/logo-small.png +0 -0
  125. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symbolcross.png +0 -0
  126. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symboldonut.png +0 -0
  127. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symbollollipop.png +0 -0
  128. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symboltriangle.png +0 -0
  129. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/dependency_links.txt +0 -0
  130. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/requires.txt +0 -0
  131. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/top_level.txt +0 -0
  132. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/tests/test.py +0 -0
  133. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/tests/test2.py +0 -0
  134. {kaxe-1.4.9.dev0 → kaxe-1.5.0}/tests/test3.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kaxe
3
- Version: 1.4.9.dev0
3
+ Version: 1.5.0
4
4
  Summary: A small graphing tool for functions, points, equations and more
5
5
  Author-email: Valter Yde Daugberg <valteryde@hotmail.com>
6
6
  Project-URL: Homepage, https://github.com/valteryde/kaxe
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kaxe"
3
- version = "1.4.9.dev0"
3
+ version = "1.5.0"
4
4
  authors = [
5
5
  { name="Valter Yde Daugberg", email="valteryde@hotmail.com" },
6
6
  ]
@@ -1,6 +1,7 @@
1
1
 
2
2
  from .point import Points2D
3
3
  from .equation import Equation
4
+ from .inequality import Inequality
4
5
  from .function import Function2D
5
6
  from .pillar import Pillars, Histogram
6
7
  from .map import HeatMap, ColorScale
@@ -0,0 +1,216 @@
1
+
2
+ from ...core.shapes import shapes
3
+ from ...core.color import to_rgba
4
+ from ...core.symbol import symbol
5
+ from ...plot import identities
6
+ from .equation import Equation
7
+
8
+ _OPS = {
9
+ '<=': lambda d: d > 0,
10
+ 'le': lambda d: d > 0,
11
+ '≤': lambda d: d > 0,
12
+ '<': lambda d: d >= 0,
13
+ 'lt': lambda d: d >= 0,
14
+ '>=': lambda d: d < 0,
15
+ 'ge': lambda d: d < 0,
16
+ '≥': lambda d: d < 0,
17
+ '>': lambda d: d <= 0,
18
+ 'gt': lambda d: d <= 0,
19
+ }
20
+
21
+
22
+ def _resolve_plot(parent):
23
+ from ...core.d3.translator import getEquivalent2DPlot
24
+
25
+ if getattr(parent, 'identity', None) == identities.XYZPLOT:
26
+ return getEquivalent2DPlot(parent)
27
+ return parent
28
+
29
+
30
+ def _eval_diff(parent, left, right, px, py):
31
+ try:
32
+ x, y = parent.inversepixel(px, py)
33
+ if x is None or y is None:
34
+ return None
35
+ return left(x, y) - right(x, y)
36
+ except (TypeError, ZeroDivisionError, ValueError):
37
+ return None
38
+
39
+
40
+ class Inequality:
41
+ """
42
+ A class to represent a two-variable inequality ``left op right``.
43
+
44
+ Draws the boundary curve (same as :class:`Equation`) and red diagonal
45
+ hatching on the forbidden side of the inequality.
46
+
47
+ Supported in classical plots, polar plot and 3D plots as a 2D object with ``z=0``.
48
+
49
+ Parameters
50
+ ----------
51
+ left : callable
52
+ Left side of the inequality.
53
+ right : callable
54
+ Right side of the inequality.
55
+ op : str, optional
56
+ Comparison operator: ``<=``, ``<``, ``>=``, or ``>`` (default is ``<=``).
57
+ color : tuple | list, optional
58
+ Boundary line color. Random if omitted.
59
+ width : int, optional
60
+ Boundary line thickness (default is 2).
61
+ hatch_color : tuple | list, optional
62
+ Color of forbidden-region hatching (default is red with transparency).
63
+ hatch_spacing : int, optional
64
+ Pixel spacing between parallel hatch lines (default is 10).
65
+ hatch_width : int, optional
66
+ Hatch line thickness (default is 1).
67
+ computePadding : int, optional
68
+ Extra padding when sampling the plot area (default is 50).
69
+
70
+ Examples
71
+ --------
72
+ >>> g = lambda x, y: x + y - 3
73
+ >>> ineq = Inequality(g, lambda x, y: 0)
74
+ >>> plt.add(ineq)
75
+ """
76
+
77
+ def __init__(
78
+ self,
79
+ left,
80
+ right,
81
+ op='<=',
82
+ color=None,
83
+ width=2,
84
+ hatch_color=(255, 0, 0, 180),
85
+ hatch_spacing=10,
86
+ hatch_width=1,
87
+ computePadding=50,
88
+ ):
89
+ self.left = left
90
+ self.right = right
91
+ self.computePadding = computePadding
92
+ self.hatch_spacing = hatch_spacing
93
+ self.hatch_width = hatch_width
94
+ self.hatch_color = to_rgba(hatch_color)
95
+
96
+ if op not in _OPS:
97
+ raise ValueError(f"Unsupported operator {op!r}; use one of {sorted(_OPS)}")
98
+ self.op = op
99
+ self._is_forbidden = _OPS[op]
100
+
101
+ self.boundary = Equation(left, right, color=color, width=width, computePadding=computePadding)
102
+ self.hatch_batch = shapes.Batch()
103
+ self.color = self.boundary.color
104
+ self.legendColor = self.boundary.legendColor
105
+ self.width = width
106
+
107
+ self.supports = [identities.XYPLOT, identities.POLAR, identities.XYZPLOT]
108
+
109
+ def __build_hatch__(self, parent):
110
+ box = parent.windowBox
111
+ x0 = box[0] - self.computePadding
112
+ x1 = box[2] + self.computePadding
113
+ y0 = box[1] - self.computePadding
114
+ y1 = box[3] + self.computePadding
115
+
116
+ width = x1 - x0
117
+ height = y1 - y0
118
+ spacing = self.hatch_spacing
119
+ sample_step = 2
120
+ eps = 1e-9
121
+
122
+ scale = getattr(parent, 'getVisualScale', lambda: 1.0)()
123
+ hatch_width = max(1, int(self.hatch_width * scale))
124
+
125
+ max_extent = int(width + height)
126
+ for offset in range(-int(height), int(width + height), spacing):
127
+ segment_start = None
128
+ last_point = None
129
+
130
+ for t in range(0, max_extent, sample_step):
131
+ px = x0 + t
132
+ py = y0 + t + offset
133
+
134
+ if px < x0 or px > x1 or py < y0 or py > y1:
135
+ if segment_start is not None and last_point is not None:
136
+ self.__add_hatch_segment__(segment_start, last_point, hatch_width)
137
+ segment_start = None
138
+ last_point = None
139
+ continue
140
+
141
+ if not parent.inside(px, py):
142
+ if segment_start is not None and last_point is not None:
143
+ self.__add_hatch_segment__(segment_start, last_point, hatch_width)
144
+ segment_start = None
145
+ last_point = None
146
+ continue
147
+
148
+ diff = _eval_diff(parent, self.left, self.right, px, py)
149
+ forbidden = diff is not None and abs(diff) >= eps and self._is_forbidden(diff)
150
+
151
+ if forbidden:
152
+ point = (px, py)
153
+ if segment_start is None:
154
+ segment_start = point
155
+ last_point = point
156
+ elif segment_start is not None and last_point is not None:
157
+ self.__add_hatch_segment__(segment_start, last_point, hatch_width)
158
+ segment_start = None
159
+ last_point = None
160
+
161
+ if segment_start is not None and last_point is not None:
162
+ self.__add_hatch_segment__(segment_start, last_point, hatch_width)
163
+
164
+ def __add_hatch_segment__(self, start, end, hatch_width):
165
+ if start == end:
166
+ return
167
+ shapes.Line(
168
+ start[0],
169
+ start[1],
170
+ end[0],
171
+ end[1],
172
+ color=self.hatch_color,
173
+ width=hatch_width,
174
+ batch=self.hatch_batch,
175
+ )
176
+
177
+ def finalize(self, parent):
178
+ from ...core.d3.translator import translate2DTo3DObjects, has3DReference
179
+
180
+ plot = _resolve_plot(parent)
181
+ self.boundary.finalize(plot)
182
+ self.__build_hatch__(plot)
183
+
184
+ if has3DReference(plot):
185
+ translate2DTo3DObjects(plot, self.hatch_batch)
186
+
187
+ def push(self, x, y):
188
+ self.hatch_batch.push(x, y)
189
+ self.boundary.push(x, y)
190
+
191
+ def draw(self, *args, **kwargs):
192
+ self.hatch_batch.draw(*args, **kwargs)
193
+ self.boundary.draw(*args, **kwargs)
194
+
195
+ def legend(self, text: str, symbol=symbol.LINE, color=None):
196
+ """
197
+ Adds a legend entry for this inequality.
198
+
199
+ Parameters
200
+ ----------
201
+ text : str
202
+ The text to display in the legend.
203
+ symbol : symbols, optional
204
+ The symbol to use in the legend.
205
+ color : optional
206
+ Legend color. Uses the boundary color if omitted.
207
+
208
+ Returns
209
+ -------
210
+ self
211
+ """
212
+ self.legendText = text
213
+ self.legendSymbol = symbol
214
+ if color:
215
+ self.legendColor = to_rgba(color)
216
+ return self
@@ -6,8 +6,9 @@ from ...core.shapes import shapes
6
6
  from ...core.text import Text
7
7
  from ...core.round import koundTeX
8
8
  from ...plot import identities
9
- from typing import Union
9
+ from typing import Callable, Union
10
10
  from ...core.color import Colormaps
11
+ from ...core.bounds import DEFAULT_DOMAIN_2D
11
12
 
12
13
 
13
14
  class ColorScale:
@@ -204,14 +205,97 @@ class HeatMap:
204
205
  else:
205
206
  self.maxValue = max([max(row) for row in self.data])
206
207
 
207
- self.farLeft = len(data[0]) * self.unitPerPixel[0]
208
208
  self.farRight = position[0]
209
- self.farTop = len(data) * self.unitPerPixel[1]
209
+ self.farLeft = position[0] + len(data[0]) * self.unitPerPixel[0]
210
210
  self.farBottom = position[1]
211
+ self.farTop = position[1] + len(data) * self.unitPerPixel[1]
211
212
 
212
213
  self.supports = [identities.XYPLOT]
213
214
 
214
-
215
+ @classmethod
216
+ def fromFunction(
217
+ cls,
218
+ f: Callable,
219
+ numSamples: int = 100,
220
+ domain=None,
221
+ cmap=Colormaps.standard,
222
+ minValue=None,
223
+ maxValue=None,
224
+ *args,
225
+ **kwargs,
226
+ ):
227
+ """
228
+ Build a heatmap by sampling a 2D function on a regular grid.
229
+
230
+ Parameters
231
+ ----------
232
+ f : callable
233
+ Function ``f(x, y)`` returning the value at each grid point.
234
+ May accept numpy arrays for vectorized evaluation.
235
+ numSamples : int, optional
236
+ Number of cells per axis (default is 100).
237
+ domain : tuple, optional
238
+ Placement region ``(x0, x1, y0, y1)`` in plot coordinates
239
+ (default is ``(-10, 10, -10, 10)``).
240
+ cmap : Colormap, optional
241
+ Colormap for value-to-color mapping.
242
+ minValue : float or int, optional
243
+ Minimum value for the color scale. Calculated from data if omitted.
244
+ maxValue : float or int, optional
245
+ Maximum value for the color scale. Calculated from data if omitted.
246
+ *args
247
+ Additional positional arguments passed to ``f``.
248
+ **kwargs
249
+ Additional keyword arguments passed to ``f``.
250
+
251
+ Returns
252
+ -------
253
+ HeatMap
254
+
255
+ Examples
256
+ --------
257
+ >>> import math
258
+ >>> hm = kaxe.HeatMap.fromFunction(
259
+ ... lambda x, y: math.sin(x) * math.cos(y),
260
+ ... numSamples=100,
261
+ ... domain=(-10, 10, -10, 10),
262
+ ... )
263
+ >>> plt.add(hm)
264
+ """
265
+ if domain is None:
266
+ domain = DEFAULT_DOMAIN_2D
267
+ x0, x1, y0, y1 = domain
268
+ n = numSamples
269
+ dx = (x1 - x0) / n
270
+ dy = (y1 - y0) / n
271
+
272
+ xs = np.linspace(x0 + dx / 2, x1 - dx / 2, n)
273
+ ys = np.linspace(y0 + dy / 2, y1 - dy / 2, n)
274
+
275
+ data = None
276
+ try:
277
+ x_grid, y_grid = np.meshgrid(xs, ys)
278
+ z_vals = np.asarray(f(x_grid, y_grid, *args, **kwargs), dtype=np.float64)
279
+ if z_vals.shape == (n, n):
280
+ data = z_vals.tolist()
281
+ except Exception:
282
+ pass
283
+
284
+ if data is None:
285
+ data = [
286
+ [float(f(x, y, *args, **kwargs)) for x in xs]
287
+ for y in ys
288
+ ]
289
+
290
+ return cls(
291
+ data,
292
+ cmap=cmap,
293
+ unitPerPixel=[dx, dy],
294
+ position=(x0, y0),
295
+ minValue=minValue,
296
+ maxValue=maxValue,
297
+ )
298
+
215
299
  def finalize(self, parent):
216
300
 
217
301
  # get size of one box
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kaxe
3
- Version: 1.4.9.dev0
3
+ Version: 1.5.0
4
4
  Summary: A small graphing tool for functions, points, equations and more
5
5
  Author-email: Valter Yde Daugberg <valteryde@hotmail.com>
6
6
  Project-URL: Homepage, https://github.com/valteryde/kaxe
@@ -60,6 +60,7 @@ src/kaxe/objects/d2/contour.py
60
60
  src/kaxe/objects/d2/equation.py
61
61
  src/kaxe/objects/d2/fill.py
62
62
  src/kaxe/objects/d2/function.py
63
+ src/kaxe/objects/d2/inequality.py
63
64
  src/kaxe/objects/d2/map.py
64
65
  src/kaxe/objects/d2/parameter.py
65
66
  src/kaxe/objects/d2/pillar.py
@@ -127,4 +128,5 @@ src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-med
127
128
  src/kaxe/resources/computer-modern-family/readme.txt
128
129
  tests/test.py
129
130
  tests/test2.py
130
- tests/test3.py
131
+ tests/test3.py
132
+ tests/test_5.py
@@ -0,0 +1,15 @@
1
+
2
+ import sys
3
+
4
+ sys.path.append('./src')
5
+
6
+ import kaxe
7
+
8
+ plt = kaxe.Plot()
9
+
10
+ f = lambda x,y: (x - 1) ** 2 + (y - 2) ** 2
11
+ g = lambda x,y: x + y - 3
12
+
13
+ plt.add(kaxe.Contour(f))
14
+ plt.add(kaxe.Inequality(g, lambda x,y: 0, hatch_spacing=50))
15
+ plt.show()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes