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.
- {kaxe-1.4.9.dev0/src/kaxe.egg-info → kaxe-1.5.0}/PKG-INFO +1 -1
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/pyproject.toml +1 -1
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/__init__.py +1 -0
- kaxe-1.5.0/src/kaxe/objects/d2/inequality.py +216 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/map.py +88 -4
- {kaxe-1.4.9.dev0 → kaxe-1.5.0/src/kaxe.egg-info}/PKG-INFO +1 -1
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/SOURCES.txt +3 -1
- kaxe-1.5.0/tests/test_5.py +15 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/LICENSE +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/MANIFEST.in +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/README.md +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/setup.cfg +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/bar.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/box.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/pie.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/chart/qqplot.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/axis.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/bounds.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/color.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/backend.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/camera.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/helper.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/hud.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/color.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/line.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/point.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/pointer.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/objects/triangle.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/openglrender.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/d3/translator.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/draw.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/fileloader.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/helper.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/legend.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/line.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/marker.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/profiler.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/round.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/shapes.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/styles.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/svg.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/svg_pdf.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/symbol.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/text.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/core/window.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/data/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/data/excel.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/_lazy.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/arrow.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/bubble.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/contour.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/equation.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/fill.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/function.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/parameter.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/pillar.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d2/point.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/base.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/function.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/mesh.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/point.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/d3/potato.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/function.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/legend.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/mapdata.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/point.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/objects/text.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/_lazy.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/box.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/constants.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/axes.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/geometry.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/plot3d.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/d3/variants.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/double.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/empty.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/grid.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/log.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/polar.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/standard.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/themes.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/zoom.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/plot/zoom_connector.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/__init__.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-semibold.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-semiboldoblique.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.classical-serif-italic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-bolditalic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-italic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-bold.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-boldoblique.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-demi-condensed-demicondensed.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-medium.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-oblique.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-bold.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-bolditalic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-boldslanted.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-romanslanted.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-roman.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-upright-italic-uprightitalic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bold.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bolditalic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-italic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-light.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-lightoblique.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-regular.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-italic.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-medium.ttf +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/readme.txt +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/logo-small.png +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symbolcross.png +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symboldonut.png +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symbollollipop.png +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/symboltriangle.png +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/dependency_links.txt +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/requires.txt +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe.egg-info/top_level.txt +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/tests/test.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/tests/test2.py +0 -0
- {kaxe-1.4.9.dev0 → kaxe-1.5.0}/tests/test3.py +0 -0
|
@@ -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.
|
|
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
|
|
@@ -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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.bright-semibold.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-bolditalic.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-italic.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-bold.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-medium.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-oblique.ttf
RENAMED
|
File without changes
|
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-bolditalic.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.9.dev0 → kaxe-1.5.0}/src/kaxe/resources/computer-modern-family/cmu.serif-roman.ttf
RENAMED
|
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
|