maidr 0.14.0__py3-none-any.whl → 0.16.0__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 CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.14.0"
1
+ __version__ = "0.16.0"
2
2
 
3
3
  from .api import close, render, save_html, set_engine, show, stacked
4
4
  from .core import Maidr
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
- from typing import Any
2
+
3
3
  import threading
4
+ from typing import Any
4
5
 
5
6
  from matplotlib.artist import Artist
6
7
  from matplotlib.axes import Axes
@@ -57,17 +58,16 @@ class FigureManager:
57
58
  raise ValueError(f"No figure found for axis: {ax}.")
58
59
 
59
60
  # Add plot to the Maidr object associated with the plot's figure.
60
- maidr = cls._get_maidr(ax.get_figure())
61
+ maidr = cls._get_maidr(ax.get_figure(), plot_type)
61
62
  plot = MaidrPlotFactory.create(ax, plot_type, **kwargs)
62
63
  maidr.plots.append(plot)
63
-
64
64
  return maidr
65
65
 
66
66
  @classmethod
67
- def _get_maidr(cls, fig: Figure) -> Maidr:
67
+ def _get_maidr(cls, fig: Figure, plot_type: PlotType) -> Maidr:
68
68
  """Retrieve or create a Maidr instance for the given Figure."""
69
69
  if fig not in cls.figs.keys():
70
- cls.figs[fig] = Maidr(fig)
70
+ cls.figs[fig] = Maidr(fig, plot_type)
71
71
  return cls.figs[fig]
72
72
 
73
73
  @classmethod
maidr/core/maidr.py CHANGED
@@ -14,6 +14,7 @@ from matplotlib.figure import Figure
14
14
 
15
15
  from maidr.core.context_manager import HighlightContextManager
16
16
  from maidr.core.enum.maidr_key import MaidrKey
17
+ from maidr.core.enum.plot_type import PlotType
17
18
  from maidr.core.plot import MaidrPlot
18
19
  from maidr.util.environment import Environment
19
20
 
@@ -39,12 +40,13 @@ class Maidr:
39
40
  Displays the rendered HTML content in the specified rendering context.
40
41
  """
41
42
 
42
- def __init__(self, fig: Figure) -> None:
43
+ def __init__(self, fig: Figure, plot_type: PlotType = PlotType.LINE) -> None:
43
44
  """Create a new Maidr for the given ``matplotlib.figure.Figure``."""
44
45
  self._fig = fig
45
46
  self._plots = []
46
47
  self.maidr_id = None
47
48
  self.selector_id = Maidr._unique_id()
49
+ self.plot_type = plot_type
48
50
 
49
51
  @property
50
52
  def fig(self) -> Figure:
@@ -137,6 +139,8 @@ class Maidr:
137
139
 
138
140
  def _flatten_maidr(self) -> dict | list[dict]:
139
141
  """Return a single plot schema or a list of schemas from the Maidr instance."""
142
+ if self.plot_type == PlotType.LINE:
143
+ self._plots = [self._plots[0]]
140
144
  maidr = [plot.schema for plot in self._plots]
141
145
 
142
146
  # Replace the selector having maidr='true' with maidr={self.maidr_id}
@@ -16,7 +16,7 @@ from maidr.util.mixin import (
16
16
  class GroupedBarPlot(
17
17
  MaidrPlot, ContainerExtractorMixin, LevelExtractorMixin, DictMergerMixin
18
18
  ):
19
- def __init__(self, ax: Axes, plot_type: PlotType) -> None:
19
+ def __init__(self, ax: Axes, plot_type: PlotType, **kwargs) -> None:
20
20
  super().__init__(ax, plot_type)
21
21
  self._support_highlighting = False
22
22
 
@@ -1,45 +1,102 @@
1
- from __future__ import annotations
2
-
3
1
  from matplotlib.axes import Axes
4
2
  from matplotlib.lines import Line2D
5
3
 
6
- from maidr.core.enum import MaidrKey, PlotType
7
- from maidr.core.plot import MaidrPlot
8
- from maidr.exception import ExtractionError
4
+ from maidr.core.enum.maidr_key import MaidrKey
5
+ from maidr.core.enum.plot_type import PlotType
6
+ from maidr.core.plot.maidr_plot import MaidrPlot
7
+ from maidr.exception.extraction_error import ExtractionError
9
8
  from maidr.util.environment import Environment
10
- from maidr.util.mixin import LineExtractorMixin
9
+ from maidr.util.mixin.extractor_mixin import LineExtractorMixin
10
+
11
+
12
+ class MultiLinePlot(MaidrPlot, LineExtractorMixin):
13
+ """
14
+ A class for extracting and processing data from line plots.
15
+
16
+ This class can handle both single-line and multi-line plots, extracting
17
+ coordinate data and line identifiers. It processes matplotlib Line2D objects
18
+ and converts them into structured data for further processing or visualization.
19
+
20
+ Parameters
21
+ ----------
22
+ ax : Axes
23
+ The matplotlib axes object containing the line plot(s).
24
+ **kwargs : dict
25
+ Additional keyword arguments to pass to the parent class.
26
+
27
+ Attributes
28
+ ----------
29
+ type : PlotType
30
+ Set to PlotType.LINE to identify this as a line plot.
11
31
 
