maidr 1.4.1__py3-none-any.whl → 1.4.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 CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "1.4.1"
1
+ __version__ = "1.4.2"
2
2
 
3
3
  from .api import close, render, save_html, show, stacked
4
4
  from .core import Maidr
@@ -2,8 +2,11 @@
2
2
  SMOOTH_KEYWORDS = [
3
3
  "smooth",
4
4
  "lowess",
5
+ "loess",
5
6
  "regression",
6
7
  "linear regression",
8
+ "linear fit",
9
+ "fit",
7
10
  "kde",
8
11
  "density",
9
12
  "gaussian",
maidr/patch/regplot.py CHANGED
@@ -5,11 +5,10 @@ from matplotlib.axes import Axes
5
5
  from matplotlib.lines import Line2D
6
6
  from maidr.core.enum import PlotType
7
7
  from maidr.patch.common import common
8
- import numpy as np
9
8
  from maidr.core.context_manager import ContextManager
10
9
  import uuid
11
10
  from maidr.core.enum.smooth_keywords import SMOOTH_KEYWORDS
12
- from maidr.util.regression_line_utils import find_regression_line
11
+ from maidr.util.regression_line_utils import find_smooth_lines_by_label
13
12
 
14
13
 
15
14
  def regplot(wrapped, instance, args, kwargs) -> Axes:
@@ -23,27 +22,34 @@ def regplot(wrapped, instance, args, kwargs) -> Axes:
23
22
  # Prevent any MAIDR layer registration during plotting when scatter=False
24
23
  with ContextManager.set_internal_context():
25
24
  ax = wrapped(*args, **kwargs)
25
+
26
26
  axes = ax if isinstance(ax, Axes) else ax.axes if hasattr(ax, "axes") else None
27
27
  if axes is not None:
28
- regression_line = find_regression_line(axes)
29
- if regression_line is not None:
30
- # ---
31
- # Assign a unique gid to the regression line if not already set.
32
- # This is necessary because the SVG output may contain many <g> and <path> tags,
33
- # and only the regression line should be uniquely selectable for accessibility and highlighting.
34
- # By setting a unique gid, we ensure the backend and frontend can generate a reliable selector
35
- # (e.g., g[id='maidr-...'] path) that matches only the intended regression line.
36
- # ---
37
- if regression_line.get_gid() is None:
28
+ # Find and register all smooth lines
29
+ smooth_lines = find_smooth_lines_by_label(axes)
30
+ for line in smooth_lines:
31
+ # If line doesn't have a gid yet, assign one and register
32
+ if line.get_gid() is None:
38
33
  new_gid = f"maidr-{uuid.uuid4()}"
39
- regression_line.set_gid(new_gid)
40
- common(
41
- PlotType.SMOOTH,
42
- lambda *a, **k: ax,
43
- instance,
44
- args,
45
- dict(kwargs, regression_line=regression_line),
46
- )
34
+ line.set_gid(new_gid)
35
+ common(
36
+ PlotType.SMOOTH,
37
+ lambda *a, **k: ax,
38
+ instance,
39
+ args,
40
+ dict(kwargs, regression_line=line),
41
+ )
42
+ else:
43
+ # Even if it has a gid, register it as a smooth layer
44
+ # This handles the case where patched_plot already assigned a gid
45
+ common(
46
+ PlotType.SMOOTH,
47
+ lambda *a, **k: ax,
48
+ instance,
49
+ args,
50
+ dict(kwargs, regression_line=line),
51
+ )
52
+
47
53
  return ax
48
54
 
49
55
 
@@ -53,7 +59,8 @@ def patched_plot(wrapped, instance, args, kwargs):
53
59
  """
54
60
  # Call the original plot function
55
61
  lines = wrapped(*args, **kwargs)
56
- # lines can be a list of Line2D objects
62
+
63
+ # Check each line for smooth keywords and register if found
57
64
  for line in lines:
58
65
  if isinstance(line, Line2D):
59
66
  label = line.get_label() or ""
@@ -72,6 +79,7 @@ def patched_plot(wrapped, instance, args, kwargs):
72
79
  args,
73
80
  dict(kwargs, regression_line=line),
74
81
  )
82
+
75
83
  return lines
76
84
 
77
85
 
@@ -1,8 +1,11 @@
1
1
  from matplotlib.lines import Line2D
2
+ from matplotlib.axes import Axes
2
3
  import numpy as np
4
+ from typing import List, Union
5
+ from maidr.core.enum.smooth_keywords import SMOOTH_KEYWORDS
3
6
 
4
7
 
5
- def find_regression_line(axes):
8
+ def find_regression_line(axes: Axes) -> Union[Line2D, None]:
6
9
  """
7
10
  Helper to find the regression line (Line2D) in the given axes.
8
11
  """
@@ -17,3 +20,50 @@ def find_regression_line(axes):
17
20
  ),
18
21
  None,
19
22
  )
23
+
24
+
25
+ def find_smooth_lines_by_label(axes: Axes) -> List[Line2D]:
26
+ """
27
+ Helper to find all smooth/regression lines (Line2D) in the given axes by checking their labels.
28
+
29
+ This function detects smooth lines by examining their labels for smooth-related keywords
30
+ or generic '_child' labels that are commonly created by seaborn's regplot function.
31
+
32
+ Parameters
33
+ ----------
34
+ axes : matplotlib.axes.Axes
35
+ The matplotlib axes object to search for smooth lines.
36
+
37
+ Returns
38
+ -------
39
+ List[Line2D]
40
+ List of Line2D objects that have labels matching smooth keywords or generic '_child' labels.
41
+
42
+ Examples
43
+ --------
44
+ >>> import matplotlib.pyplot as plt
45
+ >>> import seaborn as sns
46
+ >>>
47
+ >>> fig, ax = plt.subplots()
48
+ >>> # Create a regplot with smooth line
49
+ >>> sns.regplot(x=[1, 2, 3], y=[1, 2, 3], ax=ax, lowess=True)
50
+ >>>
51
+ >>> # Find smooth lines
52
+ >>> smooth_lines = find_smooth_lines_by_label(ax)
53
+ >>> print(f"Found {len(smooth_lines)} smooth lines")
54
+ """
55
+ smooth_lines = []
56
+ for line in axes.get_lines():
57
+ if isinstance(line, Line2D):
58
+ label = line.get_label() or ""
59
+ label_str = str(label)
60
+
61
+ # Check if label matches smooth keywords
62
+ if any(key in label_str.lower() for key in SMOOTH_KEYWORDS):
63
+ smooth_lines.append(line)
64
+ # Also check for seaborn regplot lines with generic labels (like '_child0', '_child1')
65
+ elif label_str.startswith("_child"):
66
+ # Lines with _child labels are likely smooth lines from seaborn regplot
67
+ smooth_lines.append(line)
68
+
69
+ return smooth_lines
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: maidr
3
- Version: 1.4.1
3
+ Version: 1.4.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=rjIWNGJRb5ksabBvZv4Ia2vq3YIhfCUr2sytbDXnV4U,415
1
+ maidr/__init__.py,sha256=WXjwKTG-ThyAevvEASjvfUbjdOvs1iXAhaOhvkyrreo,415
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
@@ -6,7 +6,7 @@ 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=ljG0omqzd8K8Yk213N7i7PXGvG-IOlnE5v7o6RoGJzc,795
8
8
  maidr/core/enum/plot_type.py,sha256=7Orx3b_0NdpI_PtVJfLyJPh4qBqYMTsYBBr8VwOtiAM,347
9
- maidr/core/enum/smooth_keywords.py,sha256=VlpIX1BaoX8efwIrT72GIptxguTpiPtJvvJUPMoaFSQ,194
9
+ maidr/core/enum/smooth_keywords.py,sha256=z2kVZZ-mETWWh5reWu_hj9WkJD6WFj7_2-6s1e4C1JE,236
10
10
  maidr/core/figure_manager.py,sha256=jXs-Prkeru1Pahj21hjh8BAwXM9ZFUZ3GFfKUfIRX_M,4117
11
11
  maidr/core/maidr.py,sha256=dxoJsvFyqhyv7PFHsYZrGAVnNmyjW0v0eng45cxhrf4,16325
12
12
  maidr/core/plot/__init__.py,sha256=xDIpRGM-4DfaSSL3nKcXrjdMecCHJ6en4K4nA_fPefQ,83
@@ -37,7 +37,7 @@ maidr/patch/histogram.py,sha256=k3N0RUf1SQ2402pwbaY5QyS98KnLWvr9glCHQw9NTko,2378
37
37
  maidr/patch/kdeplot.py,sha256=qv-OKzuop2aTrkZgUe2OnLxvV-KMyeXt1Td0_uZeHzE,2338
38
38
  maidr/patch/lineplot.py,sha256=og42V0tWBKCnf6idT3pLsIj3QBvKjg8aUN-k1udPRVw,1901
39
39
  maidr/patch/mplfinance.py,sha256=oxRhtKWnC-Fr9EBNS1RF-nKJKCKOPbtg4mseLsP1kMI,7967
40
- maidr/patch/regplot.py,sha256=Ciz43C5XZfWK6wtVWrlV0WNz4R__rcgdqVE9OCaXXRk,3236
40
+ maidr/patch/regplot.py,sha256=k86ekd0E4XJ_L1u85zObuDnxuXlM83z7tKtyXRTj2rI,3240
41
41
  maidr/patch/scatterplot.py,sha256=kln6zZwjVsdQzICalo-RnBOJrx1BnIB2xYUwItHvSNY,525
42
42
  maidr/util/__init__.py,sha256=eRJZfRpDX-n7UoV3JXw_9Lbfu_qNl_D0W1UTvLL-Iv4,81
43
43
  maidr/util/dedup_utils.py,sha256=RpgPL5p-3oULUHaTCZJaQKhPHfyPkvBLHMt8lAGpJ5A,438
@@ -47,11 +47,11 @@ maidr/util/mixin/extractor_mixin.py,sha256=oHtwpmS5kARvaLrSO3DKTPQxyFUw9nOcKN7rz
47
47
  maidr/util/mixin/merger_mixin.py,sha256=V0qLw_6DUB7X6CQ3BCMpsCQX_ZuwAhoSTm_E4xAJFKM,712
48
48
  maidr/util/mplfinance_utils.py,sha256=AvDzvAAQbMsPZxcxWr3DwctZMp4xW5CkQEBezWTk1mY,13704
49
49
  maidr/util/plot_detection.py,sha256=bVSocZMGCLP6CduRSpOmwIzLFWEBnNdYN9T1ULfVPMw,3893
50
- maidr/util/regression_line_utils.py,sha256=P8RQLixTby2JLz73XZgNiu96C2Ct3pNe4ENRWOjgT8M,509
50
+ maidr/util/regression_line_utils.py,sha256=yFKr-H0whT_su2YVZwNksBLp5EC5s77sr6HUFgNcsyY,2329
51
51
  maidr/util/svg_utils.py,sha256=2gyzBtNKFHs0utrw1iOlxTmznzivOWQMV2aW8zu2c8E,1442
52
52
  maidr/widget/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  maidr/widget/shiny.py,sha256=wrrw2KAIpE_A6CNQGBtNHauR1DjenA_n47qlFXX9_rk,745
54
- maidr-1.4.1.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
55
- maidr-1.4.1.dist-info/METADATA,sha256=rGSOkUIcGPVk2z2SgpfMy1EP_B7m0HgpStq3h1SKdK4,2664
56
- maidr-1.4.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
57
- maidr-1.4.1.dist-info/RECORD,,
54
+ maidr-1.4.2.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
55
+ maidr-1.4.2.dist-info/METADATA,sha256=9Wm3c8aZvsWjAGCGtGmPVUa6_xDCqaobGN_Asl6uS0c,2664
56
+ maidr-1.4.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
57
+ maidr-1.4.2.dist-info/RECORD,,
File without changes
File without changes