maidr 1.2.0__py3-none-any.whl → 1.2.2__py3-none-any.whl
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.
- maidr/__init__.py +1 -1
- maidr/core/plot/lineplot.py +44 -30
- maidr/patch/lineplot.py +28 -18
- {maidr-1.2.0.dist-info → maidr-1.2.2.dist-info}/METADATA +1 -1
- {maidr-1.2.0.dist-info → maidr-1.2.2.dist-info}/RECORD +7 -7
- {maidr-1.2.0.dist-info → maidr-1.2.2.dist-info}/LICENSE +0 -0
- {maidr-1.2.0.dist-info → maidr-1.2.2.dist-info}/WHEEL +0 -0
maidr/__init__.py
CHANGED
maidr/core/plot/lineplot.py
CHANGED
|
@@ -8,6 +8,7 @@ from maidr.core.enum.plot_type import PlotType
|
|
|
8
8
|
from maidr.core.plot.maidr_plot import MaidrPlot
|
|
9
9
|
from maidr.exception.extraction_error import ExtractionError
|
|
10
10
|
from maidr.util.mixin.extractor_mixin import LineExtractorMixin
|
|
11
|
+
import uuid
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class MultiLinePlot(MaidrPlot, LineExtractorMixin):
|
|
@@ -42,62 +43,75 @@ class MultiLinePlot(MaidrPlot, LineExtractorMixin):
|
|
|
42
43
|
super().__init__(ax, PlotType.LINE)
|
|
43
44
|
|
|
44
45
|
def _get_selector(self) -> Union[str, List[str]]:
|
|
45
|
-
|
|
46
|
+
# Return selectors for all lines that have data
|
|
47
|
+
all_lines = self.ax.get_lines()
|
|
48
|
+
if not all_lines:
|
|
49
|
+
return ["g[maidr='true'] > path"]
|
|
50
|
+
|
|
51
|
+
selectors = []
|
|
52
|
+
for line in all_lines:
|
|
53
|
+
# Only create selectors for lines that have data (same logic as _extract_line_data)
|
|
54
|
+
xydata = line.get_xydata()
|
|
55
|
+
if xydata is None or not xydata.size: # type: ignore
|
|
56
|
+
continue
|
|
57
|
+
gid = line.get_gid()
|
|
58
|
+
if gid:
|
|
59
|
+
selectors.append(f"g[id='{gid}'] path")
|
|
60
|
+
else:
|
|
61
|
+
selectors.append("g[maidr='true'] > path")
|
|
62
|
+
|
|
63
|
+
if not selectors:
|
|
64
|
+
return ["g[maidr='true'] > path"]
|
|
65
|
+
|
|
66
|
+
return selectors
|
|
46
67
|
|
|
47
|
-
def _extract_plot_data(self) ->
|
|
48
|
-
|
|
49
|
-
data = self._extract_line_data(plot)
|
|
68
|
+
def _extract_plot_data(self) -> Union[List[List[dict]], None]:
|
|
69
|
+
data = self._extract_line_data()
|
|
50
70
|
|
|
51
71
|
if data is None:
|
|
52
|
-
raise ExtractionError(self.type,
|
|
72
|
+
raise ExtractionError(self.type, None)
|
|
53
73
|
|
|
54
74
|
return data
|
|
55
75
|
|
|
56
|
-
def _extract_line_data(
|
|
57
|
-
self, plot: Union[List[Line2D], None]
|
|
58
|
-
) -> Union[List[dict], None]:
|
|
76
|
+
def _extract_line_data(self) -> Union[List[List[dict]], None]:
|
|
59
77
|
"""
|
|
60
|
-
Extract data from
|
|
61
|
-
|
|
62
|
-
Parameters
|
|
63
|
-
----------
|
|
64
|
-
plot : list[Line2D] | None
|
|
65
|
-
List of Line2D objects to extract data from.
|
|
78
|
+
Extract data from all line objects and return as separate arrays.
|
|
66
79
|
|
|
67
80
|
Returns
|
|
68
81
|
-------
|
|
69
|
-
list[dict] | None
|
|
70
|
-
List of dictionaries
|
|
71
|
-
or None if the plot data is invalid.
|
|
82
|
+
list[list[dict]] | None
|
|
83
|
+
List of lists, where each inner list contains dictionaries with x,y coordinates
|
|
84
|
+
and line identifiers for one line, or None if the plot data is invalid.
|
|
72
85
|
"""
|
|
73
|
-
|
|
86
|
+
all_lines = self.ax.get_lines()
|
|
87
|
+
if not all_lines:
|
|
74
88
|
return None
|
|
75
89
|
|
|
76
|
-
|
|
90
|
+
all_lines_data = []
|
|
77
91
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if
|
|
92
|
+
for line in all_lines:
|
|
93
|
+
xydata = line.get_xydata()
|
|
94
|
+
if xydata is None or not xydata.size: # type: ignore
|
|
81
95
|
continue
|
|
82
96
|
|
|
83
|
-
# Tag the element for highlighting
|
|
84
97
|
self._elements.append(line)
|
|
85
98
|
|
|
86
|
-
#
|
|
99
|
+
# Assign unique GID to each line if not already set
|
|
100
|
+
if line.get_gid() is None:
|
|
101
|
+
unique_gid = f"maidr-{uuid.uuid4()}"
|
|
102
|
+
line.set_gid(unique_gid)
|
|
87
103
|
|
|
88
104
|
label: str = line.get_label() # type: ignore
|
|
89
105
|
line_data = [
|
|
90
106
|
{
|
|
91
107
|
MaidrKey.X: float(x),
|
|
92
108
|
MaidrKey.Y: float(y),
|
|
93
|
-
# Replace labels starting with '_child'
|
|
94
|
-
# with an empty string to exclude
|
|
95
|
-
# internal or non-relevant labels from being used as identifiers.
|
|
96
109
|
MaidrKey.FILL: (label if not label.startswith("_child") else ""),
|
|
97
110
|
}
|
|
98
111
|
for x, y in line.get_xydata() # type: ignore
|
|
99
112
|
]
|
|
100
|
-
if len(line_data) > 0:
|
|
101
|
-
all_line_data.append(line_data)
|
|
102
113
|
|
|
103
|
-
|
|
114
|
+
if line_data:
|
|
115
|
+
all_lines_data.append(line_data)
|
|
116
|
+
|
|
117
|
+
return all_lines_data if all_lines_data else None
|
maidr/patch/lineplot.py
CHANGED
|
@@ -7,29 +7,39 @@ from matplotlib.lines import Line2D
|
|
|
7
7
|
from maidr.core.enum import PlotType
|
|
8
8
|
from maidr.patch.common import common
|
|
9
9
|
from maidr.core.enum.smooth_keywords import SMOOTH_KEYWORDS
|
|
10
|
+
from maidr.core.context_manager import ContextManager
|
|
11
|
+
from maidr.core.figure_manager import FigureManager
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
def line(wrapped, instance, args, kwargs) -> Axes | list[Line2D]:
|
|
13
15
|
"""
|
|
14
|
-
Wrapper
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
----------
|
|
18
|
-
wrapped : callable
|
|
19
|
-
The wrapped function (plot or lineplot)
|
|
20
|
-
instance : object
|
|
21
|
-
The object to which the wrapped function belongs
|
|
22
|
-
args : tuple
|
|
23
|
-
Positional arguments passed to the wrapped function
|
|
24
|
-
kwargs : dict
|
|
25
|
-
Keyword arguments passed to the wrapped function
|
|
26
|
-
|
|
27
|
-
Returns
|
|
28
|
-
-------
|
|
29
|
-
Axes | list[Line2D]
|
|
30
|
-
The result of the wrapped function after processing
|
|
16
|
+
Wrapper for line plotting functions that creates a single MAIDR plot per axes to handle
|
|
17
|
+
multiline plots (matplotlib) and single-call plots (seaborn) correctly by preventing
|
|
18
|
+
multiple MAIDR layers and using internal context to avoid cyclic processing.
|
|
31
19
|
"""
|
|
32
|
-
|
|
20
|
+
# Don't proceed if the call is made internally by the patched function.
|
|
21
|
+
if ContextManager.is_internal_context():
|
|
22
|
+
return wrapped(*args, **kwargs)
|
|
23
|
+
|
|
24
|
+
# Set the internal context to avoid cyclic processing.
|
|
25
|
+
with ContextManager.set_internal_context():
|
|
26
|
+
# Patch the plotting function.
|
|
27
|
+
plot = wrapped(*args, **kwargs)
|
|
28
|
+
|
|
29
|
+
# Get the axes from the plot result (works for both matplotlib and seaborn)
|
|
30
|
+
ax = FigureManager.get_axes(plot)
|
|
31
|
+
if ax is None:
|
|
32
|
+
# If we can't get axes from plot, try from instance
|
|
33
|
+
ax = instance if isinstance(instance, Axes) else getattr(instance, "axes", None)
|
|
34
|
+
|
|
35
|
+
# Check if a MAIDR plot already exists for this axes
|
|
36
|
+
if ax is not None and not hasattr(ax, "_maidr_plot_created"):
|
|
37
|
+
# Create MAIDR plot only once for this axes using common()
|
|
38
|
+
common(PlotType.LINE, lambda *a, **k: plot, instance, args, kwargs)
|
|
39
|
+
# Mark that a MAIDR plot has been created for this axes
|
|
40
|
+
setattr(ax, "_maidr_plot_created", True)
|
|
41
|
+
|
|
42
|
+
return plot
|
|
33
43
|
|
|
34
44
|
|
|
35
45
|
# Patch matplotlib function.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: maidr
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: Multimodal Access and Interactive Data Representations
|
|
5
5
|
License: GPL-3.0-or-later
|
|
6
6
|
Keywords: accessibility,visualization,sonification,braille,tactile,multimodal,data representation,blind,low vision,visual impairments
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
maidr/__init__.py,sha256=
|
|
1
|
+
maidr/__init__.py,sha256=8RJF5FjMzhNWOpVQkU_BCfkLKaWvTrrQeTIat9_SXJE,399
|
|
2
2
|
maidr/api.py,sha256=F43mXWsxc7tHdlZqbRlEWkc-RjJVo_zgxCn3NiLBY58,1764
|
|
3
3
|
maidr/core/__init__.py,sha256=WgxLpSEYMc4k3OyEOf1shOxfEq0ASzppEIZYmE91ThQ,25
|
|
4
4
|
maidr/core/context_manager.py,sha256=6cT7ZGOApSpC-SLD2XZWWU_H08i-nfv-JUlzXOtvWYw,3374
|
|
@@ -16,7 +16,7 @@ maidr/core/plot/candlestick.py,sha256=8YKjNmxJx7TEvaH5v4lYDzA11VHpVHpZrv9EJG2Ter
|
|
|
16
16
|
maidr/core/plot/grouped_barplot.py,sha256=bRcQcvwkF3Q3aZ3PlhbZ6bHI_AfcqdKUMVvlLL94wXM,2078
|
|
17
17
|
maidr/core/plot/heatmap.py,sha256=yMS-31tS2GW4peds9LtZesMxmmTV_YfqYO5M_t5KasQ,2521
|
|
18
18
|
maidr/core/plot/histogram.py,sha256=QV5W-6ZJQQcZsrM91JJBX-ONktJzH7yg_et5_bBPfQQ,1525
|
|
19
|
-
maidr/core/plot/lineplot.py,sha256=
|
|
19
|
+
maidr/core/plot/lineplot.py,sha256=C3xz6uWXYM_mbTq_geb5bP0JdvhcQf6cpfTs78Y6fCM,3852
|
|
20
20
|
maidr/core/plot/maidr_plot.py,sha256=B6hjsu-jSWlevEqJawgwjMOJr51nBBNh7yqJdSTkNhw,3681
|
|
21
21
|
maidr/core/plot/maidr_plot_factory.py,sha256=5SC8Nc3IfVYn-jQU_SD9vw7R5yhTHTBgQwGnAc7_DmA,2507
|
|
22
22
|
maidr/core/plot/regplot.py,sha256=b7u6bGTz1IxKahplNUrfwIr_OGSwMJ2BuLgFAVjL0s0,2744
|
|
@@ -33,7 +33,7 @@ maidr/patch/heatmap.py,sha256=uxLLg530Ql9KVC5rxk8vnwPHXBWWHwYgJRkyHY-tJzs,1048
|
|
|
33
33
|
maidr/patch/highlight.py,sha256=I1dGFHJAnVd0AHVnMJzk_TE8BC8Uv-I6fTzSrJLU5QM,1155
|
|
34
34
|
maidr/patch/histogram.py,sha256=k3N0RUf1SQ2402pwbaY5QyS98KnLWvr9glCHQw9NTko,2378
|
|
35
35
|
maidr/patch/kdeplot.py,sha256=qv-OKzuop2aTrkZgUe2OnLxvV-KMyeXt1Td0_uZeHzE,2338
|
|
36
|
-
maidr/patch/lineplot.py,sha256=
|
|
36
|
+
maidr/patch/lineplot.py,sha256=og42V0tWBKCnf6idT3pLsIj3QBvKjg8aUN-k1udPRVw,1901
|
|
37
37
|
maidr/patch/regplot.py,sha256=Ciz43C5XZfWK6wtVWrlV0WNz4R__rcgdqVE9OCaXXRk,3236
|
|
38
38
|
maidr/patch/scatterplot.py,sha256=kln6zZwjVsdQzICalo-RnBOJrx1BnIB2xYUwItHvSNY,525
|
|
39
39
|
maidr/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -46,7 +46,7 @@ maidr/util/regression_line_utils.py,sha256=P8RQLixTby2JLz73XZgNiu96C2Ct3pNe4ENRW
|
|
|
46
46
|
maidr/util/svg_utils.py,sha256=2gyzBtNKFHs0utrw1iOlxTmznzivOWQMV2aW8zu2c8E,1442
|
|
47
47
|
maidr/widget/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
48
|
maidr/widget/shiny.py,sha256=wrrw2KAIpE_A6CNQGBtNHauR1DjenA_n47qlFXX9_rk,745
|
|
49
|
-
maidr-1.2.
|
|
50
|
-
maidr-1.2.
|
|
51
|
-
maidr-1.2.
|
|
52
|
-
maidr-1.2.
|
|
49
|
+
maidr-1.2.2.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
50
|
+
maidr-1.2.2.dist-info/METADATA,sha256=Nd6NYe790oDdPYo_iu51Uk18cOOSKZFw3845AI_MKec,2796
|
|
51
|
+
maidr-1.2.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
52
|
+
maidr-1.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|