maidr 1.7.0__py3-none-any.whl → 1.7.1__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.7.0"
1
+ __version__ = "1.7.1"
2
2
 
3
3
  from .api import close, render, save_html, show, stacked
4
4
  from .core import Maidr
@@ -114,13 +114,18 @@ class MultiLinePlot(MaidrPlot, LineExtractorMixin):
114
114
  elif not label.startswith("_child"):
115
115
  line_type = label
116
116
 
117
+ # Use the new method to extract data with categorical labels
118
+ line_coords = LineExtractorMixin.extract_line_data_with_categorical_labels(self.ax, line)
119
+ if line_coords is None:
120
+ continue
121
+
117
122
  line_data = [
118
123
  {
119
- MaidrKey.X: float(x),
120
- MaidrKey.Y: float(y),
124
+ MaidrKey.X: x,
125
+ MaidrKey.Y: y,
121
126
  **({MaidrKey.FILL: line_type} if line_type else {}),
122
127
  }
123
- for x, y in line.get_xydata() # type: ignore
128
+ for x, y in line_coords
124
129
  ]
125
130
 
126
131
  if line_data:
@@ -1,6 +1,5 @@
1
- from __future__ import annotations
2
-
3
- from typing import Any
1
+ import numpy as np
2
+ from typing import Any, List, Optional, Tuple, Union
4
3
 
5
4
  from matplotlib.axes import Axes
6
5
  from matplotlib.cm import ScalarMappable
@@ -38,7 +37,7 @@ class ContainerExtractorMixin:
38
37
 
39
38
  class LevelExtractorMixin:
40
39
  @staticmethod
41
- def extract_level(ax: Axes, key: MaidrKey = MaidrKey.X) -> list[str] | None:
40
+ def extract_level(ax: Axes, key: MaidrKey = MaidrKey.X) -> Optional[List[str]]:
42
41
  """Retrieve label texts from Axes based on the specified Maidr key."""
43
42
  if ax is None:
44
43
  return None
@@ -95,7 +94,7 @@ class LevelExtractorMixin:
95
94
 
96
95
  class LineExtractorMixin:
97
96
  @staticmethod
98
- def extract_line(ax: Axes) -> Line2D | None:
97
+ def extract_line(ax: Axes) -> Optional[Line2D]:
99
98
  """Retrieve the last line object from Axes, if available."""
100
99
  if ax is None or ax.get_lines() is None:
101
100
  return None
@@ -105,7 +104,7 @@ class LineExtractorMixin:
105
104
  return ax.get_lines()[-1]
106
105
 
107
106
  @staticmethod
108
- def extract_lines(ax: Axes) -> list[Line2D] | None:
107
+ def extract_lines(ax: Axes) -> Optional[List[Line2D]]:
109
108
  """Retrieve all line objects from Axes, if available."""
110
109
  if ax is None or ax.get_lines() is None:
111
110
  return None
@@ -114,6 +113,54 @@ class LineExtractorMixin:
114
113
  # `maidr` package supports the same.
115
114
  return ax.get_lines()
116
115
 
116
+ @staticmethod
117
+ def extract_line_data_with_categorical_labels(ax: Axes, line: Line2D) -> Optional[List[Tuple[Union[str, float], float]]]:
118
+ """
119
+ Extract line data with proper handling of categorical x-axis labels.
120
+
121
+ Parameters
122
+ ----------
123
+ ax : Axes
124
+ The matplotlib axes object
125
+ line : Line2D
126
+ The line object to extract data from
127
+
128
+ Returns
129
+ -------
130
+ Optional[List[Tuple[Union[str, float], float]]]
131
+ List of (x, y) tuples where x values are categorical labels if available,
132
+ or numeric values if no categorical labels are found
133
+ """
134
+ if ax is None or line is None:
135
+ return None
136
+
137
+ xydata = line.get_xydata()
138
+ if xydata is None:
139
+ return None
140
+
141
+ # Convert to numpy array for easier handling
142
+ xy_array = np.asarray(xydata)
143
+ if xy_array.size == 0:
144
+ return None
145
+
146
+ # Extract x-axis labels for categorical data
147
+ x_labels = LevelExtractorMixin.extract_level(ax, MaidrKey.X)
148
+
149
+ # If we have categorical labels, map numeric coordinates to labels
150
+ if x_labels:
151
+ result = []
152
+ for x, y in xy_array:
153
+ # Map numeric x-coordinate to categorical label if available
154
+ if isinstance(x, (int, float)) and 0 <= int(x) < len(x_labels):
155
+ x_value = x_labels[int(x)]
156
+ else:
157
+ x_value = float(x)
158
+ result.append((x_value, float(y)))
159
+ return result
160
+ else:
161
+ # No categorical labels, return numeric values
162
+ return [(float(x), float(y)) for x, y in xy_array]
163
+
117
164
 