32
+ Notes
33
+ -----
34
+ - When using the JavaScript engine, only single-line plots are supported.
35
+ - For multi-line plots, use the TypeScript engine.
36
+ - The extracted data structure includes x, y coordinates and line identifiers
37
+ (fill values) for each point.
38
+ """
12
39
 
13
- class LinePlot(MaidrPlot, LineExtractorMixin):
14
- def __init__(self, ax: Axes) -> None:
40
+ def __init__(self, ax: Axes, **kwargs):
15
41
  super().__init__(ax, PlotType.LINE)
16
42
 
17
43
  def _get_selector(self) -> str:
18
44
  return "g[maidr='true'] > path"
19
45
 
20
46
  def _extract_plot_data(self) -> list[dict]:
21
- plot = self.extract_line(self.ax)
47
+ plot = self.extract_lines(self.ax)
22
48
  data = self._extract_line_data(plot)
23
49
  engine = Environment.get_engine()
24
- if engine == "ts":
25
- data = [data]
50
+ if engine == "js":
51
+ if len(data) > 1:
52
+ raise Exception(
53
+ "MultiLine Plot not supported in JS. Use TypeScript Engine for this plot!"
54
+ )
55
+ data = data[0]
26
56
 
27
57
  if data is None:
28
58
  raise ExtractionError(self.type, plot)
29
59
 
30
60
  return data
31
61
 
32
- def _extract_line_data(self, plot: Line2D | None) -> list[dict] | None:
33
- if plot is None or plot.get_xydata() is None:
62
+ def _extract_line_data(self, plot: list[Line2D] | None) -> list[dict] | None:
63
+ """
64
+ Extract data from multiple line objects.
65
+
66
+ Parameters
67
+ ----------
68
+ plot : list[Line2D] | None
69
+ List of Line2D objects to extract data from.
70
+
71
+ Returns
72
+ -------
73
+ list[dict] | None
74
+ List of dictionaries containing x,y coordinates and line identifiers,
75
+ or None if the plot data is invalid.
76
+ """
77
+ if plot is None or len(plot) == 0:
34
78
  return None
35
79
 
36
- # Tag the elements for highlighting.
37
- self._elements.append(plot)
80
+ all_line_data = []
81
+
82
+ # Process each line in the plot
83
+ for i, line in enumerate(plot):
84
+ if line.get_xydata() is None:
85
+ continue
86
+
87
+ # Tag the element for highlighting
88
+ self._elements.append(line)
89
+
90
+ # Extract data from this line
91
+ line_data = [
92
+ {
93
+ MaidrKey.X: float(x),
94
+ MaidrKey.Y: float(y),
95
+ MaidrKey.FILL: line.get_label(),
96
+ }
97
+ for x, y in line.get_xydata() # type: ignore
98
+ ]
99
+
100
+ all_line_data.append(line_data)
38
101
 
39
- return [
40
- {
41
- MaidrKey.X: float(x),
42
- MaidrKey.Y: float(y),
43
- }
44
- for x, y in plot.get_xydata()
45
- ]
102
+ return all_line_data if all_line_data else None
@@ -8,7 +8,7 @@ from maidr.core.plot.boxplot import BoxPlot
8
8
  from maidr.core.plot.grouped_barplot import GroupedBarPlot
9
9
  from maidr.core.plot.heatmap import HeatPlot
10
10
  from maidr.core.plot.histogram import HistPlot
11
- from maidr.core.plot.lineplot import LinePlot
11
+ from maidr.core.plot.lineplot import MultiLinePlot
12
12
  from maidr.core.plot.maidr_plot import MaidrPlot
13
13
  from maidr.core.plot.scatterplot import ScatterPlot
14
14
 
@@ -39,7 +39,7 @@ class MaidrPlotFactory:
39
39
  elif PlotType.HIST == plot_type:
40
40
  return HistPlot(ax)
41
41
  elif PlotType.LINE == plot_type:
42
- return LinePlot(ax)
42
+ return MultiLinePlot(ax)
43
43
  elif PlotType.SCATTER == plot_type:
44
44
  return ScatterPlot(ax)
45
45
  elif PlotType.DODGED == plot_type or PlotType.STACKED == plot_type:
maidr/patch/lineplot.py CHANGED
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import wrapt
4
-
5
4
  from matplotlib.axes import Axes
6
5
  from matplotlib.lines import Line2D
7
6
 
@@ -10,6 +9,25 @@ from maidr.patch.common import common
10
9
 
11
10
 
12
11
  def line(wrapped, instance, args, kwargs) -> Axes | list[Line2D]:
12
+ """
13
+ Wrapper function for line plotting functions in matplotlib and seaborn.
14
+
15
+ Parameters
16
+ ----------
17
+ wrapped : callable
18
+ The wrapped function (plot or lineplot)
19
+ instance : object
20
+ The object to which the wrapped function belongs
21
+ args : tuple
22
+ Positional arguments passed to the wrapped function
23
+ kwargs : dict
24
+ Keyword arguments passed to the wrapped function
25
+
26
+ Returns
27
+ -------
28
+ Axes | list[Line2D]
29
+ The result of the wrapped function after processing
30
+ """
13
31
  return common(PlotType.LINE, wrapped, instance, args, kwargs)
14
32
 
15
33
 
@@ -1,4 +1,5 @@
1
1
  from __future__ import annotations
2
+
2
3
  from typing import Any
3
4
 
4
5
  from matplotlib.axes import Axes
@@ -64,6 +65,16 @@ class LineExtractorMixin:
64
65
  # `maidr` package supports the same.
65
66
  return ax.get_lines()[-1]
66
67
 
68
+ @staticmethod
69
+ def extract_lines(ax: Axes) -> list[Line2D] | None:
70
+ """Retrieve all line objects from Axes, if available."""
71
+ if ax is None or ax.get_lines() is None:
72
+ return None
73
+
74
+ # Since the upstream MaidrJS library currently supports only the last plot line,
75
+ # `maidr` package supports the same.
76
+ return ax.get_lines()
77
+
67
78
 
68
79
  class CollectionExtractorMixin:
69
80
  @staticmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: maidr
3
- Version: 0.14.0
3
+ Version: 0.16.0
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=YHLH1St1nSRY7D2GUwqgZPSgGdYODkUylSw3xzDwsqQ,369
1
+ maidr/__init__.py,sha256=c9XIJcwH7iiFKgL4lkZi08iLSDirzPxVAx3Uz1I9ATs,369
2
2
  maidr/api.py,sha256=u2WOQ8RWmXpzseEgbZJCB7FFZs7cEy-ya-Q18tGAYB4,1350
3
3
  maidr/core/__init__.py,sha256=WgxLpSEYMc4k3OyEOf1shOxfEq0ASzppEIZYmE91ThQ,25
4
4
  maidr/core/context_manager.py,sha256=HSzD4wpiALdI4Vm0QTdWqi1MWR5Uqy8BX_lOlCM3JYY,3463
@@ -6,17 +6,17 @@ maidr/core/enum/__init__.py,sha256=9ee78L0dlxEx4ulUGVlD-J23UcUZmrGu0rXms54up3c,9
6
6
  maidr/core/enum/library.py,sha256=e8ujT_L-McJWfoVJd1ty9K_2bwITnf1j0GPLsnAcHes,104
7
7
  maidr/core/enum/maidr_key.py,sha256=LNtt74d2gurefDNPD3SLLsTxKqO9qTyo3PBAUAyofnc,736
8
8
  maidr/core/enum/plot_type.py,sha256=pyfyIwlq3taqe2Z1sVUSbMsTp5QTvYBlZXsMMMclEVM,293
9
- maidr/core/figure_manager.py,sha256=HyYLIX3QzE-PmatSsTez9MmncTEu0wzPdFktZzE3NQM,3891
10
- maidr/core/maidr.py,sha256=9x1-CTvp7RGnEZTUdWleruxSM6Rsou3pQr_VI9IijnI,11511
9
+ maidr/core/figure_manager.py,sha256=rd8XEwqNmfKu1I9zGD1p9g3wVlkMYNCrdLLCg4IzlfQ,3934
10
+ maidr/core/maidr.py,sha256=G7ACqroX80F9z4-tJj6-YFcjvv9--A-qrmH1Syp4jgQ,11717
11
11
  maidr/core/plot/__init__.py,sha256=xDIpRGM-4DfaSSL3nKcXrjdMecCHJ6en4K4nA_fPefQ,83
12
12
  maidr/core/plot/barplot.py,sha256=DGiMbakzER-Czpzekw-yBHXZuzWpBg7ODtJPQ8voI04,2605
13
13
  maidr/core/plot/boxplot.py,sha256=roADG8xJYRQlZPYbfGBQSQRw8974lhVnngGKEKXJttk,6090
14
- maidr/core/plot/grouped_barplot.py,sha256=pRmSAr6obcdjK4PPOt7-U77tMMKLM4lkKOiOklS8TbA,2061
14
+ maidr/core/plot/grouped_barplot.py,sha256=tAiOWwtfsWDwyGdUuCdQ6-f8UQxnsDDwpN30Skk8p-U,2071
15
15
  maidr/core/plot/heatmap.py,sha256=_Hn_wXsu-BQBYs4YO440-WRhmXAJ1WeBndBGVEUAP5M,2447
16
16
  maidr/core/plot/histogram.py,sha256=QV5W-6ZJQQcZsrM91JJBX-ONktJzH7yg_et5_bBPfQQ,1525
17
- maidr/core/plot/lineplot.py,sha256=TAqajxACVjs8ydIf_AiqUzwnfPdFydHhxc_TGDFsxcc,1282
17
+ maidr/core/plot/lineplot.py,sha256=5FKgT4s6l9Y7Lb7ELJ4SqMo0ItqimEhbKMgoVG_Rmu8,3242
18
18
  maidr/core/plot/maidr_plot.py,sha256=_9Ugn3cUwi-URxeTRbDAKDZwASrB65p9TKOXhFX1zbU,3176
19
- maidr/core/plot/maidr_plot_factory.py,sha256=Ai-vFpn9YhZPQeVQxdjq0prVJNcGZ8NJvS3eKAxxZ_w,1681
19
+ maidr/core/plot/maidr_plot_factory.py,sha256=QGcHK_oquY_M2_KJVEtc5-rBAD-gm7KI1kSD7cduHzg,1691
20
20
  maidr/core/plot/scatterplot.py,sha256=sQhT80w0Sp9AsUAZi4v6lfWsHJAvuFcer2aAE2NpAYE,1240
21
21
  maidr/exception/__init__.py,sha256=PzaXoYBhyZxMDcJkuxJugDx7jZeseI0El6LpxIwXyG4,46
22
22
  maidr/exception/extraction_error.py,sha256=rd37Oxa9gn2OWFWt9AOH5fv0hNd3sAWGvpDMFBuJY2I,607
@@ -28,16 +28,16 @@ maidr/patch/common.py,sha256=bRe4jruUvCIwp1t1E8Q3OuQ0eEyHgpMjXVpsPBZj4C8,843
28
28
  maidr/patch/heatmap.py,sha256=uxLLg530Ql9KVC5rxk8vnwPHXBWWHwYgJRkyHY-tJzs,1048
29
29
  maidr/patch/highlight.py,sha256=2DOO1tLDpXDtGd8DAPpnDOtq2_rWViPS7IDn9TbBXyA,925
30
30
  maidr/patch/histogram.py,sha256=tnyKkTMuzDXdyQBywhpHZgH3i2mXzOCSyfUSRM0tfUg,1315
31
- maidr/patch/lineplot.py,sha256=AIVsEPXMlkyUfYJ2xcU0GtZLpykEhHDLVFZjYnWCq9U,492
31
+ maidr/patch/lineplot.py,sha256=_EyqOp8BcO-kGq9sn8PyNQ8-Bz0FsnHAufXRkTGQzBw,1025
32
32
  maidr/patch/scatterplot.py,sha256=JZJXy3vWbJgzZh2zysNrqSA7MRcfSCms6lr_MY5CMD0,526
33
33
  maidr/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  maidr/util/environment.py,sha256=xtfibTH4RXW2GC7R_9OQo119BTe5M3bx0u13eFZaiZs,4554
35
35
  maidr/util/mixin/__init__.py,sha256=aGJZNhtWh77yIVPc7ipIZm1OajigjMtCWYKPuDWTC-c,217
36
- maidr/util/mixin/extractor_mixin.py,sha256=Y-34424UR8ECHECAuQZ7zKhyk5QC6GOiUeCMRhI06QQ,3132
36
+ maidr/util/mixin/extractor_mixin.py,sha256=lOVDaNsHnOS2aYxiGXAigGjt8WXzcer9MocaipcOh60,3511
37
37
  maidr/util/mixin/merger_mixin.py,sha256=V0qLw_6DUB7X6CQ3BCMpsCQX_ZuwAhoSTm_E4xAJFKM,712
38
38
  maidr/widget/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
39
  maidr/widget/shiny.py,sha256=wrrw2KAIpE_A6CNQGBtNHauR1DjenA_n47qlFXX9_rk,745
40
- maidr-0.14.0.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
41
- maidr-0.14.0.dist-info/METADATA,sha256=2wr_G1PtwvMel2JVhADxYONzNHFPpEBbtyDe7zNIwNc,2688
42
- maidr-0.14.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
43
- maidr-0.14.0.dist-info/RECORD,,
40
+ maidr-0.16.0.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
41
+ maidr-0.16.0.dist-info/METADATA,sha256=i1WmNwRomAMP244eEJoCaTUyuGhaWQWsm96MKL5K0RY,2688
42
+ maidr-0.16.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
43
+ maidr-0.16.0.dist-info/RECORD,,
File without changes