maidr 1.4.3__py3-none-any.whl → 1.4.8__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/maidr.py +5 -71
- maidr/core/plot/barplot.py +3 -1
- maidr/core/plot/candlestick.py +11 -8
- maidr/core/plot/lineplot.py +0 -1
- maidr/core/plot/mplfinance_barplot.py +3 -1
- maidr/core/plot/mplfinance_lineplot.py +0 -1
- maidr/patch/barplot.py +0 -2
- maidr/patch/lineplot.py +0 -1
- maidr/patch/mplfinance.py +2 -1
- maidr/util/mplfinance_utils.py +75 -69
- maidr/util/plot_detection.py +2 -2
- {maidr-1.4.3.dist-info → maidr-1.4.8.dist-info}/METADATA +28 -20
- {maidr-1.4.3.dist-info → maidr-1.4.8.dist-info}/RECORD +19 -19
- {maidr-1.4.3.dist-info → maidr-1.4.8.dist-info}/WHEEL +1 -1
- {maidr-1.4.3.dist-info → maidr-1.4.8.dist-info/licenses}/LICENSE +0 -0
maidr/__init__.py
CHANGED
maidr/core/maidr.py
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
import urllib.request
|
|
5
|
-
import urllib.error
|
|
6
3
|
import json
|
|
7
4
|
|
|
8
5
|
import io
|
|
9
|
-
import json
|
|
10
6
|
import os
|
|
11
7
|
import tempfile
|
|
12
8
|
import uuid
|
|
@@ -25,11 +21,6 @@ from maidr.core.plot import MaidrPlot
|
|
|
25
21
|
from maidr.util.environment import Environment
|
|
26
22
|
from maidr.util.dedup_utils import deduplicate_smooth_and_line
|
|
27
23
|
|
|
28
|
-
# Module-level cache for version to avoid repeated API calls
|
|
29
|
-
_MAIDR_VERSION_CACHE: str | None = None
|
|
30
|
-
_MAIDR_VERSION_CACHE_TIME: float = 0.0
|
|
31
|
-
_MAIDR_CACHE_DURATION = 3600 # Cache for 1 hour
|
|
32
|
-
|
|
33
24
|
|
|
34
25
|
class Maidr:
|
|
35
26
|
"""
|
|
@@ -264,7 +255,9 @@ class Maidr:
|
|
|
264
255
|
svg_buffer = io.StringIO() # Reset the buffer
|
|
265
256
|
svg_buffer.write(
|
|
266
257
|
etree.tostring(
|
|
267
|
-
root_svg,
|
|
258
|
+
root_svg,
|
|
259
|
+
pretty_print=True,
|
|
260
|
+
encoding="unicode", # type: ignore
|
|
268
261
|
)
|
|
269
262
|
)
|
|
270
263
|
|
|
@@ -281,70 +274,11 @@ class Maidr:
|
|
|
281
274
|
"""Generate a unique identifier string using UUID4."""
|
|
282
275
|
return str(uuid.uuid4())
|
|
283
276
|
|
|
284
|
-
@staticmethod
|
|
285
|
-
def _get_latest_maidr_version() -> str:
|
|
286
|
-
"""
|
|
287
|
-
Query the npm registry API to get the latest version of maidr with caching.
|
|
288
|
-
|
|
289
|
-
Returns
|
|
290
|
-
-------
|
|
291
|
-
str
|
|
292
|
-
The latest version of maidr from npm registry, or 'latest' as fallback.
|
|
293
|
-
"""
|
|
294
|
-
import time
|
|
295
|
-
|
|
296
|
-
global _MAIDR_VERSION_CACHE, _MAIDR_VERSION_CACHE_TIME
|
|
297
|
-
|
|
298
|
-
# Check if version fetching is disabled via environment variable
|
|
299
|
-
if os.getenv("MAIDR_DISABLE_VERSION_FETCH", "").lower() in ("true", "1", "yes"):
|
|
300
|
-
return "latest"
|
|
301
|
-
|
|
302
|
-
current_time = time.time()
|
|
303
|
-
|
|
304
|
-
# Check if we have a valid cached version
|
|
305
|
-
if (
|
|
306
|
-
_MAIDR_VERSION_CACHE is not None
|
|
307
|
-
and current_time - _MAIDR_VERSION_CACHE_TIME < _MAIDR_CACHE_DURATION
|
|
308
|
-
):
|
|
309
|
-
return _MAIDR_VERSION_CACHE
|
|
310
|
-
|
|
311
|
-
try:
|
|
312
|
-
# Query npm registry API for maidr package
|
|
313
|
-
with urllib.request.urlopen(
|
|
314
|
-
"https://registry.npmjs.org/maidr/latest", timeout=5 # 5 second timeout
|
|
315
|
-
) as response:
|
|
316
|
-
if response.status == 200:
|
|
317
|
-
data = json.loads(response.read().decode("utf-8"))
|
|
318
|
-
version = data.get("version", "latest")
|
|
319
|
-
|
|
320
|
-
# Cache the successful result
|
|
321
|
-
_MAIDR_VERSION_CACHE = version
|
|
322
|
-
_MAIDR_VERSION_CACHE_TIME = current_time
|
|
323
|
-
|
|
324
|
-
return version
|
|
325
|
-
|
|
326
|
-
except Exception:
|
|
327
|
-
# Any error - just use latest
|
|
328
|
-
pass
|
|
329
|
-
|
|
330
|
-
# Fallback to 'latest' if API call fails
|
|
331
|
-
return "latest"
|
|
332
|
-
|
|
333
|
-
@staticmethod
|
|
334
|
-
def clear_version_cache() -> None:
|
|
335
|
-
"""Clear the cached version to force a fresh API call on next request."""
|
|
336
|
-
global _MAIDR_VERSION_CACHE, _MAIDR_VERSION_CACHE_TIME
|
|
337
|
-
_MAIDR_VERSION_CACHE = None
|
|
338
|
-
_MAIDR_VERSION_CACHE_TIME = 0.0
|
|
339
|
-
|
|
340
277
|
@staticmethod
|
|
341
278
|
def _inject_plot(plot: HTML, maidr: str, maidr_id, use_iframe: bool = True) -> Tag:
|
|
342
279
|
"""Embed the plot and associated MAIDR scripts into the HTML structure."""
|
|
343
280
|
# Get the latest version from npm registry
|
|
344
|
-
|
|
345
|
-
MAIDR_TS_CDN_URL = (
|
|
346
|
-
f"https://cdn.jsdelivr.net/npm/maidr@{latest_version}/dist/maidr.js"
|
|
347
|
-
)
|
|
281
|
+
MAIDR_TS_CDN_URL = "https://cdn.jsdelivr.net/npm/maidr@latest/dist/maidr.js"
|
|
348
282
|
|
|
349
283
|
script = f"""
|
|
350
284
|
if (!document.querySelector('script[src="{MAIDR_TS_CDN_URL}"]'))
|
|
@@ -366,7 +300,7 @@ class Maidr:
|
|
|
366
300
|
base_html = tags.div(
|
|
367
301
|
tags.link(
|
|
368
302
|
rel="stylesheet",
|
|
369
|
-
href=
|
|
303
|
+
href="https://cdn.jsdelivr.net/npm/maidr@latest/dist/maidr_style.css",
|
|
370
304
|
),
|
|
371
305
|
tags.script(script, type="text/javascript"),
|
|
372
306
|
tags.div(plot),
|
maidr/core/plot/barplot.py
CHANGED
|
@@ -23,7 +23,9 @@ class BarPlot(MaidrPlot, ContainerExtractorMixin, LevelExtractorMixin, DictMerge
|
|
|
23
23
|
levels = self.extract_level(self.ax)
|
|
24
24
|
formatted_data = []
|
|
25
25
|
combined_data = list(
|
|
26
|
-
zip(levels, data)
|
|
26
|
+
zip(levels, data)
|
|
27
|
+
if plot[0].orientation == "vertical"
|
|
28
|
+
else zip(data, levels) # type: ignore
|
|
27
29
|
)
|
|
28
30
|
if combined_data: # type: ignore
|
|
29
31
|
for x, y in combined_data: # type: ignore
|
maidr/core/plot/candlestick.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import matplotlib.dates as mdates
|
|
4
|
-
import numpy as np
|
|
5
3
|
from matplotlib.axes import Axes
|
|
6
4
|
from matplotlib.patches import Rectangle
|
|
7
5
|
|
|
@@ -41,6 +39,7 @@ class CandlestickPlot(MaidrPlot):
|
|
|
41
39
|
self._maidr_wick_collection = kwargs.get("_maidr_wick_collection", None)
|
|
42
40
|
self._maidr_body_collection = kwargs.get("_maidr_body_collection", None)
|
|
43
41
|
self._maidr_date_nums = kwargs.get("_maidr_date_nums", None)
|
|
42
|
+
self._maidr_original_data = kwargs.get("_maidr_original_data", None) # Store original data
|
|
44
43
|
|
|
45
44
|
# Store the GID for proper selector generation
|
|
46
45
|
self._maidr_gid = None
|
|
@@ -64,16 +63,16 @@ class CandlestickPlot(MaidrPlot):
|
|
|
64
63
|
self._elements = [body_collection, wick_collection]
|
|
65
64
|
|
|
66
65
|
# Use the utility class to extract data
|
|
67
|
-
|
|
68
|
-
body_collection, wick_collection, self._maidr_date_nums
|
|
66
|
+
data = MplfinanceDataExtractor.extract_candlestick_data(
|
|
67
|
+
body_collection, wick_collection, self._maidr_date_nums, self._maidr_original_data
|
|
69
68
|
)
|
|
69
|
+
return data
|
|
70
70
|
|
|
71
71
|
# Fallback to original detection method
|
|
72
72
|
if not self.axes:
|
|
73
73
|
return []
|
|
74
74
|
|
|
75
75
|
ax_ohlc = self.axes[0]
|
|
76
|
-
candles = []
|
|
77
76
|
|
|
78
77
|
# Look for Rectangle patches (original_flavor candlestick)
|
|
79
78
|
body_rectangles = []
|
|
@@ -95,9 +94,10 @@ class CandlestickPlot(MaidrPlot):
|
|
|
95
94
|
rect.set_gid(self._maidr_gid)
|
|
96
95
|
|
|
97
96
|
# Use the utility class to extract data
|
|
98
|
-
|
|
99
|
-
body_rectangles, self._maidr_date_nums
|
|
97
|
+
data = MplfinanceDataExtractor.extract_rectangle_candlestick_data(
|
|
98
|
+
body_rectangles, self._maidr_date_nums, self._maidr_original_data
|
|
100
99
|
)
|
|
100
|
+
return data
|
|
101
101
|
|
|
102
102
|
return []
|
|
103
103
|
|
|
@@ -133,11 +133,14 @@ class CandlestickPlot(MaidrPlot):
|
|
|
133
133
|
"""Initialize the MAIDR schema dictionary with basic plot information."""
|
|
134
134
|
title = "Candlestick Chart"
|
|
135
135
|
|
|
136
|
+
# Extract the plot data
|
|
137
|
+
plot_data = self._extract_plot_data()
|
|
138
|
+
|
|
136
139
|
maidr_schema = {
|
|
137
140
|
MaidrKey.TYPE: self.type,
|
|
138
141
|
MaidrKey.TITLE: title,
|
|
139
142
|
MaidrKey.AXES: self._extract_axes_data(),
|
|
140
|
-
MaidrKey.DATA:
|
|
143
|
+
MaidrKey.DATA: plot_data,
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
# Include selector only if the plot supports highlighting.
|
maidr/core/plot/lineplot.py
CHANGED
|
@@ -49,7 +49,9 @@ class MplfinanceBarPlot(
|
|
|
49
49
|
levels = self.extract_level(self.ax)
|
|
50
50
|
formatted_data = []
|
|
51
51
|
combined_data = list(
|
|
52
|
-
zip(levels, data)
|
|
52
|
+
zip(levels, data)
|
|
53
|
+
if plot[0].orientation == "vertical"
|
|
54
|
+
else zip(data, levels) # type: ignore
|
|
53
55
|
)
|
|
54
56
|
if combined_data: # type: ignore
|
|
55
57
|
for x, y in combined_data: # type: ignore
|
maidr/patch/barplot.py
CHANGED
maidr/patch/lineplot.py
CHANGED
|
@@ -6,7 +6,6 @@ from matplotlib.lines import Line2D
|
|
|
6
6
|
|
|
7
7
|
from maidr.core.enum import PlotType
|
|
8
8
|
from maidr.patch.common import common
|
|
9
|
-
from maidr.core.enum.smooth_keywords import SMOOTH_KEYWORDS
|
|
10
9
|
from maidr.core.context_manager import ContextManager
|
|
11
10
|
from maidr.core.figure_manager import FigureManager
|
|
12
11
|
|
maidr/patch/mplfinance.py
CHANGED
|
@@ -32,7 +32,7 @@ def mplfinance_plot_patch(wrapped, instance, args, kwargs):
|
|
|
32
32
|
if not (isinstance(result, tuple) and len(result) >= 2):
|
|
33
33
|
return result if original_returnfig else None
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
_, axes = result[0], result[1]
|
|
36
36
|
ax_list = axes if isinstance(axes, list) else [axes]
|
|
37
37
|
|
|
38
38
|
# Enhanced axis identification using content-based detection
|
|
@@ -92,6 +92,7 @@ def mplfinance_plot_patch(wrapped, instance, args, kwargs):
|
|
|
92
92
|
_maidr_wick_collection=wick_collection,
|
|
93
93
|
_maidr_body_collection=body_collection,
|
|
94
94
|
_maidr_date_nums=date_nums,
|
|
95
|
+
_maidr_original_data=data,
|
|
95
96
|
)
|
|
96
97
|
common(
|
|
97
98
|
PlotType.CANDLESTICK,
|
maidr/util/mplfinance_utils.py
CHANGED
|
@@ -5,7 +5,8 @@ Utility functions for handling mplfinance-specific data extraction and processin
|
|
|
5
5
|
import matplotlib.dates as mdates
|
|
6
6
|
import numpy as np
|
|
7
7
|
from matplotlib.patches import Rectangle
|
|
8
|
-
from typing import List, Optional, Tuple, Any
|
|
8
|
+
from typing import List, Optional, Tuple, Any, Union
|
|
9
|
+
import pandas as pd
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class MplfinanceDataExtractor:
|
|
@@ -62,6 +63,7 @@ class MplfinanceDataExtractor:
|
|
|
62
63
|
body_collection: Any,
|
|
63
64
|
wick_collection: Any,
|
|
64
65
|
date_nums: Optional[List[float]] = None,
|
|
66
|
+
original_data: Optional[Union[pd.DataFrame, pd.Series, dict]] = None,
|
|
65
67
|
) -> List[dict]:
|
|
66
68
|
"""
|
|
67
69
|
Extract candlestick data from mplfinance collections.
|
|
@@ -74,6 +76,8 @@ class MplfinanceDataExtractor:
|
|
|
74
76
|
LineCollection containing candlestick wicks
|
|
75
77
|
date_nums : Optional[List[float]], default=None
|
|
76
78
|
List of matplotlib date numbers corresponding to the candles
|
|
79
|
+
original_data : Optional[Union[pd.DataFrame, pd.Series, dict]], default=None
|
|
80
|
+
Original DataFrame/Series/dict with OHLC data for accurate bull/bear classification
|
|
77
81
|
|
|
78
82
|
Returns
|
|
79
83
|
-------
|
|
@@ -85,7 +89,6 @@ class MplfinanceDataExtractor:
|
|
|
85
89
|
|
|
86
90
|
candles = []
|
|
87
91
|
paths = body_collection.get_paths()
|
|
88
|
-
face_colors = body_collection.get_facecolor()
|
|
89
92
|
|
|
90
93
|
for i, path in enumerate(paths):
|
|
91
94
|
if len(path.vertices) >= 4:
|
|
@@ -109,8 +112,10 @@ class MplfinanceDataExtractor:
|
|
|
109
112
|
x_center
|
|
110
113
|
)
|
|
111
114
|
|
|
112
|
-
# Determine if this is an up or down candle
|
|
113
|
-
is_up = MplfinanceDataExtractor.
|
|
115
|
+
# Determine if this is an up or down candle using original data
|
|
116
|
+
is_up = MplfinanceDataExtractor._determine_bull_bear_from_data(
|
|
117
|
+
original_data, i, date_str
|
|
118
|
+
)
|
|
114
119
|
|
|
115
120
|
# Extract OHLC values
|
|
116
121
|
(
|
|
@@ -132,13 +137,16 @@ class MplfinanceDataExtractor:
|
|
|
132
137
|
"close": round(close_val, 2),
|
|
133
138
|
"volume": 0, # Volume is handled separately
|
|
134
139
|
}
|
|
140
|
+
|
|
135
141
|
candles.append(candle_data)
|
|
136
142
|
|
|
137
143
|
return candles
|
|
138
144
|
|
|
139
145
|
@staticmethod
|
|
140
146
|
def extract_rectangle_candlestick_data(
|
|
141
|
-
body_rectangles: List[Rectangle],
|
|
147
|
+
body_rectangles: List[Rectangle],
|
|
148
|
+
date_nums: Optional[List[float]] = None,
|
|
149
|
+
original_data: Optional[Union[pd.DataFrame, pd.Series, dict]] = None,
|
|
142
150
|
) -> List[dict]:
|
|
143
151
|
"""
|
|
144
152
|
Extract candlestick data from Rectangle patches (original_flavor).
|
|
@@ -149,6 +157,8 @@ class MplfinanceDataExtractor:
|
|
|
149
157
|
List of Rectangle patches representing candlestick bodies
|
|
150
158
|
date_nums : Optional[List[float]], default=None
|
|
151
159
|
List of matplotlib date numbers corresponding to the candles
|
|
160
|
+
original_data : Optional[Union[pd.DataFrame, pd.Series, dict]], default=None
|
|
161
|
+
Original DataFrame/Series/dict with OHLC data for accurate bull/bear classification
|
|
152
162
|
|
|
153
163
|
Returns
|
|
154
164
|
-------
|
|
@@ -180,10 +190,11 @@ class MplfinanceDataExtractor:
|
|
|
180
190
|
|
|
181
191
|
y_bottom = rect.get_y()
|
|
182
192
|
height = rect.get_height()
|
|
183
|
-
face_color = rect.get_facecolor()
|
|
184
193
|
|
|
185
|
-
# Determine if this is an up or down candle
|
|
186
|
-
is_up_candle = MplfinanceDataExtractor.
|
|
194
|
+
# Determine if this is an up or down candle using original data
|
|
195
|
+
is_up_candle = MplfinanceDataExtractor._determine_bull_bear_from_data(
|
|
196
|
+
original_data, i, date_str
|
|
197
|
+
)
|
|
187
198
|
|
|
188
199
|
# Extract OHLC values from rectangle
|
|
189
200
|
(
|
|
@@ -211,10 +222,65 @@ class MplfinanceDataExtractor:
|
|
|
211
222
|
"close": round(close_price, 2),
|
|
212
223
|
"volume": 0,
|
|
213
224
|
}
|
|
225
|
+
|
|
214
226
|
candles.append(candle_data)
|
|
215
227
|
|
|
216
228
|
return candles
|
|
217
229
|
|
|
230
|
+
@staticmethod
|
|
231
|
+
def _determine_bull_bear_from_data(
|
|
232
|
+
original_data: Optional[Union[pd.DataFrame, pd.Series, dict]],
|
|
233
|
+
index: int,
|
|
234
|
+
date_str: str
|
|
235
|
+
) -> bool:
|
|
236
|
+
"""
|
|
237
|
+
Determine if a candle is bullish (up) or bearish (down) using original OHLC data.
|
|
238
|
+
|
|
239
|
+
This is the most robust method as it uses the actual data rather than colors.
|
|
240
|
+
|
|
241
|
+
Parameters
|
|
242
|
+
----------
|
|
243
|
+
original_data : Optional[Union[pd.DataFrame, pd.Series, dict]]
|
|
244
|
+
Original DataFrame/Series/dict with OHLC data
|
|
245
|
+
index : int
|
|
246
|
+
Index of the candle
|
|
247
|
+
date_str : str
|
|
248
|
+
Date string for the candle
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
-------
|
|
252
|
+
bool
|
|
253
|
+
True if bullish (close > open), False if bearish (close < open)
|
|
254
|
+
"""
|
|
255
|
+
# Default to bullish if no data available
|
|
256
|
+
if original_data is None:
|
|
257
|
+
return True
|
|
258
|
+
|
|
259
|
+
try:
|
|
260
|
+
# Try to access the original data
|
|
261
|
+
if hasattr(original_data, 'iloc'):
|
|
262
|
+
# It's a pandas DataFrame/Series
|
|
263
|
+
if index < len(original_data):
|
|
264
|
+
row = original_data.iloc[index]
|
|
265
|
+
if 'Close' in row and 'Open' in row:
|
|
266
|
+
is_bullish = row['Close'] > row['Open']
|
|
267
|
+
return is_bullish
|
|
268
|
+
|
|
269
|
+
elif hasattr(original_data, '__getitem__'):
|
|
270
|
+
# It's a dictionary or similar
|
|
271
|
+
if 'Close' in original_data and 'Open' in original_data:
|
|
272
|
+
closes = original_data['Close']
|
|
273
|
+
opens = original_data['Open']
|
|
274
|
+
if index < len(closes) and index < len(opens):
|
|
275
|
+
is_bullish = closes[index] > opens[index]
|
|
276
|
+
return is_bullish
|
|
277
|
+
|
|
278
|
+
except (KeyError, IndexError, AttributeError):
|
|
279
|
+
pass
|
|
280
|
+
|
|
281
|
+
# Fallback to bullish if data access fails
|
|
282
|
+
return True # Default to bullish
|
|
283
|
+
|
|
218
284
|
@staticmethod
|
|
219
285
|
def clean_axis_label(label: str) -> str:
|
|
220
286
|
"""
|
|
@@ -268,7 +334,7 @@ class MplfinanceDataExtractor:
|
|
|
268
334
|
|
|
269
335
|
date_dt = pd.to_datetime(date_num, unit="D")
|
|
270
336
|
return date_dt.strftime("%Y-%m-%d")
|
|
271
|
-
except:
|
|
337
|
+
except (ValueError, TypeError):
|
|
272
338
|
pass
|
|
273
339
|
except (ValueError, TypeError, OverflowError):
|
|
274
340
|
pass
|
|
@@ -320,66 +386,6 @@ class MplfinanceDataExtractor:
|
|
|
320
386
|
# Use the utility class for date conversion
|
|
321
387
|
return MplfinanceDataExtractor._convert_date_num_to_string(x_center_num)
|
|
322
388
|
|
|
323
|
-
@staticmethod
|
|
324
|
-
def _is_up_candle(face_colors: Any, index: int) -> bool:
|
|
325
|
-
"""
|
|
326
|
-
Determine if a candle is up based on face color.
|
|
327
|
-
|
|
328
|
-
Parameters
|
|
329
|
-
----------
|
|
330
|
-
face_colors : Any
|
|
331
|
-
Face colors from the collection
|
|
332
|
-
index : int
|
|
333
|
-
Index of the candle
|
|
334
|
-
|
|
335
|
-
Returns
|
|
336
|
-
-------
|
|
337
|
-
bool
|
|
338
|
-
True if up candle, False if down candle
|
|
339
|
-
"""
|
|
340
|
-
is_up = True # Default to up candle
|
|
341
|
-
if hasattr(face_colors, "__len__") and len(face_colors) > index:
|
|
342
|
-
color = (
|
|
343
|
-
face_colors[index]
|
|
344
|
-
if hasattr(face_colors[index], "__len__")
|
|
345
|
-
else face_colors
|
|
346
|
-
)
|
|
347
|
-
if isinstance(color, (list, tuple, np.ndarray)):
|
|
348
|
-
if len(color) >= 3:
|
|
349
|
-
# Dark colors typically indicate down candles
|
|
350
|
-
if color[0] < 0.5 and color[1] < 0.5 and color[2] < 0.5:
|
|
351
|
-
is_up = False
|
|
352
|
-
return is_up
|
|
353
|
-
|
|
354
|
-
@staticmethod
|
|
355
|
-
def _is_up_candle_from_color(face_color: Any) -> bool:
|
|
356
|
-
"""
|
|
357
|
-
Determine if a candle is up based on face color (for Rectangle patches).
|
|
358
|
-
|
|
359
|
-
Parameters
|
|
360
|
-
----------
|
|
361
|
-
face_color : Any
|
|
362
|
-
Face color of the rectangle
|
|
363
|
-
|
|
364
|
-
Returns
|
|
365
|
-
-------
|
|
366
|
-
bool
|
|
367
|
-
True if up candle, False if down candle
|
|
368
|
-
"""
|
|
369
|
-
try:
|
|
370
|
-
if (
|
|
371
|
-
isinstance(face_color, (list, tuple, np.ndarray))
|
|
372
|
-
and len(face_color) >= 3
|
|
373
|
-
):
|
|
374
|
-
# Green colors typically indicate up candles
|
|
375
|
-
if face_color[1] > face_color[0]:
|
|
376
|
-
return True
|
|
377
|
-
else:
|
|
378
|
-
return False
|
|
379
|
-
except (TypeError, IndexError):
|
|
380
|
-
pass
|
|
381
|
-
return True # Default to up candle
|
|
382
|
-
|
|
383
389
|
@staticmethod
|
|
384
390
|
def _extract_ohlc_from_rectangle(
|
|
385
391
|
y_min: float, y_max: float, is_up: bool
|
maidr/util/plot_detection.py
CHANGED
|
@@ -4,7 +4,7 @@ Utility functions for detecting plot types and determining appropriate plot clas
|
|
|
4
4
|
|
|
5
5
|
from matplotlib.axes import Axes
|
|
6
6
|
from matplotlib.lines import Line2D
|
|
7
|
-
from typing import
|
|
7
|
+
from typing import List, Union
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class PlotDetectionUtils:
|
|
@@ -109,7 +109,7 @@ class PlotDetectionUtils:
|
|
|
109
109
|
|
|
110
110
|
@staticmethod
|
|
111
111
|
def get_candlestick_axes(
|
|
112
|
-
ax: Union[Axes, List[Axes], List[List[Axes]]]
|
|
112
|
+
ax: Union[Axes, List[Axes], List[List[Axes]]],
|
|
113
113
|
) -> List[Axes]:
|
|
114
114
|
"""
|
|
115
115
|
Extract and normalize axes for candlestick plots.
|
|
@@ -1,39 +1,48 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: maidr
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.8
|
|
4
4
|
Summary: Multimodal Access and Interactive Data Representations
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Author: JooYoung Seo
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
Project-URL: Homepage, https://xability.github.io/py-maidr
|
|
6
|
+
Project-URL: Repository, https://github.com/xability/py-maidr
|
|
7
|
+
Author-email: JooYoung Seo <jseo1005@illinois.edu>, Saairam Venkatesh <saairam2@illinois.edu>
|
|
8
|
+
License-Expression: GPL-3.0-or-later
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: accessibility,blind,braille,data representation,low vision,multimodal,sonification,tactile,visual impairments,visualization
|
|
10
11
|
Classifier: Intended Audience :: Developers
|
|
11
12
|
Classifier: Intended Audience :: End Users/Desktop
|
|
12
13
|
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
13
14
|
Classifier: Intended Audience :: Healthcare Industry
|
|
14
15
|
Classifier: Intended Audience :: Science/Research
|
|
15
16
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
16
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
23
21
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
24
22
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
25
23
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
26
24
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
25
|
Classifier: Topic :: Text Processing :: Markup :: HTML
|
|
28
|
-
Requires-
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist: mplfinance
|
|
32
|
-
Requires-Dist: numpy
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist: wrapt
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
|
+
Requires-Dist: htmltools>=0.5
|
|
28
|
+
Requires-Dist: lxml>=5.1.0
|
|
29
|
+
Requires-Dist: mplfinance>=0.12.10b0
|
|
30
|
+
Requires-Dist: numpy>=1.26
|
|
31
|
+
Requires-Dist: virtualenv<21,>=20.26.6
|
|
32
|
+
Requires-Dist: wrapt<2,>=1.16.0
|
|
33
|
+
Provides-Extra: jupyter
|
|
34
|
+
Requires-Dist: ipykernel>=6.0.0; extra == 'jupyter'
|
|
35
|
+
Requires-Dist: jupyter<2,>=1.0.0; extra == 'jupyter'
|
|
36
|
+
Provides-Extra: test
|
|
37
|
+
Requires-Dist: jupyter<2,>=1.0.0; extra == 'test'
|
|
38
|
+
Requires-Dist: matplotlib>=3.8; extra == 'test'
|
|
39
|
+
Requires-Dist: pytest-mock<4,>=3.12.0; extra == 'test'
|
|
40
|
+
Requires-Dist: pytest<8,>=7.3.2; extra == 'test'
|
|
41
|
+
Requires-Dist: seaborn>=0.12; extra == 'test'
|
|
42
|
+
Provides-Extra: visualization
|
|
43
|
+
Requires-Dist: matplotlib>=3.8; extra == 'visualization'
|
|
44
|
+
Requires-Dist: seaborn>=0.12; extra == 'visualization'
|
|
45
|
+
Requires-Dist: statsmodels>=0.14.4; extra == 'visualization'
|
|
37
46
|
Description-Content-Type: text/markdown
|
|
38
47
|
|
|
39
48
|
<div align="center">
|
|
@@ -68,4 +77,3 @@ Please visit the [user guide](https://xability.github.io/py-maidr/) page.
|
|
|
68
77
|
## Example Code
|
|
69
78
|
|
|
70
79
|
We provide [some example code](https://github.com/xability/py-maidr/blob/main/example) for using py-maidr with matplotlib, seaborn, Jupyter Notebook, Quarto, Shiny, and Streamlit.
|
|
71
|
-
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
maidr/__init__.py,sha256=
|
|
1
|
+
maidr/__init__.py,sha256=L1N9chRSdVzT_lTD4NWEy8u_PJZvtXiORg0Yx4sGQpA,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
|
|
5
|
+
maidr/core/figure_manager.py,sha256=jXs-Prkeru1Pahj21hjh8BAwXM9ZFUZ3GFfKUfIRX_M,4117
|
|
6
|
+
maidr/core/maidr.py,sha256=tELie62HFSzZXjMosvVhinqQMzb1G25Odrxb7RBL694,14089
|
|
5
7
|
maidr/core/enum/__init__.py,sha256=9ee78L0dlxEx4ulUGVlD-J23UcUZmrGu0rXms54up3c,93
|
|
6
8
|
maidr/core/enum/library.py,sha256=e8ujT_L-McJWfoVJd1ty9K_2bwITnf1j0GPLsnAcHes,104
|
|
7
9
|
maidr/core/enum/maidr_key.py,sha256=ljG0omqzd8K8Yk213N7i7PXGvG-IOlnE5v7o6RoGJzc,795
|
|
8
10
|
maidr/core/enum/plot_type.py,sha256=7Orx3b_0NdpI_PtVJfLyJPh4qBqYMTsYBBr8VwOtiAM,347
|
|
9
11
|
maidr/core/enum/smooth_keywords.py,sha256=z2kVZZ-mETWWh5reWu_hj9WkJD6WFj7_2-6s1e4C1JE,236
|
|
10
|
-
maidr/core/figure_manager.py,sha256=jXs-Prkeru1Pahj21hjh8BAwXM9ZFUZ3GFfKUfIRX_M,4117
|
|
11
|
-
maidr/core/maidr.py,sha256=dxoJsvFyqhyv7PFHsYZrGAVnNmyjW0v0eng45cxhrf4,16325
|
|
12
12
|
maidr/core/plot/__init__.py,sha256=xDIpRGM-4DfaSSL3nKcXrjdMecCHJ6en4K4nA_fPefQ,83
|
|
13
|
-
maidr/core/plot/barplot.py,sha256=
|
|
13
|
+
maidr/core/plot/barplot.py,sha256=0hBgp__putezvxXc9G3qmaktmAzze3cN8pQMD9iqktE,2116
|
|
14
14
|
maidr/core/plot/boxplot.py,sha256=i11GdNuz_c-hilmhydu3ah-bzyVdFoBkNvRi5lpMrrY,9946
|
|
15
|
-
maidr/core/plot/candlestick.py,sha256=
|
|
15
|
+
maidr/core/plot/candlestick.py,sha256=0yKeuchDd-BdepKcKo8Dsi6Kl3FoAUqgP7ggMCitsRY,5460
|
|
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=
|
|
19
|
+
maidr/core/plot/lineplot.py,sha256=48aEkx8rjZ9lYEZSHWCJcSzdVblKwcdJZDZK0vnxmPo,4291
|
|
20
20
|
maidr/core/plot/maidr_plot.py,sha256=DN4TTRNt_SCqGa_mbkHrnpCk-eUQm71HoFRqs3bB6xk,3868
|
|
21
21
|
maidr/core/plot/maidr_plot_factory.py,sha256=NW2iFScswgXbAC9rAOo4iMkAFsjY43DAvFioGr0yzx4,2732
|
|
22
|
-
maidr/core/plot/mplfinance_barplot.py,sha256=
|
|
23
|
-
maidr/core/plot/mplfinance_lineplot.py,sha256=
|
|
22
|
+
maidr/core/plot/mplfinance_barplot.py,sha256=GPjjxdXVvfW0_xBhRZMmgmDNqSKrWLvL6yuonOdfTZk,5208
|
|
23
|
+
maidr/core/plot/mplfinance_lineplot.py,sha256=JYuZP-kVEfEC62tMNtzcsy24j57nZuhKT_4_VOnAAB8,6933
|
|
24
24
|
maidr/core/plot/regplot.py,sha256=b7u6bGTz1IxKahplNUrfwIr_OGSwMJ2BuLgFAVjL0s0,2744
|
|
25
25
|
maidr/core/plot/scatterplot.py,sha256=o0i0uS-wXK9ZrENxneoHbh3-u-2goRONp19Yu9QLsaY,1257
|
|
26
26
|
maidr/exception/__init__.py,sha256=PzaXoYBhyZxMDcJkuxJugDx7jZeseI0El6LpxIwXyG4,46
|
|
27
27
|
maidr/exception/extraction_error.py,sha256=rd37Oxa9gn2OWFWt9AOH5fv0hNd3sAWGvpDMFBuJY2I,607
|
|
28
28
|
maidr/patch/__init__.py,sha256=FnkoUQJC2ODhLO37GwgRVSitBCRax42Ti0e4NIAgdO0,236
|
|
29
|
-
maidr/patch/barplot.py,sha256=
|
|
29
|
+
maidr/patch/barplot.py,sha256=qdUy5Y8zkMg4dH3fFh93OYzLdar4nl1u5O2Jcw4d2zI,2433
|
|
30
30
|
maidr/patch/boxplot.py,sha256=l7wDD4pDi4ZbsL5EX5XDhPRxgtSIFSrFguMOZ7IC2eg,2845
|
|
31
31
|
maidr/patch/candlestick.py,sha256=NFkzwpxmLBpWmb5s05pjk6obNMQee-xIEZTqGkbhhqM,1776
|
|
32
32
|
maidr/patch/clear.py,sha256=2Sc4CIt5jRGkew3TxFsBZm-uowC9yDSxtraEcXZjmGw,396
|
|
@@ -35,23 +35,23 @@ maidr/patch/heatmap.py,sha256=uxLLg530Ql9KVC5rxk8vnwPHXBWWHwYgJRkyHY-tJzs,1048
|
|
|
35
35
|
maidr/patch/highlight.py,sha256=I1dGFHJAnVd0AHVnMJzk_TE8BC8Uv-I6fTzSrJLU5QM,1155
|
|
36
36
|
maidr/patch/histogram.py,sha256=k3N0RUf1SQ2402pwbaY5QyS98KnLWvr9glCHQw9NTko,2378
|
|
37
37
|
maidr/patch/kdeplot.py,sha256=qv-OKzuop2aTrkZgUe2OnLxvV-KMyeXt1Td0_uZeHzE,2338
|
|
38
|
-
maidr/patch/lineplot.py,sha256=
|
|
39
|
-
maidr/patch/mplfinance.py,sha256=
|
|
38
|
+
maidr/patch/lineplot.py,sha256=kvTAiOddy1g5GMP456Awk21NUEZfn-vWaYXy5GTVtuA,1841
|
|
39
|
+
maidr/patch/mplfinance.py,sha256=73aYyFYnAX-AXqPid8ScfexEU2Y8fC9L_tEidzPcKZo,8008
|
|
40
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
|
|
44
44
|
maidr/util/environment.py,sha256=-2LyZUpHojBCMEbkr_xkcC-_IDqtGDALB8683v7kTdI,5253
|
|
45
|
+
maidr/util/mplfinance_utils.py,sha256=aWNRkNS2IAF4YYEF9w7CcmcKWMGg3KkYJAv0xL8KcyY,14417
|
|
46
|
+
maidr/util/plot_detection.py,sha256=bgLHoDcHSRwOiyKzUK3EqGwdAIhF44ocHW5ox6xYGZw,3883
|
|
47
|
+
maidr/util/regression_line_utils.py,sha256=yFKr-H0whT_su2YVZwNksBLp5EC5s77sr6HUFgNcsyY,2329
|
|
48
|
+
maidr/util/svg_utils.py,sha256=2gyzBtNKFHs0utrw1iOlxTmznzivOWQMV2aW8zu2c8E,1442
|
|
45
49
|
maidr/util/mixin/__init__.py,sha256=aGJZNhtWh77yIVPc7ipIZm1OajigjMtCWYKPuDWTC-c,217
|
|
46
50
|
maidr/util/mixin/extractor_mixin.py,sha256=oHtwpmS5kARvaLrSO3DKTPQxyFUw9nOcKN7rzTj1q4g,5192
|
|
47
51
|
maidr/util/mixin/merger_mixin.py,sha256=V0qLw_6DUB7X6CQ3BCMpsCQX_ZuwAhoSTm_E4xAJFKM,712
|
|
48
|
-
maidr/util/mplfinance_utils.py,sha256=AvDzvAAQbMsPZxcxWr3DwctZMp4xW5CkQEBezWTk1mY,13704
|
|
49
|
-
maidr/util/plot_detection.py,sha256=bVSocZMGCLP6CduRSpOmwIzLFWEBnNdYN9T1ULfVPMw,3893
|
|
50
|
-
maidr/util/regression_line_utils.py,sha256=yFKr-H0whT_su2YVZwNksBLp5EC5s77sr6HUFgNcsyY,2329
|
|
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.
|
|
55
|
-
maidr-1.4.
|
|
56
|
-
maidr-1.4.
|
|
57
|
-
maidr-1.4.
|
|
54
|
+
maidr-1.4.8.dist-info/METADATA,sha256=k2BDw4pB46XBISkX40QpD60gI2cF6_l1lxP97uxNhMQ,3094
|
|
55
|
+
maidr-1.4.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
56
|
+
maidr-1.4.8.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
57
|
+
maidr-1.4.8.dist-info/RECORD,,
|
|
File without changes
|