118
165
  class CollectionExtractorMixin:
119
166
  @staticmethod
@@ -133,7 +180,7 @@ class CollectionExtractorMixin:
133
180
 
134
181
  class ScalarMappableExtractorMixin:
135
182
  @staticmethod
136
- def extract_scalar_mappable(ax: Axes) -> ScalarMappable | None:
183
+ def extract_scalar_mappable(ax: Axes) -> Optional[ScalarMappable]:
137
184
  """Retrieve the first collection ScalarMappable from an Axes object."""
138
185
  if ax is None or ax.get_children() is None:
139
186
  return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maidr
3
- Version: 1.7.0
3
+ Version: 1.7.1
4
4
  Summary: Multimodal Access and Interactive Data Representations
5
5
  Project-URL: Homepage, https://xability.github.io/py-maidr
6
6
  Project-URL: Repository, https://github.com/xability/py-maidr
@@ -1,4 +1,4 @@
1
- maidr/__init__.py,sha256=N6tFj8F07eJxaRvcZZNW0wNWTR2I2JcTgM9PTSKWGtM,415
1
+ maidr/__init__.py,sha256=5pE1kfXuUom-1WcK9Z4Dl8PFegDww1BeKyscUSWJ4Rg,415
2
2
  maidr/api.py,sha256=gRNLXqUWpFGdD-I7Nu6J0_LeEni9KRAr0TBHwHaDAsc,1928
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=9R1ddSnUkGEE9WJgUPeuZhRtxXNBnOM9rbJdfJcY8b
16
16
  maidr/core/plot/grouped_barplot.py,sha256=_zn4XMeEnSiDHtf6t4-z9ErBqg_CijhAS2CCtlHgYIQ,2077
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=48aEkx8rjZ9lYEZSHWCJcSzdVblKwcdJZDZK0vnxmPo,4291
19
+ maidr/core/plot/lineplot.py,sha256=VbMjG-D5X-oeehduAtbqsyZ-hbcFc4NQYBwpCzgk4lo,4492
20
20
  maidr/core/plot/maidr_plot.py,sha256=9T0boWaonM99jggEed97-rCy_cufRMWXrXo-CbmPudE,4230
21
21
  maidr/core/plot/maidr_plot_factory.py,sha256=NW2iFScswgXbAC9rAOo4iMkAFsjY43DAvFioGr0yzx4,2732
22
22
  maidr/core/plot/mplfinance_barplot.py,sha256=zhTp2i6BH0xn7vQvGTotKgu2HbzlKT4p6zA5CVUUHHc,5673
@@ -48,11 +48,11 @@ maidr/util/plot_detection.py,sha256=bgLHoDcHSRwOiyKzUK3EqGwdAIhF44ocHW5ox6xYGZw,
48
48
  maidr/util/regression_line_utils.py,sha256=yFKr-H0whT_su2YVZwNksBLp5EC5s77sr6HUFgNcsyY,2329
49
49
  maidr/util/svg_utils.py,sha256=2gyzBtNKFHs0utrw1iOlxTmznzivOWQMV2aW8zu2c8E,1442
50
50
  maidr/util/mixin/__init__.py,sha256=aGJZNhtWh77yIVPc7ipIZm1OajigjMtCWYKPuDWTC-c,217
51
- maidr/util/mixin/extractor_mixin.py,sha256=oHtwpmS5kARvaLrSO3DKTPQxyFUw9nOcKN7rzTj1q4g,5192
51
+ maidr/util/mixin/extractor_mixin.py,sha256=l1DQTqZiVeZ18qXrz-rKCh8ETFofucBfwjIjO4S85HU,6923
52
52
  maidr/util/mixin/merger_mixin.py,sha256=V0qLw_6DUB7X6CQ3BCMpsCQX_ZuwAhoSTm_E4xAJFKM,712
53
53
  maidr/widget/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  maidr/widget/shiny.py,sha256=wrrw2KAIpE_A6CNQGBtNHauR1DjenA_n47qlFXX9_rk,745
55
- maidr-1.7.0.dist-info/METADATA,sha256=rjXKEyignRmgCOB6C6E_FhvqEkPvjGHIMuxFkZAHpos,3154
56
- maidr-1.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
- maidr-1.7.0.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
58
- maidr-1.7.0.dist-info/RECORD,,
55
+ maidr-1.7.1.dist-info/METADATA,sha256=WjKqqdKOwH8ZkI00md0BINyrpZv_hpD3WL5ZL1_iXkM,3154
56
+ maidr-1.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
+ maidr-1.7.1.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
58
+ maidr-1.7.1.dist-info/RECORD,,
File without changes