maidr 1.6.0__tar.gz → 1.7.0__tar.gz

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.
Files changed (163) hide show
  1. {maidr-1.6.0 → maidr-1.7.0}/CHANGELOG.md +34 -0
  2. {maidr-1.6.0 → maidr-1.7.0}/PKG-INFO +1 -2
  3. {maidr-1.6.0 → maidr-1.7.0}/docs/examples.qmd +88 -2
  4. {maidr-1.6.0 → maidr-1.7.0}/docs/index.qmd +28 -2
  5. maidr-1.7.0/example/candle_stick/test_data_daily_current_year.csv +11 -0
  6. maidr-1.7.0/example/candle_stick/test_data_daily_mixed_years.csv +11 -0
  7. maidr-1.7.0/example/candle_stick/test_data_hourly.csv +11 -0
  8. maidr-1.7.0/example/candle_stick/test_data_minute.csv +11 -0
  9. maidr-1.7.0/example/candle_stick/test_data_weekly.csv +11 -0
  10. {maidr-1.6.0 → maidr-1.7.0}/maidr/__init__.py +1 -1
  11. maidr-1.7.0/maidr/core/plot/candlestick.py +233 -0
  12. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/mplfinance_barplot.py +18 -1
  13. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/mplfinance_lineplot.py +11 -3
  14. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/candlestick.py +27 -1
  15. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/mplfinance.py +38 -5
  16. maidr-1.7.0/maidr/util/datetime_conversion.py +406 -0
  17. {maidr-1.6.0 → maidr-1.7.0}/pyproject.toml +1 -2
  18. {maidr-1.6.0 → maidr-1.7.0}/uv.lock +1 -3
  19. maidr-1.6.0/maidr/core/plot/candlestick.py +0 -141
  20. {maidr-1.6.0 → maidr-1.7.0}/.commitlintrc.cjs +0 -0
  21. {maidr-1.6.0 → maidr-1.7.0}/.editorconfig +0 -0
  22. {maidr-1.6.0 → maidr-1.7.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  23. {maidr-1.6.0 → maidr-1.7.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  24. {maidr-1.6.0 → maidr-1.7.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  25. {maidr-1.6.0 → maidr-1.7.0}/.github/copilot-instructions.md +0 -0
  26. {maidr-1.6.0 → maidr-1.7.0}/.github/workflows/ci.yml +0 -0
  27. {maidr-1.6.0 → maidr-1.7.0}/.github/workflows/docs.yml +0 -0
  28. {maidr-1.6.0 → maidr-1.7.0}/.github/workflows/release.yml +0 -0
  29. {maidr-1.6.0 → maidr-1.7.0}/.gitignore +0 -0
  30. {maidr-1.6.0 → maidr-1.7.0}/.pre-commit-config.yaml +0 -0
  31. {maidr-1.6.0 → maidr-1.7.0}/.vscode/extensions.json +0 -0
  32. {maidr-1.6.0 → maidr-1.7.0}/.vscode/settings.json +0 -0
  33. {maidr-1.6.0 → maidr-1.7.0}/CONDUCT.md +0 -0
  34. {maidr-1.6.0 → maidr-1.7.0}/CONTRIBUTING.md +0 -0
  35. {maidr-1.6.0 → maidr-1.7.0}/LICENSE +0 -0
  36. {maidr-1.6.0 → maidr-1.7.0}/README.md +0 -0
  37. {maidr-1.6.0 → maidr-1.7.0}/docs/.gitignore +0 -0
  38. {maidr-1.6.0 → maidr-1.7.0}/docs/CNAME +0 -0
  39. {maidr-1.6.0 → maidr-1.7.0}/docs/_environment +0 -0
  40. {maidr-1.6.0 → maidr-1.7.0}/docs/_extensions/machow/interlinks/.gitignore +0 -0
  41. {maidr-1.6.0 → maidr-1.7.0}/docs/_extensions/machow/interlinks/_extension.yml +0 -0
  42. {maidr-1.6.0 → maidr-1.7.0}/docs/_extensions/machow/interlinks/interlinks.lua +0 -0
  43. {maidr-1.6.0 → maidr-1.7.0}/docs/_extensions/shafayetShafee/line-highlight/_extension.yml +0 -0
  44. {maidr-1.6.0 → maidr-1.7.0}/docs/_extensions/shafayetShafee/line-highlight/line-highlight.lua +0 -0
  45. {maidr-1.6.0 → maidr-1.7.0}/docs/_extensions/shafayetShafee/line-highlight/resources/css/line-highlight.css +0 -0
  46. {maidr-1.6.0 → maidr-1.7.0}/docs/_extensions/shafayetShafee/line-highlight/resources/js/line-highlight.js +0 -0
  47. {maidr-1.6.0 → maidr-1.7.0}/docs/_quarto.yml +0 -0
  48. {maidr-1.6.0 → maidr-1.7.0}/docs/styles.css +0 -0
  49. {maidr-1.6.0 → maidr-1.7.0}/example/bar/example_bar_plot.ipynb +0 -0
  50. {maidr-1.6.0 → maidr-1.7.0}/example/bar/matplotlib/example_mpl_bar_plot.py +0 -0
  51. {maidr-1.6.0 → maidr-1.7.0}/example/bar/seaborn/example_sns_bar_plot.py +0 -0
  52. {maidr-1.6.0 → maidr-1.7.0}/example/box/example_box_plot.ipynb +0 -0
  53. {maidr-1.6.0 → maidr-1.7.0}/example/box/matplotlib/example_mpl_box.py +0 -0
  54. {maidr-1.6.0 → maidr-1.7.0}/example/box/seaborn/example_sns_box.py +0 -0
  55. {maidr-1.6.0 → maidr-1.7.0}/example/candle_stick/legacy_candlestick_example.py +0 -0
  56. {maidr-1.6.0 → maidr-1.7.0}/example/candle_stick/mplfinance_candlestick_example.py +0 -0
  57. {maidr-1.6.0 → maidr-1.7.0}/example/candle_stick/volcandat.csv +0 -0
  58. {maidr-1.6.0 → maidr-1.7.0}/example/count/example_count_plot.ipynb +0 -0
  59. {maidr-1.6.0 → maidr-1.7.0}/example/count/seaborn/example_sns_count_plot.py +0 -0
  60. {maidr-1.6.0 → maidr-1.7.0}/example/dodged/matplotlib/example_mpl_dodged.py +0 -0
  61. {maidr-1.6.0 → maidr-1.7.0}/example/dodged/seaborn/example_sns_dodged.py +0 -0
  62. {maidr-1.6.0 → maidr-1.7.0}/example/facet-subplots/matplotlib/example_mpl_facet_bar_plot.py +0 -0
  63. {maidr-1.6.0 → maidr-1.7.0}/example/facet-subplots/matplotlib/example_mpl_facet_combined_plot.py +0 -0
  64. {maidr-1.6.0 → maidr-1.7.0}/example/facet-subplots/seaborn/example_sns_facet_bar_plot.py +0 -0
  65. {maidr-1.6.0 → maidr-1.7.0}/example/facet-subplots/seaborn/example_sns_facet_combined_plot.py +0 -0
  66. {maidr-1.6.0 → maidr-1.7.0}/example/flask/test_flask_app.py +0 -0
  67. {maidr-1.6.0 → maidr-1.7.0}/example/heatmap/example_heatmap_plot.ipynb +0 -0
  68. {maidr-1.6.0 → maidr-1.7.0}/example/heatmap/matplotlib/example_mpl_heatmap.py +0 -0
  69. {maidr-1.6.0 → maidr-1.7.0}/example/heatmap/seaborn/example_sns_heatmap.py +0 -0
  70. {maidr-1.6.0 → maidr-1.7.0}/example/histogram/example_histogram_plot.ipynb +0 -0
  71. {maidr-1.6.0 → maidr-1.7.0}/example/histogram/matplotlib/example_mpl_hist.py +0 -0
  72. {maidr-1.6.0 → maidr-1.7.0}/example/histogram/matplotlib/histogram_with_kde_matplotlib.py +0 -0
  73. {maidr-1.6.0 → maidr-1.7.0}/example/histogram/seaborn/example_sns_hist.py +0 -0
  74. {maidr-1.6.0 → maidr-1.7.0}/example/histogram/seaborn/histogram_with_kde_seaborn.py +0 -0
  75. {maidr-1.6.0 → maidr-1.7.0}/example/kde/example_kde_plots.ipynb +0 -0
  76. {maidr-1.6.0 → maidr-1.7.0}/example/kde/matplotlib/multiple_kde_matplotlib.py +0 -0
  77. {maidr-1.6.0 → maidr-1.7.0}/example/kde/matplotlib/single_kde_matplotlib.py +0 -0
  78. {maidr-1.6.0 → maidr-1.7.0}/example/kde/seaborn/multiple_kde_seaborn.py +0 -0
  79. {maidr-1.6.0 → maidr-1.7.0}/example/kde/seaborn/single_kde_seaborn.py +0 -0
  80. {maidr-1.6.0 → maidr-1.7.0}/example/line/example_line_plot.ipynb +0 -0
  81. {maidr-1.6.0 → maidr-1.7.0}/example/line/matplotlib/example_mpl_line.py +0 -0
  82. {maidr-1.6.0 → maidr-1.7.0}/example/line/seaborn/example_sns_line.py +0 -0
  83. {maidr-1.6.0 → maidr-1.7.0}/example/multilayer/example_mpl_multilayer.py +0 -0
  84. {maidr-1.6.0 → maidr-1.7.0}/example/multilayer/example_multilayer_plot.ipynb +0 -0
  85. {maidr-1.6.0 → maidr-1.7.0}/example/multiline/example_multiline_plot.ipynb +0 -0
  86. {maidr-1.6.0 → maidr-1.7.0}/example/multiline/matplotlib/example_mpl_multiline.py +0 -0
  87. {maidr-1.6.0 → maidr-1.7.0}/example/multiline/seaborn/example_sns_multiline.py +0 -0
  88. {maidr-1.6.0 → maidr-1.7.0}/example/multipanel/example_multipanel_plot.ipynb +0 -0
  89. {maidr-1.6.0 → maidr-1.7.0}/example/multipanel/matplotlib/example_mpl_multipanel.py +0 -0
  90. {maidr-1.6.0 → maidr-1.7.0}/example/multipanel/seaborn/example_sns_multipanel.py +0 -0
  91. {maidr-1.6.0 → maidr-1.7.0}/example/quarto/demo.qmd +0 -0
  92. {maidr-1.6.0 → maidr-1.7.0}/example/reg/example_reg_plots.ipynb +0 -0
  93. {maidr-1.6.0 → maidr-1.7.0}/example/reg/matplotlib/example_matplotlib_smooth_plot.py +0 -0
  94. {maidr-1.6.0 → maidr-1.7.0}/example/reg/seaborn/example_sns_reg.py +0 -0
  95. {maidr-1.6.0 → maidr-1.7.0}/example/scatter/example_scatter_plot.ipynb +0 -0
  96. {maidr-1.6.0 → maidr-1.7.0}/example/scatter/matplotlib/example_mpl_scatter.py +0 -0
  97. {maidr-1.6.0 → maidr-1.7.0}/example/scatter/seaborn/example_sns_scatter.py +0 -0
  98. {maidr-1.6.0 → maidr-1.7.0}/example/shiny/example_shiny_scatter.py +0 -0
  99. {maidr-1.6.0 → maidr-1.7.0}/example/stacked/matplotlib/example_mpl_stacked.html +0 -0
  100. {maidr-1.6.0 → maidr-1.7.0}/example/stacked/matplotlib/example_mpl_stacked.py +0 -0
  101. {maidr-1.6.0 → maidr-1.7.0}/example/stacked/seaborn/example_sns_stacked.html +0 -0
  102. {maidr-1.6.0 → maidr-1.7.0}/example/stacked/seaborn/example_sns_stacked.py +0 -0
  103. {maidr-1.6.0 → maidr-1.7.0}/example/streamlit/example_streamlit_app.py +0 -0
  104. {maidr-1.6.0 → maidr-1.7.0}/maidr/api.py +0 -0
  105. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/__init__.py +0 -0
  106. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/context_manager.py +0 -0
  107. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/enum/__init__.py +0 -0
  108. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/enum/library.py +0 -0
  109. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/enum/maidr_key.py +0 -0
  110. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/enum/plot_type.py +0 -0
  111. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/enum/smooth_keywords.py +0 -0
  112. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/figure_manager.py +0 -0
  113. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/maidr.py +0 -0
  114. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/__init__.py +0 -0
  115. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/barplot.py +0 -0
  116. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/boxplot.py +0 -0
  117. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/grouped_barplot.py +0 -0
  118. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/heatmap.py +0 -0
  119. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/histogram.py +0 -0
  120. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/lineplot.py +0 -0
  121. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/maidr_plot.py +0 -0
  122. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/maidr_plot_factory.py +0 -0
  123. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/regplot.py +0 -0
  124. {maidr-1.6.0 → maidr-1.7.0}/maidr/core/plot/scatterplot.py +0 -0
  125. {maidr-1.6.0 → maidr-1.7.0}/maidr/exception/__init__.py +0 -0
  126. {maidr-1.6.0 → maidr-1.7.0}/maidr/exception/extraction_error.py +0 -0
  127. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/__init__.py +0 -0
  128. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/barplot.py +0 -0
  129. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/boxplot.py +0 -0
  130. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/clear.py +0 -0
  131. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/common.py +0 -0
  132. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/heatmap.py +0 -0
  133. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/highlight.py +0 -0
  134. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/histogram.py +0 -0
  135. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/kdeplot.py +0 -0
  136. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/lineplot.py +0 -0
  137. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/regplot.py +0 -0
  138. {maidr-1.6.0 → maidr-1.7.0}/maidr/patch/scatterplot.py +0 -0
  139. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/__init__.py +0 -0
  140. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/dedup_utils.py +0 -0
  141. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/environment.py +0 -0
  142. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/mixin/__init__.py +0 -0
  143. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/mixin/extractor_mixin.py +0 -0
  144. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/mixin/merger_mixin.py +0 -0
  145. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/mplfinance_utils.py +0 -0
  146. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/plot_detection.py +0 -0
  147. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/regression_line_utils.py +0 -0
  148. {maidr-1.6.0 → maidr-1.7.0}/maidr/util/svg_utils.py +0 -0
  149. {maidr-1.6.0 → maidr-1.7.0}/maidr/widget/__init__.py +0 -0
  150. {maidr-1.6.0 → maidr-1.7.0}/maidr/widget/shiny.py +0 -0
  151. {maidr-1.6.0 → maidr-1.7.0}/tests/__init__.py +0 -0
  152. {maidr-1.6.0 → maidr-1.7.0}/tests/conftest.py +0 -0
  153. {maidr-1.6.0 → maidr-1.7.0}/tests/core/__init__.py +0 -0
  154. {maidr-1.6.0 → maidr-1.7.0}/tests/core/enum/__init__.py +0 -0
  155. {maidr-1.6.0 → maidr-1.7.0}/tests/core/plot/__init__.py +0 -0
  156. {maidr-1.6.0 → maidr-1.7.0}/tests/core/test_figure_manager.py +0 -0
  157. {maidr-1.6.0 → maidr-1.7.0}/tests/core/test_maidr_plot.py +0 -0
  158. {maidr-1.6.0 → maidr-1.7.0}/tests/core/test_maidr_plot_factory.py +0 -0
  159. {maidr-1.6.0 → maidr-1.7.0}/tests/fixture/__init__.py +0 -0
  160. {maidr-1.6.0 → maidr-1.7.0}/tests/fixture/library_factory.py +0 -0
  161. {maidr-1.6.0 → maidr-1.7.0}/tests/fixture/matplotlib_factory.py +0 -0
  162. {maidr-1.6.0 → maidr-1.7.0}/tests/fixture/seaborn_factory.py +0 -0
  163. {maidr-1.6.0 → maidr-1.7.0}/tox.ini +0 -0
@@ -1,6 +1,40 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v1.7.0 (2025-08-21)
5
+
6
+ ### Features
7
+
8
+ - Format date in candlestick ([#234](https://github.com/xability/py-maidr/pull/234),
9
+ [`ffe03f7`](https://github.com/xability/py-maidr/commit/ffe03f7a2368ef33a4266692e7b652daafa14a30))
10
+
11
+
12
+ ## v1.6.1 (2025-08-13)
13
+
14
+ ### Bug Fixes
15
+
16
+ - Add new selector logic for candlestick plots
17
+ ([#231](https://github.com/xability/py-maidr/pull/231),
18
+ [`66cd73a`](https://github.com/xability/py-maidr/commit/66cd73adb04f77c0b83fd6e2d9cf757ee909bd69))
19
+
20
+ ### Continuous Integration
21
+
22
+ - Remove virtualenv dependecny ([#228](https://github.com/xability/py-maidr/pull/228),
23
+ [`b8e1423`](https://github.com/xability/py-maidr/commit/b8e1423c2ecd073bd1037466f68577242872df6b))
24
+
25
+ ### Documentation
26
+
27
+ - Update user manual to reflect all supported plot types with proper technical descriptions
28
+ ([#230](https://github.com/xability/py-maidr/pull/230),
29
+ [`bae1163`](https://github.com/xability/py-maidr/commit/bae116322cb580f5c528da2857a7ca3ec2a655a7))
30
+
31
+ Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
32
+
33
+ Co-authored-by: jooyoungseo <19754711+jooyoungseo@users.noreply.github.com>
34
+
35
+ Co-authored-by: JooYoung Seo <jseo1005@illinois.edu>
36
+
37
+
4
38
  ## v1.6.0 (2025-08-04)
5
39
 
6
40
  ### Continuous Integration
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maidr
3
- Version: 1.6.0
3
+ Version: 1.7.0
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
@@ -28,7 +28,6 @@ Requires-Dist: htmltools>=0.5
28
28
  Requires-Dist: lxml>=5.1.0
29
29
  Requires-Dist: mplfinance>=0.12.10b0
30
30
  Requires-Dist: numpy>=1.26
31
- Requires-Dist: virtualenv<21,>=20.26.6
32
31
  Requires-Dist: wrapt<2,>=1.16.0
33
32
  Provides-Extra: jupyter
34
33
  Requires-Dist: ipykernel>=6.0.0; extra == 'jupyter'
@@ -49,6 +49,33 @@ plt.ylabel("Body Mass (g)")
49
49
  maidr.show(bar_plot) #<<
50
50
  ```
51
51
 
52
+
53
+ ### Count Plots
54
+
55
+ ```{python}
56
+ #| warning: false
57
+ #| fig-alt: Count plot showing frequency of categorical data
58
+
59
+ import matplotlib.pyplot as plt
60
+ import seaborn as sns
61
+
62
+ import maidr #<<
63
+
64
+ # Load the Titanic dataset
65
+ titanic = sns.load_dataset("titanic")
66
+
67
+ # Create a count plot
68
+ plt.figure(figsize=(6, 6))
69
+ count_plot = sns.countplot(x="class", data=titanic, palette="viridis") #<<
70
+
71
+ plt.title("Passenger Class Distribution on the Titanic")
72
+ plt.xlabel("Passenger Class")
73
+ plt.ylabel("Count")
74
+
75
+ # plt.show()
76
+ maidr.show(count_plot) #<<
77
+ ```
78
+
52
79
  #### Vertical Stacked Bar Plot
53
80
 
54
81
  ```{python}
@@ -163,6 +190,33 @@ plt.ylabel("Frequency")
163
190
  maidr.show(hist_plot) #<<
164
191
  ```
165
192
 
193
+ ### KDE (Kernel Density Estimation) Plots
194
+
195
+ ```{python}
196
+ #| warning: false
197
+ #| fig-alt: KDE plot showing probability density distribution
198
+
199
+ import matplotlib.pyplot as plt
200
+ import seaborn as sns
201
+ import numpy as np
202
+
203
+ import maidr #<<
204
+
205
+ # Generate sample data
206
+ np.random.seed(42)
207
+ data = np.random.randn(500)
208
+
209
+ # Create a KDE plot
210
+ plt.figure(figsize=(6, 6))
211
+ kde_plot = sns.kdeplot(data, fill=True, color="blue") #<<
212
+
213
+ plt.title("KDE Plot of Random Data")
214
+ plt.xlabel("Value")
215
+ plt.ylabel("Density")
216
+
217
+ # plt.show()
218
+ maidr.show(kde_plot) #<<
219
+ ```
166
220
 
167
221
  ### Line Plots
168
222
 
@@ -270,8 +324,6 @@ maidr.show(heatmap) #<<
270
324
 
271
325
  ### Box Plot
272
326
 
273
- * **Note**: Visual highlight feature has not been implemented in the box plot yet.
274
-
275
327
  ```{python}
276
328
  #| fig-alt: Box plot of petal length by species from the Iris dataset
277
329
 
@@ -321,6 +373,40 @@ plt.ylabel("Sepal Width")
321
373
  maidr.show(scatter_plot) #<<
322
374
  ```
323
375
 
376
+ ### Regression Plots
377
+
378
+ ```{python}
379
+ #| warning: false
380
+ #| fig-alt: Regression plot with scatter points and fitted line
381
+
382
+ import matplotlib.pyplot as plt
383
+ import seaborn as sns
384
+ import numpy as np
385
+
386
+ import maidr #<<
387
+
388
+ # Generate sample data
389
+ np.random.seed(42)
390
+ x = np.linspace(0, 10, 50)
391
+ y = 2 * x + 1 + np.random.normal(0, 2, 50)
392
+
393
+ # Create a regression plot
394
+ plt.figure(figsize=(6, 6))
395
+ reg_plot = sns.regplot(
396
+ x=x,
397
+ y=y,
398
+ scatter_kws={"s": 50, "alpha": 0.7},
399
+ line_kws={"color": "red", "lw": 2},
400
+ ) #<<
401
+
402
+ plt.title("Regression Plot with Fitted Line")
403
+ plt.xlabel("X values")
404
+ plt.ylabel("Y values")
405
+
406
+ # plt.show()
407
+ maidr.show(reg_plot) #<<
408
+ ```
409
+
324
410
  ### Multi-Layered Plots
325
411
 
326
412
  ```{python}
@@ -40,7 +40,7 @@ The following summarizes the key features and design principles of Py maidr:
40
40
 
41
41
  7. Reproducibility: maidr supports the generation of accessible data visualizations as part of the reproducible data science workflow with [Quarto scientific publishing system](https://quarto.org/). You can easily create accessible data representations within your reproducible reports, website blogs, slides, e-books, dashboards, and more.
42
42
 
43
- 8. Scalability: maidr supports a wide range of data visualization types, including bar plots, histograms, line plots, box plots, heatmaps, scatter plots, and more. maidr is designed to be extensible to support new visualization types. [Multi-figure and multi-layer visualizations are underway to support complex data visualizations.]
43
+ 8. Scalability: maidr supports a wide range of data visualization types, including bar plots, histograms, line plots, box plots, heatmaps, scatter plots, and more. maidr is designed to be extensible to support new visualization types. Multi-figure and multi-layer visualizations are also supported.
44
44
 
45
45
  Our core philosophy is to make data science accessible to everyone, regardless of their visual dis/abilities. We believe that by making data visualizations accessible, we can empower blind and sighted users to work together on data science projects, share insights, and make data-driven decisions collaboratively.
46
46
 
@@ -52,10 +52,18 @@ We currently support the following data visualization libraries in Python:, and
52
52
 
53
53
  * One-factor bar plot having one x (categorical) and one y (numerical/count) axis.
54
54
 
55
+ * Stacked bar plot having one x (categorical) and one y (numerical/count) axis with multiple data series stacked vertically.
56
+
57
+ * Dodged (grouped) bar plot having one x (categorical) and one y (numerical/count) axis with multiple data series displayed side-by-side.
58
+
55
59
  * One distribution histogram having one x (numerical) and y (numerical/frequency) axis.
56
60
 
61
+ * KDE (Kernel Density Estimation) plot having one x (numerical) and one y (density) axis showing probability density curves.
62
+
57
63
  * Single line plot having one x (numerical) and one y (numerical) axis.
58
64
 
65
+ * Multi-line plot having one x (numerical) and one y (numerical) axis with multiple data series on the same axes.
66
+
59
67
  * Vertical box plot having one x (categorical) and one y (numerical) axis.
60
68
 
61
69
  * Horizontal box plot having one x (numerical) and one y (categorical) axis.
@@ -66,15 +74,27 @@ We currently support the following data visualization libraries in Python:, and
66
74
 
67
75
  * Scatter plot having one x (numerical) and one y (numerical) axis.
68
76
 
77
+ * Regression plot having one x (numerical) and one y (numerical) axis with scatter points and fitted regression line.
78
+
79
+ * Candlestick chart having one x (time/date) and four y (numerical) axes (open, high, low, close) for financial data visualization (using mplfinance).
80
+
81
+ * Multi-layered plots combining different plot types on the same figure with shared axes.
82
+
83
+ * Multi-panel plots (subplots) with multiple charts in a grid layout having independent axes.
84
+
85
+ * Facet plots showing the same chart type across different data subsets with shared axis scales.
86
+
69
87
 
70
88
  ### Seaborn
71
89
 
72
90
  * `sns.barplot()`: One-factor bar plot having one x (categorical) and one y (numerical/count) axis.
73
91
 
74
- * Note: We also support `sns.countplot()`
92
+ * `sns.countplot()`: Count plot having one x (categorical) and one y (count) axis showing the frequency of categorical data.
75
93
 
76
94
  * `sns.histplot()`: One distribution histogram having one x (numerical) and y (numerical/frequency) axis.
77
95
 
96
+ * `sns.kdeplot()`: KDE (Kernel Density Estimation) plot having one x (numerical) and one y (density) axis showing probability density curves.
97
+
78
98
  * `sns.lineplot()`: Single line plot having one x (numerical) and one y (numerical) axis.
79
99
 
80
100
  * `sns.boxplot(..., orient="v")`: Vertical box plot having one x (categorical) and one y (numerical) axis.
@@ -87,6 +107,12 @@ We currently support the following data visualization libraries in Python:, and
87
107
 
88
108
  * `sns.scatterplot()`: Scatter plot having one x (numerical) and one y (numerical) axis.
89
109
 
110
+ * `sns.regplot()`: Regression plot having one x (numerical) and one y (numerical) axis with scatter points and fitted regression line.
111
+
112
+ ### Additional Libraries
113
+
114
+ * **mplfinance**: Candlestick charts having one x (time/date) and four y (numerical) axes (open, high, low, close) for financial data with support for moving averages and volume data.
115
+
90
116
 
91
117
  ## Installation
92
118
 
@@ -0,0 +1,11 @@
1
+ Date,Open,High,Low,Close,Volume
2
+ 2024-01-15,3050.72,3066.95,3050.72,3066.91,510301237
3
+ 2024-01-16,3078.96,3085.20,3074.87,3078.27,524848878
4
+ 2024-01-17,3080.80,3083.95,3072.15,3074.62,585634570
5
+ 2024-01-18,3075.10,3078.34,3065.89,3076.78,544288522
6
+ 2024-01-19,3087.02,3097.77,3080.23,3085.18,566117910
7
+ 2024-01-22,3081.25,3093.09,3073.58,3093.08,460757054
8
+ 2024-01-23,3080.33,3088.33,3075.82,3087.01,366044400
9
+ 2024-01-24,3089.28,3102.61,3084.73,3091.84,434953689
10
+ 2024-01-25,3084.18,3098.06,3078.80,3094.04,454607412
11
+ 2024-01-26,3090.75,3098.20,3083.26,3096.63,408390424
@@ -0,0 +1,11 @@
1
+ Date,Open,High,Low,Close,Volume
2
+ 2023-12-15,3050.72,3066.95,3050.72,3066.91,510301237
3
+ 2023-12-18,3078.96,3085.20,3074.87,3078.27,524848878
4
+ 2023-12-19,3080.80,3083.95,3072.15,3074.62,585634570
5
+ 2023-12-20,3075.10,3078.34,3065.89,3076.78,544288522
6
+ 2023-12-21,3087.02,3097.77,3080.23,3085.18,566117910
7
+ 2023-12-22,3081.25,3093.09,3073.58,3093.08,460757054
8
+ 2024-01-02,3080.33,3088.33,3075.82,3087.01,366044400
9
+ 2024-01-03,3089.28,3102.61,3084.73,3091.84,434953689
10
+ 2024-01-04,3084.18,3098.06,3078.80,3094.04,454607412
11
+ 2024-01-05,3090.75,3098.20,3083.26,3096.63,408390424
@@ -0,0 +1,11 @@
1
+ Date,Open,High,Low,Close,Volume
2
+ 2024-01-15 09:00:00,3050.72,3066.95,3050.72,3066.91,510301237
3
+ 2024-01-15 10:00:00,3078.96,3085.20,3074.87,3078.27,524848878
4
+ 2024-01-15 11:00:00,3080.80,3083.95,3072.15,3074.62,585634570
5
+ 2024-01-15 12:00:00,3075.10,3078.34,3065.89,3076.78,544288522
6
+ 2024-01-15 13:00:00,3087.02,3097.77,3080.23,3085.18,566117910
7
+ 2024-01-15 14:00:00,3081.25,3093.09,3073.58,3093.08,460757054
8
+ 2024-01-15 15:00:00,3080.33,3088.33,3075.82,3087.01,366044400
9
+ 2024-01-15 16:00:00,3089.28,3102.61,3084.73,3091.84,434953689
10
+ 2024-01-16 09:00:00,3084.18,3098.06,3078.80,3094.04,454607412
11
+ 2024-01-16 10:00:00,3090.75,3098.20,3083.26,3096.63,408390424
@@ -0,0 +1,11 @@
1
+ Date,Open,High,Low,Close,Volume
2
+ 2024-01-15 09:30:00,3050.72,3066.95,3050.72,3066.91,510301237
3
+ 2024-01-15 09:31:00,3078.96,3085.20,3074.87,3078.27,524848878
4
+ 2024-01-15 09:32:00,3080.80,3083.95,3072.15,3074.62,585634570
5
+ 2024-01-15 09:33:00,3075.10,3078.34,3065.89,3076.78,544288522
6
+ 2024-01-15 09:34:00,3087.02,3097.77,3080.23,3085.18,566117910
7
+ 2024-01-15 09:35:00,3081.25,3093.09,3073.58,3093.08,460757054
8
+ 2024-01-15 09:36:00,3080.33,3088.33,3075.82,3087.01,366044400
9
+ 2024-01-15 09:37:00,3089.28,3102.61,3084.73,3091.84,434953689
10
+ 2024-01-15 09:38:00,3084.18,3098.06,3078.80,3094.04,454607412
11
+ 2024-01-15 09:39:00,3090.75,3098.20,3083.26,3096.63,408390424
@@ -0,0 +1,11 @@
1
+ Date,Open,High,Low,Close,Volume
2
+ 2024-01-01,3050.72,3066.95,3050.72,3066.91,510301237
3
+ 2024-01-08,3078.96,3085.20,3074.87,3078.27,524848878
4
+ 2024-01-15,3080.80,3083.95,3072.15,3074.62,585634570
5
+ 2024-01-22,3075.10,3078.34,3065.89,3076.78,544288522
6
+ 2024-01-29,3087.02,3097.77,3080.23,3085.18,566117910
7
+ 2024-02-05,3081.25,3093.09,3073.58,3093.08,460757054
8
+ 2024-02-12,3080.33,3088.33,3075.82,3087.01,366044400
9
+ 2024-02-19,3089.28,3102.61,3084.73,3091.84,434953689
10
+ 2024-02-26,3084.18,3098.06,3078.80,3094.04,454607412
11
+ 2024-03-04,3090.75,3098.20,3083.26,3096.63,408390424
@@ -1,4 +1,4 @@
1
- __version__ = "1.6.0"
1
+ __version__ = "1.7.0"
2
2
 
3
3
  from .api import close, render, save_html, show, stacked
4
4
  from .core import Maidr
@@ -0,0 +1,233 @@
1
+ from __future__ import annotations
2
+
3
+ import uuid
4
+ from typing import Union, Dict
5
+ from matplotlib.axes import Axes
6
+ from matplotlib.patches import Rectangle
7
+ import numpy as np
8
+
9
+ from maidr.core.enum import PlotType
10
+ from maidr.core.plot import MaidrPlot
11
+ from maidr.core.enum.maidr_key import MaidrKey
12
+ from maidr.exception import ExtractionError
13
+ from maidr.util.mplfinance_utils import MplfinanceDataExtractor
14
+
15
+
16
+ class CandlestickPlot(MaidrPlot):
17
+ """
18
+ Specialized candlestick plot class for mplfinance OHLC data.
19
+
20
+ This class handles the extraction and processing of candlestick data from mplfinance
21
+ plots, including proper date conversion and data validation.
22
+ """
23
+
24
+ def __init__(self, axes: list[Axes], **kwargs) -> None:
25
+ """
26
+ Initialize the CandlestickPlot.
27
+
28
+ Parameters
29
+ ----------
30
+ axes : list[Axes]
31
+ A list of Matplotlib Axes objects. Expected to contain at least
32
+ one Axes for OHLC data, and optionally a second for volume data.
33
+ **kwargs : dict
34
+ Additional keyword arguments.
35
+ """
36
+ self.axes = axes
37
+ # Ensure there's at least one axis for the superclass init
38
+ if not axes:
39
+ raise ValueError("Axes list cannot be empty.")
40
+ super().__init__(axes[0], PlotType.CANDLESTICK)
41
+
42
+ # Store custom collections passed from mplfinance patch
43
+ self._maidr_wick_collection = kwargs.get("_maidr_wick_collection", None)
44
+ self._maidr_body_collection = kwargs.get("_maidr_body_collection", None)
45
+ self._maidr_date_nums = kwargs.get("_maidr_date_nums", None)
46
+ self._maidr_original_data = kwargs.get("_maidr_original_data", None) # Store original data
47
+ self._maidr_datetime_converter = kwargs.get("_maidr_datetime_converter", None)
48
+
49
+ # Store the GID for proper selector generation (legacy/shared)
50
+ self._maidr_gid = None
51
+ # Modern-path separate gids for body and wick
52
+ self._maidr_body_gid = None
53
+ self._maidr_wick_gid = None
54
+ if self._maidr_body_collection:
55
+ self._maidr_gid = self._maidr_body_collection.get_gid()
56
+ self._maidr_body_gid = self._maidr_gid
57
+ elif self._maidr_wick_collection:
58
+ self._maidr_gid = self._maidr_wick_collection.get_gid()
59
+ self._maidr_wick_gid = self._maidr_gid
60
+
61
+ def _extract_plot_data(self) -> list[dict]:
62
+ """
63
+ Extract candlestick data from the plot.
64
+
65
+ This method processes candlestick plots from both modern (mplfinance.plot) and
66
+ legacy (original_flavor) pipelines, extracting OHLC data and setting up
67
+ highlighting elements and GIDs.
68
+
69
+ Returns
70
+ -------
71
+ list[dict]
72
+ List of dictionaries containing candlestick data with keys:
73
+ - 'value': Date string
74
+ - 'open': Opening price (float)
75
+ - 'high': High price (float)
76
+ - 'low': Low price (float)
77
+ - 'close': Closing price (float)
78
+ - 'volume': Volume (float, typically 0 for candlestick-only plots)
79
+ """
80
+
81
+ # Get the custom collections from kwargs
82
+ body_collection = self._maidr_body_collection
83
+ wick_collection = self._maidr_wick_collection
84
+
85
+ if body_collection and wick_collection:
86
+ # Store the GIDs from the collections (modern path)
87
+ self._maidr_body_gid = body_collection.get_gid()
88
+ self._maidr_wick_gid = wick_collection.get_gid()
89
+ # Keep legacy gid filled for backward compatibility
90
+ self._maidr_gid = self._maidr_body_gid or self._maidr_wick_gid
91
+
92
+ # Use the original collections for highlighting
93
+ self._elements = [body_collection, wick_collection]
94
+
95
+ # Use datetime converter for enhanced data extraction
96
+ if self._maidr_datetime_converter is not None:
97
+ data = self._maidr_datetime_converter.extract_candlestick_data(
98
+ self.axes[0], wick_collection, body_collection
99
+ )
100
+ return data
101
+
102
+ # Fallback to original detection method
103
+ if not self.axes:
104
+ return []
105
+
106
+ ax_ohlc = self.axes[0]
107
+
108
+ # Look for Rectangle patches (original_flavor candlestick)
109
+ body_rectangles = []
110
+ for patch in ax_ohlc.patches:
111
+ if isinstance(patch, Rectangle):
112
+ body_rectangles.append(patch)
113
+
114
+ if body_rectangles:
115
+ # Set elements for highlighting
116
+ self._elements = body_rectangles
117
+
118
+ # Generate a GID for highlighting if none exists
119
+ if not self._maidr_gid:
120
+ self._maidr_gid = f"maidr-{uuid.uuid4()}"
121
+ # Set GID on all rectangles
122
+ for rect in body_rectangles:
123
+ rect.set_gid(self._maidr_gid)
124
+ # Keep a dedicated body gid for legacy dict selectors
125
+ self._maidr_body_gid = getattr(self, "_maidr_body_gid", None) or self._maidr_gid
126
+
127
+ # Assign a shared gid to wick Line2D (vertical 2-point lines) on the same axis
128
+ wick_lines = []
129
+ for line in ax_ohlc.get_lines():
130
+ try:
131
+ xydata = line.get_xydata()
132
+ if xydata is None:
133
+ continue
134
+ xy_arr = np.asarray(xydata)
135
+ if xy_arr.ndim == 2 and xy_arr.shape[0] == 2 and xy_arr.shape[1] >= 2:
136
+ x0 = float(xy_arr[0, 0])
137
+ x1 = float(xy_arr[1, 0])
138
+ if abs(x0 - x1) < 1e-10:
139
+ wick_lines.append(line)
140
+ except Exception:
141
+ continue
142
+ if wick_lines:
143
+ if not getattr(self, "_maidr_wick_gid", None):
144
+ self._maidr_wick_gid = f"maidr-{uuid.uuid4()}"
145
+ for line in wick_lines:
146
+ line.set_gid(self._maidr_wick_gid)
147
+
148
+ # Use the utility class to extract data
149
+ data = MplfinanceDataExtractor.extract_rectangle_candlestick_data(
150
+ body_rectangles, self._maidr_date_nums, self._maidr_original_data
151
+ )
152
+ return data
153
+
154
+ return []
155
+
156
+ def _extract_axes_data(self) -> dict:
157
+ """
158
+ Extract the plot's axes data including labels.
159
+
160
+ Returns
161
+ -------
162
+ dict
163
+ Dictionary containing x and y axis labels.
164
+ """
165
+ x_labels = self.ax.get_xlabel()
166
+ if not x_labels:
167
+ x_labels = self.extract_shared_xlabel(self.ax)
168
+ if not x_labels:
169
+ x_labels = "X"
170
+ return {MaidrKey.X: x_labels, MaidrKey.Y: self.ax.get_ylabel()}
171
+
172
+ def _get_selector(self) -> Union[str, Dict[str, str]]:
173
+ """Return selectors for highlighting candlestick elements.
174
+
175
+ - Modern path (collections present): return a dict with separate selectors for body, wickLow, wickHigh
176
+ - Legacy path: return a dict with body and shared wick selectors (no open/close keys)
177
+ """
178
+ # Modern path: build structured selectors using separate gids
179
+ if self._maidr_body_collection and self._maidr_wick_collection and self._maidr_body_gid and self._maidr_wick_gid:
180
+ # Determine candle count N
181
+ N = None
182
+ if self._maidr_original_data is not None:
183
+ try:
184
+ N = len(self._maidr_original_data)
185
+ except Exception:
186
+ N = None
187
+ if N is None and hasattr(self._maidr_wick_collection, "get_paths"):
188
+ try:
189
+ wick_paths = len(list(self._maidr_wick_collection.get_paths()))
190
+ if wick_paths % 2 == 0 and wick_paths > 0:
191
+ N = wick_paths // 2
192
+ except Exception:
193
+ pass
194
+ if N is None and hasattr(self._maidr_body_collection, "get_paths"):
195
+ try:
196
+ body_paths = len(list(self._maidr_body_collection.get_paths()))
197
+ if body_paths > 0:
198
+ N = body_paths
199
+ except Exception:
200
+ pass
201
+ if N is None:
202
+ raise ExtractionError(PlotType.CANDLESTICK, self._maidr_wick_collection)
203
+
204
+ selectors = {
205
+ "body": f"g[id='{self._maidr_body_gid}'] > path",
206
+ "wickLow": f"g[id='{self._maidr_wick_gid}'] > path:nth-child(-n+{N})",
207
+ "wickHigh": f"g[id='{self._maidr_wick_gid}'] > path:nth-child(n+{N + 1})",
208
+ }
209
+ return selectors
210
+
211
+ # Legacy path: build shared-id selectors; omit open/close
212
+ legacy_selectors = {}
213
+ if getattr(self, "_maidr_body_gid", None) or self._maidr_gid:
214
+ body_gid = getattr(self, "_maidr_body_gid", None) or self._maidr_gid
215
+ legacy_selectors["body"] = f"g[id='{body_gid}'] > path"
216
+ if getattr(self, "_maidr_wick_gid", None):
217
+ legacy_selectors["wick"] = f"g[id='{self._maidr_wick_gid}'] > path"
218
+ if legacy_selectors:
219
+ return legacy_selectors
220
+
221
+ # Fallback
222
+ return "g[maidr='true'] > path, g[maidr='true'] > rect"
223
+
224
+ def render(self) -> dict:
225
+ """Initialize the MAIDR schema dictionary with basic plot information."""
226
+ base_schema = super().render()
227
+ base_schema[MaidrKey.TITLE] = "Candlestick Chart"
228
+ base_schema[MaidrKey.AXES] = self._extract_axes_data()
229
+ base_schema[MaidrKey.DATA] = self._extract_plot_data()
230
+ # Include selector only if the plot supports highlighting.
231
+ if self._support_highlighting:
232
+ base_schema[MaidrKey.SELECTOR] = self._get_selector()
233
+ return base_schema
@@ -31,6 +31,10 @@ class MplfinanceBarPlot(
31
31
  self._custom_patches = kwargs.get("_maidr_patches", None)
32
32
  # Store date numbers for volume bars (from mplfinance)
33
33
  self._maidr_date_nums = kwargs.get("_maidr_date_nums", None)
34
+
35
+ # Store datetime converter if available
36
+ self._maidr_datetime_converter = kwargs.get("_maidr_datetime_converter", None)
37
+
34
38
  # Store custom title
35
39
 
36
40
  def set_title(self, title: str) -> None:
@@ -48,6 +52,13 @@ class MplfinanceBarPlot(
48
52
  )
49
53
  data = self._extract_bar_container_data(plot)
50
54
  levels = self.extract_level(self.ax)
55
+
56
+ # Ensure we have valid data and levels before processing
57
+ if data is None or levels is None:
58
+ if data is None:
59
+ raise ExtractionError(self.type, plot)
60
+ return []
61
+
51
62
  formatted_data = []
52
63
  combined_data = list(
53
64
  zip(levels, data)
@@ -78,7 +89,13 @@ class MplfinanceBarPlot(
78
89
  # Set elements for highlighting (use the patches directly)
79
90
  self._elements = sorted_patches
80
91
 
81
- # Use the utility class to extract data
92
+ # Use datetime converter for enhanced data extraction
93
+ if self._maidr_datetime_converter is not None:
94
+ data = self._maidr_datetime_converter.extract_volume_data(self.ax)
95
+ if data: # Only use if successful
96
+ return [{"x": item[0], "y": item[1]} for item in data]
97
+
98
+ # Fallback to existing logic
82
99
  return MplfinanceDataExtractor.extract_volume_data(
83
100
  sorted_patches, self._maidr_date_nums
84
101
  )
@@ -23,6 +23,9 @@ class MplfinanceLinePlot(MaidrPlot, LineExtractorMixin):
23
23
  def __init__(self, ax: Axes, **kwargs):
24
24
  super().__init__(ax, PlotType.LINE)
25
25
 
26
+ # Store datetime converter if available
27
+ self._maidr_datetime_converter = kwargs.get("_maidr_datetime_converter", None)
28
+
26
29
  def _get_selector(self) -> Union[str, List[str]]:
27
30
  """Return selectors for all lines that have data."""
28
31
  all_lines = self.ax.get_lines()
@@ -101,10 +104,15 @@ class MplfinanceLinePlot(MaidrPlot, LineExtractorMixin):
101
104
  if np.isnan(x) or np.isnan(y) or np.isinf(x) or np.isinf(y):
102
105
  continue
103
106
 
104
- # Handle x-value conversion - could be string (date) or numeric
105
- if isinstance(x, str):
106
- x_value = x # Keep string as-is (for dates)
107
+ # Use datetime converter for enhanced data extraction
108
+ datetime_converter = getattr(line, "_maidr_datetime_converter", None) or self._maidr_datetime_converter
109
+ if datetime_converter is not None:
110
+ # Convert x-coordinate (matplotlib index) to formatted datetime
111
+ x_value = datetime_converter.get_formatted_datetime(int(round(x)))
112
+ if x_value is None:
113
+ x_value = float(x) # Fallback to numeric
107
114
  else:
115
+ # Fallback to existing logic
108
116
  # Check if we have date numbers from mplfinance
109
117
  if date_nums is not None and i < len(date_nums):
110
118
  # Use the date number to convert to date string
@@ -2,6 +2,7 @@ import wrapt
2
2
  from typing import Any, Callable, Dict, Tuple
3
3
  from matplotlib.patches import Rectangle
4
4
  from mplfinance import original_flavor
5
+ import numpy as np
5
6
 
6
7
  from maidr.core.context_manager import ContextManager
7
8
  from maidr.core.enum.plot_type import PlotType
@@ -46,10 +47,35 @@ def candlestick(
46
47
  # Patch the plotting function.
47
48
  plot = wrapped(*args, **kwargs)
48
49
 
50
+ original_data = None
51
+ date_nums = None
52
+ if len(args) >= 2:
53
+ try:
54
+ quotes = args[1]
55
+ if quotes is not None:
56
+ arr = np.asarray(quotes)
57
+ if arr.ndim == 2 and arr.shape[1] >= 5 and arr.size > 0:
58
+ date_nums = arr[:, 0].tolist()
59
+ original_data = {
60
+ "Open": arr[:, 1].tolist(),
61
+ "High": arr[:, 2].tolist(),
62
+ "Low": arr[:, 3].tolist(),
63
+ "Close": arr[:, 4].tolist(),
64
+ }
65
+ except Exception:
66
+ pass
67
+
49
68
  axes = []
50
69
  for ax in plot:
51
70
  axes.append(FigureManager.get_axes(ax))
52
- FigureManager.create_maidr(axes, PlotType.CANDLESTICK)
71
+
72
+ extra_kwargs: Dict[str, Any] = {}
73
+ if original_data is not None:
74
+ extra_kwargs["_maidr_original_data"] = original_data
75
+ if date_nums is not None:
76
+ extra_kwargs["_maidr_date_nums"] = date_nums
77
+
78
+ FigureManager.create_maidr(axes, PlotType.CANDLESTICK, **extra_kwargs)
53
79
 
54
80
  return plot
55
81