solarwindpy 0.0.1.dev0__py3-none-any.whl → 0.1.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.

Potentially problematic release.


This version of solarwindpy might be problematic. Click here for more details.

Files changed (412) hide show
  1. plans/.velocity/metrics.json +96 -0
  2. plans/0-overview-template.md +268 -0
  3. plans/N-phase-template.md +106 -0
  4. plans/PLAN_AUDIT_SUMMARY.md +173 -0
  5. plans/TEMPLATE-USAGE-GUIDE.md +198 -0
  6. plans/__init__.py +1 -0
  7. plans/abandoned/compaction-agent-system/0-Overview.md +123 -0
  8. plans/abandoned/compaction-agent-system/agents-index-update-plan.md +109 -0
  9. plans/abandoned/compaction-agent-system/compacted_state.md +85 -0
  10. plans/abandoned/compaction-agent-system/implementation-plan.md +107 -0
  11. plans/abandoned/compaction-agent-system/system-validation-report.md +159 -0
  12. plans/abandoned/compaction-agent-system/usage-guide.md +210 -0
  13. plans/abandoned/hook-system-enhancement/0-Overview.md +214 -0
  14. plans/abandoned/hook-system-enhancement/1-Phase1-Core-Infrastructure.md +313 -0
  15. plans/abandoned/hook-system-enhancement/2-Phase2-Intelligent-Testing.md +385 -0
  16. plans/abandoned/hook-system-enhancement/3-Phase3-Physics-Validation.md +444 -0
  17. plans/abandoned/hook-system-enhancement/4-Phase4-Performance-Monitoring.md +458 -0
  18. plans/abandoned/hook-system-enhancement/5-Phase5-Developer-Experience.md +532 -0
  19. plans/abandoned/hook-system-enhancement/6-Implementation-Timeline.md +274 -0
  20. plans/abandoned/hook-system-enhancement/7-Risk-Management.md +376 -0
  21. plans/abandoned/hook-system-enhancement/8-Testing-Strategy.md +579 -0
  22. plans/abandoned/readthedocs-automation/0-Overview.md +247 -0
  23. plans/abandoned/readthedocs-automation/1-Emergency-Documentation-Fixes.md +270 -0
  24. plans/abandoned/readthedocs-automation/2-Template-System-Enhancement.md +811 -0
  25. plans/abandoned/readthedocs-automation/3-Quality-Audit-ReadTheDocs-Integration.md +844 -0
  26. plans/abandoned/readthedocs-automation/4-Plan-Consolidation-Cleanup.md +632 -0
  27. plans/abandoned/readthedocs-automation/9-Closeout.md +207 -0
  28. plans/abandoned/readthedocs-automation/ABANDONMENT_REASON.md +72 -0
  29. plans/cicd-architecture-redesign/0-Overview.md +193 -0
  30. plans/cicd-architecture-redesign/1-Workflow-Creation.md +103 -0
  31. plans/cicd-architecture-redesign/2-Version-Detection.md +123 -0
  32. plans/cicd-architecture-redesign/3-Deployment-Gates.md +169 -0
  33. plans/cicd-architecture-redesign/4-RC-Testing.md +194 -0
  34. plans/cicd-architecture-redesign/5-TestPyPI-Validation.md +264 -0
  35. plans/cicd-architecture-redesign/6-Production-Release.md +263 -0
  36. plans/cicd-architecture-redesign/7-Cleanup.md +243 -0
  37. plans/cicd-architecture-redesign/8-Documentation.md +285 -0
  38. plans/cicd-architecture-redesign/Closeout.md +225 -0
  39. plans/closeout-template.md +259 -0
  40. plans/completed/circular-import-audit/0-Overview.md +152 -0
  41. plans/completed/circular-import-audit/1-Static-Dependency-Analysis.md +62 -0
  42. plans/completed/circular-import-audit/2-Dynamic-Import-Testing.md +56 -0
  43. plans/completed/circular-import-audit/3-Performance-Impact-Assessment.md +56 -0
  44. plans/completed/circular-import-audit/4-Issue-Remediation.md +78 -0
  45. plans/completed/circular-import-audit/5-Preventive-Infrastructure.md +89 -0
  46. plans/completed/claude-settings-ecosystem-alignment/0-Overview.md +162 -0
  47. plans/completed/claude-settings-ecosystem-alignment/1-Security-Foundation.md +148 -0
  48. plans/completed/claude-settings-ecosystem-alignment/2-Hook-Integration.md +158 -0
  49. plans/completed/claude-settings-ecosystem-alignment/3-Agent-System-Integration.md +177 -0
  50. plans/completed/claude-settings-ecosystem-alignment/4-Enhanced-Workflow-Automation.md +159 -0
  51. plans/completed/claude-settings-ecosystem-alignment/5-Validation-Monitoring.md +181 -0
  52. plans/completed/claude-settings-ecosystem-alignment/compacted_session_state.md +290 -0
  53. plans/completed/combined_plan_with_checklist_documentation/1-Overview-and-Goals.md +51 -0
  54. plans/completed/combined_plan_with_checklist_documentation/2-Toolchain-and-Hosting.md +69 -0
  55. plans/completed/combined_plan_with_checklist_documentation/3-Repository-Structure.md +61 -0
  56. plans/completed/combined_plan_with_checklist_documentation/4-Configuration-and-Standards.md +70 -0
  57. plans/completed/combined_plan_with_checklist_documentation/5-Documentation-Content.md +62 -0
  58. plans/completed/combined_plan_with_checklist_documentation/6-CI-CD-and-Validation.md +58 -0
  59. plans/completed/combined_plan_with_checklist_documentation/7-Maintenance.md +55 -0
  60. plans/completed/combined_test_plan_with_checklist_fitfunctions/0-Overview.md +135 -0
  61. plans/completed/combined_test_plan_with_checklist_fitfunctions/1-Common-fixtures.md +59 -0
  62. plans/completed/combined_test_plan_with_checklist_fitfunctions/10-power_laws.md +56 -0
  63. plans/completed/combined_test_plan_with_checklist_fitfunctions/2-core.py-FitFunction.md +118 -0
  64. plans/completed/combined_test_plan_with_checklist_fitfunctions/3-gaussians.py-Gaussian-GaussianNormalized-GaussianLn.md +69 -0
  65. plans/completed/combined_test_plan_with_checklist_fitfunctions/4-trend_fits.py-TrendFit.md +99 -0
  66. plans/completed/combined_test_plan_with_checklist_fitfunctions/5-plots.py-FFPlot.md +98 -0
  67. plans/completed/combined_test_plan_with_checklist_fitfunctions/6-tex_info.py-TeXinfo.md +79 -0
  68. plans/completed/combined_test_plan_with_checklist_fitfunctions/7-Justification.md +49 -0
  69. plans/completed/combined_test_plan_with_checklist_fitfunctions/8-exponentials.md +64 -0
  70. plans/completed/combined_test_plan_with_checklist_fitfunctions/9-lines.md +58 -0
  71. plans/completed/combined_test_plan_with_checklist_plotting/0-Overview.md +142 -0
  72. plans/completed/combined_test_plan_with_checklist_plotting/1-base.py.md +90 -0
  73. plans/completed/combined_test_plan_with_checklist_plotting/10-labels-special.py.md +102 -0
  74. plans/completed/combined_test_plan_with_checklist_plotting/11-labels-chemistry.py.md +212 -0
  75. plans/completed/combined_test_plan_with_checklist_plotting/12-labels-composition.py.md +242 -0
  76. plans/completed/combined_test_plan_with_checklist_plotting/13-labels-datetime.py.md +247 -0
  77. plans/completed/combined_test_plan_with_checklist_plotting/14-labels-elemental_abundance.py.md +274 -0
  78. plans/completed/combined_test_plan_with_checklist_plotting/15-visual-validation.md +256 -0
  79. plans/completed/combined_test_plan_with_checklist_plotting/16-integration-testing.md +266 -0
  80. plans/completed/combined_test_plan_with_checklist_plotting/17-performance-benchmarks.md +267 -0
  81. plans/completed/combined_test_plan_with_checklist_plotting/18-Fixtures-and-Utilities.md +86 -0
  82. plans/completed/combined_test_plan_with_checklist_plotting/2-agg_plot.py.md +90 -0
  83. plans/completed/combined_test_plan_with_checklist_plotting/3-histograms.py.md +201 -0
  84. plans/completed/combined_test_plan_with_checklist_plotting/4-scatter.py.md +167 -0
  85. plans/completed/combined_test_plan_with_checklist_plotting/5-spiral.py.md +216 -0
  86. plans/completed/combined_test_plan_with_checklist_plotting/6-orbits.py.md +108 -0
  87. plans/completed/combined_test_plan_with_checklist_plotting/7-tools.py.md +86 -0
  88. plans/completed/combined_test_plan_with_checklist_plotting/8-select_data_from_figure.py.md +97 -0
  89. plans/completed/combined_test_plan_with_checklist_plotting/9-labels-base.py.md +88 -0
  90. plans/completed/combined_test_plan_with_checklist_solar_activity/.gitkeep +0 -0
  91. plans/completed/combined_test_plan_with_checklist_solar_activity/0-Overview.md +170 -0
  92. plans/completed/combined_test_plan_with_checklist_solar_activity/1-Package-Entry-Point-__init__.py.md +121 -0
  93. plans/completed/combined_test_plan_with_checklist_solar_activity/2-Core-Base-Classes-base.py.md +142 -0
  94. plans/completed/combined_test_plan_with_checklist_solar_activity/3-Plotting-Helpers-plots.py.md +123 -0
  95. plans/completed/combined_test_plan_with_checklist_solar_activity/4-LISIRD-Sub-package.md +119 -0
  96. plans/completed/combined_test_plan_with_checklist_solar_activity/5-Extrema-Calculator.md +103 -0
  97. plans/completed/combined_test_plan_with_checklist_solar_activity/6-Sunspot-Number-Sub-package.md +163 -0
  98. plans/completed/combined_test_plan_with_checklist_solar_activity/7-Sunspot-Number-Init.py.md +217 -0
  99. plans/completed/combined_test_plan_with_checklist_solar_activity/compacted_state.md +52 -0
  100. plans/completed/compaction-agent-modernization/0-Overview.md +156 -0
  101. plans/completed/compaction-agent-modernization/1-Architecture-Audit-Gap-Analysis.md +132 -0
  102. plans/completed/compaction-agent-modernization/2-Token-Baseline-Recalibration.md +153 -0
  103. plans/completed/compaction-agent-modernization/3-Agent-Reference-Updates.md +184 -0
  104. plans/completed/compaction-agent-modernization/4-Compression-Algorithm-Modernization.md +238 -0
  105. plans/completed/compaction-agent-modernization/5-Workflow-Integration-Streamlining.md +252 -0
  106. plans/completed/compaction-agent-modernization/6-Template-Structure-Optimization.md +240 -0
  107. plans/completed/compaction-agent-modernization/7-Integration-Testing-Validation.md +292 -0
  108. plans/completed/compaction-hook-enhancement/0-Overview.md +150 -0
  109. plans/completed/compaction-hook-enhancement/1-Token-Estimation-Enhancement.md +179 -0
  110. plans/completed/compaction-hook-enhancement/2-Compression-Intelligence.md +294 -0
  111. plans/completed/compaction-hook-enhancement/3-Git-Integration-Metadata.md +310 -0
  112. plans/completed/compaction-hook-enhancement/4-Session-Continuity-Features.md +358 -0
  113. plans/completed/compaction-hook-enhancement/5-Testing-Strategy.md +404 -0
  114. plans/completed/compaction-hook-enhancement/6-Integration-Roadmap.md +319 -0
  115. plans/completed/compaction-hook-enhancement/compacted_state.md +142 -0
  116. plans/completed/docstring-audit-enhancement/0-Overview.md +274 -0
  117. plans/completed/docstring-audit-enhancement/1-Infrastructure-Setup-and-Validation-Tools.md +206 -0
  118. plans/completed/docstring-audit-enhancement/2-Core-Physics-Modules-Enhancement.md +237 -0
  119. plans/completed/docstring-audit-enhancement/3-Fitfunctions-Mathematical-Modules-Enhancement.md +188 -0
  120. plans/completed/docstring-audit-enhancement/4-Plotting-Visualization-Modules-Enhancement.md +243 -0
  121. plans/completed/docstring-audit-enhancement/5-Specialized-Modules-Enhancement.md +216 -0
  122. plans/completed/docstring-audit-enhancement/6-Validation-and-Integration.md +216 -0
  123. plans/completed/fitfunctions-testing-implementation/0-Overview.md +130 -0
  124. plans/completed/fitfunctions-testing-implementation/1-Test-Infrastructure-Setup.md +79 -0
  125. plans/completed/fitfunctions-testing-implementation/2-Common-Fixtures-Test-Utilities.md +104 -0
  126. plans/completed/fitfunctions-testing-implementation/3-Core-FitFunction-Testing.md +168 -0
  127. plans/completed/fitfunctions-testing-implementation/4-Specialized-Function-Classes.md +210 -0
  128. plans/completed/fitfunctions-testing-implementation/5-Advanced-Classes-Testing.md +214 -0
  129. plans/completed/fitfunctions-testing-implementation/6-Plotting-Integration-Testing.md +231 -0
  130. plans/completed/fitfunctions-testing-implementation/7-Extended-Coverage-BONUS.md +184 -0
  131. plans/completed/numpy-docstring-conversion-plan/numpy-docstring-conversion-plan.md +118 -0
  132. plans/completed/pr-review-remediation/0-Overview.md +138 -0
  133. plans/completed/pr-review-remediation/1-Critical-Safety-Improvements.md +179 -0
  134. plans/completed/pr-review-remediation/2-Smart-Timeouts-Validation.md +399 -0
  135. plans/completed/pr-review-remediation/3-Enhanced-GitHub-Integration.md +258 -0
  136. plans/completed/pr-review-remediation/compacted_state.md +66 -0
  137. plans/completed/python-310-migration/0-Overview.md +390 -0
  138. plans/completed/python-310-migration/1-Planning-Setup.md +164 -0
  139. plans/completed/python-310-migration/2-Implementation.md +256 -0
  140. plans/completed/python-310-migration/3-Testing-Validation.md +335 -0
  141. plans/completed/python-310-migration/4-Documentation-Release.md +274 -0
  142. plans/completed/python-310-migration/5-Closeout.md +252 -0
  143. plans/completed/requirements-management-consolidation/0-Overview.md +118 -0
  144. plans/completed/requirements-management-consolidation/1-Documentation-Validation-Environment-Setup.md +116 -0
  145. plans/completed/requirements-management-consolidation/2-Requirements-Consolidation.md +161 -0
  146. plans/completed/requirements-management-consolidation/3-Workflow-Automation-Final-Integration.md +196 -0
  147. plans/completed/single-ecosystem-plan-implementation/0-Overview.md +83 -0
  148. plans/completed/single-ecosystem-plan-implementation/1-Plan-Preservation-Session-Management.md +38 -0
  149. plans/completed/single-ecosystem-plan-implementation/2-File-Structure-Optimization.md +43 -0
  150. plans/completed/single-ecosystem-plan-implementation/3-Plan-Migration-Archive-Setup.md +82 -0
  151. plans/completed/single-ecosystem-plan-implementation/4-Agent-System-Transformation.md +108 -0
  152. plans/completed/single-ecosystem-plan-implementation/5-Template-System-Enhancement.md +131 -0
  153. plans/completed/single-ecosystem-plan-implementation/6-Final-Validation-Testing.md +120 -0
  154. plans/completed/test-directory-consolidation/0-Overview.md +51 -0
  155. plans/completed/test-directory-consolidation/1-Structure-Preparation.md +82 -0
  156. plans/completed/test-directory-consolidation/2-File-Migration.md +100 -0
  157. plans/completed/test-directory-consolidation/3-Import-Transformation.md +117 -0
  158. plans/completed/test-directory-consolidation/4-Configuration-Consolidation.md +140 -0
  159. plans/completed/test-directory-consolidation/5-Validation.md +152 -0
  160. plans/completed/test-directory-consolidation/6-Cleanup.md +156 -0
  161. plans/completed/test-planning-agents-architecture/0-Overview.md +79 -0
  162. plans/completed/test-planning-agents-architecture/1-Branch-Isolation-Testing.md +49 -0
  163. plans/completed/test-planning-agents-architecture/2-Cross-Branch-Coordination.md +51 -0
  164. plans/completed/test-planning-agents-architecture/3-Merge-Workflow-Testing.md +48 -0
  165. plans/deployment-semver-pypi-rtd/0-Overview.md +463 -0
  166. plans/deployment-semver-pypi-rtd/1-Semantic-Versioning-Foundation.md +136 -0
  167. plans/deployment-semver-pypi-rtd/2-PyPI-Deployment-Infrastructure.md +168 -0
  168. plans/deployment-semver-pypi-rtd/3-Release-Automation.md +214 -0
  169. plans/deployment-semver-pypi-rtd/4-Plan-Closeout.md +543 -0
  170. plans/deployment-semver-pypi-rtd/compacted_session_state.md +172 -0
  171. plans/deployment-semver-pypi-rtd/compacted_state.md +131 -0
  172. plans/documentation-code-audit/0-Overview.md +393 -0
  173. plans/documentation-code-audit/1-Discovery-Inventory.md +183 -0
  174. plans/documentation-code-audit/2-Execution-Environment-Setup.md +263 -0
  175. plans/documentation-code-audit/3-Systematic-Validation.md +322 -0
  176. plans/documentation-code-audit/4-Code-Example-Remediation.md +358 -0
  177. plans/documentation-code-audit/5-Physics-MultiIndex-Compliance.md +464 -0
  178. plans/documentation-code-audit/6-Doctest-Integration.md +523 -0
  179. plans/documentation-code-audit/7-Reporting-Documentation.md +498 -0
  180. plans/documentation-code-audit/8-Closeout.md +456 -0
  181. plans/documentation-rebuild-session/compacted_state.md +109 -0
  182. plans/documentation-rendering-fixes/0-Overview.md +104 -0
  183. plans/documentation-rendering-fixes/1-Sphinx-Build-Diagnostics-Warning-Audit.md +101 -0
  184. plans/documentation-rendering-fixes/2-Configuration-Infrastructure-Fixes.md +113 -0
  185. plans/documentation-rendering-fixes/3-Docstring-Syntax-Audit-Repair.md +131 -0
  186. plans/documentation-rendering-fixes/4-HTML-Page-Rendering-Verification.md +113 -0
  187. plans/documentation-rendering-fixes/5-Advanced-Documentation-Quality-Assurance.md +119 -0
  188. plans/documentation-rendering-fixes/6-Documentation-Build-Optimization-Testing.md +129 -0
  189. plans/documentation-rendering-fixes/compacted_state.md +132 -0
  190. plans/documentation-template-fix/0-Overview.md +197 -0
  191. plans/documentation-template-fix/1-Template-System-Analysis.md +269 -0
  192. plans/documentation-template-fix/2-Template-Modification.md +609 -0
  193. plans/documentation-template-fix/3-Build-System-Integration.md +766 -0
  194. plans/documentation-template-fix/4-Testing-Validation.md +1399 -0
  195. plans/documentation-template-fix/5-Documentation-Training.md +602 -0
  196. plans/documentation-workflow-fix/0-Overview.md +222 -0
  197. plans/documentation-workflow-fix/1-Immediate-Fixes.md +238 -0
  198. plans/documentation-workflow-fix/2-Configuration-Setup.md +298 -0
  199. plans/documentation-workflow-fix/3-Pre-commit-Integration.md +382 -0
  200. plans/documentation-workflow-fix/4-Workflow-Improvements.md +446 -0
  201. plans/documentation-workflow-fix/5-Documentation-and-Training.md +527 -0
  202. plans/duplicate-object-warnings-fix-plan.md +130 -0
  203. plans/github-issues-migration/0-Overview.md +510 -0
  204. plans/github-issues-migration/1-Foundation-Label-System.md +180 -0
  205. plans/github-issues-migration/2-Migration-Tool-Rewrite.md +235 -0
  206. plans/github-issues-migration/3-CLI-Integration-Automation.md +169 -0
  207. plans/github-issues-migration/4-Validated-Migration.md +252 -0
  208. plans/github-issues-migration/5-Documentation-Training.md +171 -0
  209. plans/github-issues-migration/6-Closeout.md +179 -0
  210. plans/github-workflows-repair/repair-plan.md +299 -0
  211. plans/issues_from_plans.py +342 -0
  212. plans/pr-270-doc-validation-fixes/0-Overview.md +354 -0
  213. plans/pr-270-doc-validation-fixes/1-Critical-PR-Fixes.md +117 -0
  214. plans/pr-270-doc-validation-fixes/2-Framework-Right-Sizing.md +129 -0
  215. plans/pr-270-doc-validation-fixes/3-Sustainable-Documentation.md +126 -0
  216. plans/pr-270-doc-validation-fixes/4-Closeout-Migration.md +143 -0
  217. plans/pr-270-doc-validation-fixes/PLAN_COMPLETED.md +149 -0
  218. plans/python-310-migration/0-Overview.md +390 -0
  219. plans/python-310-migration/1-Planning-Setup.md +164 -0
  220. plans/python-310-migration/2-Implementation.md +256 -0
  221. plans/python-310-migration/3-Testing-Validation.md +335 -0
  222. plans/python-310-migration/4-Documentation-Release.md +274 -0
  223. plans/python-310-migration/5-Closeout.md +252 -0
  224. plans/readthedocs-simplified/0-Overview.md +243 -0
  225. plans/readthedocs-simplified/1-Immediate-Fixes.md +216 -0
  226. plans/readthedocs-simplified/2-Template-Simplification.md +278 -0
  227. plans/readthedocs-simplified/3-ReadTheDocs-Setup.md +298 -0
  228. plans/readthedocs-simplified/4-Testing-Validation.md +328 -0
  229. plans/readthedocs-simplified/5-Closeout.md +231 -0
  230. plans/readthedocs-simplified/compacted_state.md +127 -0
  231. plans/session-compaction-2025-08-12/compacted_state.md +114 -0
  232. plans/session-compaction-2025-08-13/compacted_state.md +145 -0
  233. plans/session-continuity-protocol/0-Overview.md +35 -0
  234. plans/session-continuity-protocol/1-Core-Principles-Framework.md +40 -0
  235. plans/session-continuity-protocol/2-Pre-Session-Validation-System.md +79 -0
  236. plans/session-continuity-protocol/3-Context-Switching-Prevention.md +87 -0
  237. plans/session-continuity-protocol/4-Progress-Tracking-Recovery.md +100 -0
  238. plans/sphinx-warnings-analysis.md +222 -0
  239. plans/systemprompt-optimization/0-Overview.md +447 -0
  240. plans/systemprompt-optimization/1-Deploy-SystemPrompt.md +114 -0
  241. plans/systemprompt-optimization/2-Documentation-Alignment.md +198 -0
  242. plans/systemprompt-optimization/3-Monitoring-Infrastructure.md +396 -0
  243. plans/systemprompt-optimization/4-Implementation-Script.md +450 -0
  244. plans/systemprompt-optimization/9-Closeout.md +165 -0
  245. plans/systemprompt-optimization/compacted_state.md +143 -0
  246. plans/template-value-propositions/0-Overview.md +357 -0
  247. plans/template-value-propositions/1-Value-Proposition-Framework-Design.md +144 -0
  248. plans/template-value-propositions/2-Plan-Template-Enhancement.md +178 -0
  249. plans/template-value-propositions/3-Value-Generator-Hook-Implementation.md +291 -0
  250. plans/template-value-propositions/4-Value-Validator-Hook-Implementation.md +274 -0
  251. plans/template-value-propositions/5-Documentation-Agent-Updates.md +219 -0
  252. plans/template-value-propositions/6-Integration-Testing-Validation.md +247 -0
  253. plans/tests-audit/0-Overview.md +410 -0
  254. plans/tests-audit/1-Discovery-Inventory.md +170 -0
  255. plans/tests-audit/2-Physics-Validation-Audit.md +195 -0
  256. plans/tests-audit/3-Architecture-Compliance.md +195 -0
  257. plans/tests-audit/4-Numerical-Stability-Analysis.md +203 -0
  258. plans/tests-audit/5-Documentation-Enhancement.md +220 -0
  259. plans/tests-audit/6-Audit-Deliverables.md +220 -0
  260. plans/tests-audit/7-Closeout.md +252 -0
  261. plans/tests-audit/artifacts/ARCHITECTURE_COMPLIANCE_REPORT.md +315 -0
  262. plans/tests-audit/artifacts/ARCHITECTURE_RECOMMENDATIONS.md +943 -0
  263. plans/tests-audit/artifacts/COMPREHENSIVE_AUDIT_REPORT.md +356 -0
  264. plans/tests-audit/artifacts/CONTRIBUTING_ENHANCED_TEMPLATE.md +419 -0
  265. plans/tests-audit/artifacts/COVERAGE_GAP_ANALYSIS.md +152 -0
  266. plans/tests-audit/artifacts/DOCUMENTATION_ENHANCEMENT_REPORT.md +502 -0
  267. plans/tests-audit/artifacts/EXECUTIVE_AUDIT_SUMMARY.md +129 -0
  268. plans/tests-audit/artifacts/IMPLEMENTATION_ROADMAP.md +647 -0
  269. plans/tests-audit/artifacts/NUMERICAL_RECOMMENDATIONS.md +739 -0
  270. plans/tests-audit/artifacts/NUMERICAL_STABILITY_GUIDE_TEMPLATE.rst +451 -0
  271. plans/tests-audit/artifacts/NUMERICAL_STABILITY_REPORT.md +301 -0
  272. plans/tests-audit/artifacts/PHASE_3_SUMMARY.md +280 -0
  273. plans/tests-audit/artifacts/PHASE_4_SUMMARY.md +229 -0
  274. plans/tests-audit/artifacts/PHASE_5_SUMMARY.md +292 -0
  275. plans/tests-audit/artifacts/PHASE_6_CLOSEOUT.md +278 -0
  276. plans/tests-audit/artifacts/PHYSICS_GUIDE_TEMPLATE.rst +268 -0
  277. plans/tests-audit/artifacts/PHYSICS_VALIDATION_REPORT.md +235 -0
  278. plans/tests-audit/artifacts/TECHNICAL_DELIVERABLES_PACKAGE.md +2502 -0
  279. plans/tests-audit/artifacts/TEST_INVENTORY.csv +1204 -0
  280. plans/tests-audit/artifacts/TEST_INVENTORY.md +135 -0
  281. plans/tests-audit/artifacts/test_discovery_analysis.py +231 -0
  282. plans/tests-audit/artifacts/test_parser.py +395 -0
  283. solarwindpy/README.md +3 -0
  284. solarwindpy/Untitled.ipynb +54 -0
  285. solarwindpy/__init__.py +74 -0
  286. solarwindpy/core/__init__.py +23 -0
  287. solarwindpy/core/alfvenic_turbulence.py +804 -0
  288. solarwindpy/core/base.py +267 -0
  289. solarwindpy/core/ions.py +309 -0
  290. solarwindpy/core/plasma.py +2133 -0
  291. solarwindpy/core/spacecraft.py +256 -0
  292. solarwindpy/core/tensor.py +90 -0
  293. solarwindpy/core/units_constants.py +199 -0
  294. solarwindpy/core/vector.py +328 -0
  295. solarwindpy/fitfunctions/__init__.py +20 -0
  296. solarwindpy/fitfunctions/core.py +734 -0
  297. solarwindpy/fitfunctions/exponentials.py +188 -0
  298. solarwindpy/fitfunctions/gaussians.py +264 -0
  299. solarwindpy/fitfunctions/lines.py +116 -0
  300. solarwindpy/fitfunctions/moyal.py +71 -0
  301. solarwindpy/fitfunctions/plots.py +751 -0
  302. solarwindpy/fitfunctions/power_laws.py +209 -0
  303. solarwindpy/fitfunctions/tex_info.py +568 -0
  304. solarwindpy/fitfunctions/trend_fits.py +482 -0
  305. solarwindpy/instabilities/__init__.py +16 -0
  306. solarwindpy/instabilities/beta_ani.py +82 -0
  307. solarwindpy/instabilities/verscharen2016.py +631 -0
  308. solarwindpy/plotting/__init__.py +33 -0
  309. solarwindpy/plotting/agg_plot.py +489 -0
  310. solarwindpy/plotting/base.py +465 -0
  311. solarwindpy/plotting/hist1d.py +405 -0
  312. solarwindpy/plotting/hist2d.py +1035 -0
  313. solarwindpy/plotting/histograms.py +1845 -0
  314. solarwindpy/plotting/labels/__init__.py +104 -0
  315. solarwindpy/plotting/labels/base.py +686 -0
  316. solarwindpy/plotting/labels/chemistry.py +19 -0
  317. solarwindpy/plotting/labels/composition.py +100 -0
  318. solarwindpy/plotting/labels/datetime.py +235 -0
  319. solarwindpy/plotting/labels/elemental_abundance.py +73 -0
  320. solarwindpy/plotting/labels/special.py +794 -0
  321. solarwindpy/plotting/orbits.py +515 -0
  322. solarwindpy/plotting/scatter.py +99 -0
  323. solarwindpy/plotting/select_data_from_figure.py +329 -0
  324. solarwindpy/plotting/spiral.py +980 -0
  325. solarwindpy/plotting/tools.py +434 -0
  326. solarwindpy/scripts/__init__.py +1 -0
  327. solarwindpy/scripts/logs/.gitignore +1 -0
  328. solarwindpy/solar_activity/__init__.py +53 -0
  329. solarwindpy/solar_activity/base.py +605 -0
  330. solarwindpy/solar_activity/lisird/__init__.py +3 -0
  331. solarwindpy/solar_activity/lisird/extrema_calculator.py +394 -0
  332. solarwindpy/solar_activity/lisird/lisird.py +319 -0
  333. solarwindpy/solar_activity/plots.py +116 -0
  334. solarwindpy/solar_activity/sunspot_number/.DS_Store +0 -0
  335. solarwindpy/solar_activity/sunspot_number/__init__.py +3 -0
  336. solarwindpy/solar_activity/sunspot_number/sidc.py +556 -0
  337. solarwindpy/solar_activity/sunspot_number/ssn_extrema.csv +72 -0
  338. solarwindpy/solar_activity/sunspot_number/ssn_extrema.csv.silso +72 -0
  339. solarwindpy/tools/__init__.py +162 -0
  340. solarwindpy-0.1.1.dist-info/METADATA +181 -0
  341. solarwindpy-0.1.1.dist-info/RECORD +409 -0
  342. {solarwindpy-0.0.1.dev0.dist-info → solarwindpy-0.1.1.dist-info}/WHEEL +1 -1
  343. solarwindpy-0.1.1.dist-info/licenses/LICENSE.rst +32 -0
  344. solarwindpy-0.1.1.dist-info/top_level.txt +3 -0
  345. tests/__init__.py +1 -0
  346. tests/conftest.py +10 -0
  347. tests/core/__init__.py +1 -0
  348. tests/core/test_alfvenic_turbulence.py +544 -0
  349. tests/core/test_base.py +112 -0
  350. tests/core/test_base_head_tail.py +29 -0
  351. tests/core/test_base_mi_tuples.py +11 -0
  352. tests/core/test_core_verify_datetimeindex.py +32 -0
  353. tests/core/test_ions.py +325 -0
  354. tests/core/test_plasma.py +2581 -0
  355. tests/core/test_plasma_io.py +12 -0
  356. tests/core/test_quantities.py +507 -0
  357. tests/core/test_spacecraft.py +210 -0
  358. tests/core/test_units_constants.py +22 -0
  359. tests/data/epoch.csv +4 -0
  360. tests/data/plasma.csv +4 -0
  361. tests/data/spacecraft.csv +4 -0
  362. tests/fitfunctions/conftest.py +60 -0
  363. tests/fitfunctions/test_core.py +193 -0
  364. tests/fitfunctions/test_exponentials.py +342 -0
  365. tests/fitfunctions/test_gaussians.py +142 -0
  366. tests/fitfunctions/test_lines.py +349 -0
  367. tests/fitfunctions/test_moyal.py +258 -0
  368. tests/fitfunctions/test_plots.py +258 -0
  369. tests/fitfunctions/test_power_laws.py +365 -0
  370. tests/fitfunctions/test_tex_info.py +183 -0
  371. tests/fitfunctions/test_trend_fit_properties.py +31 -0
  372. tests/fitfunctions/test_trend_fits.py +244 -0
  373. tests/plotting/__init__.py +1 -0
  374. tests/plotting/labels/__init__.py +1 -0
  375. tests/plotting/labels/test_chemistry.py +243 -0
  376. tests/plotting/labels/test_composition.py +345 -0
  377. tests/plotting/labels/test_datetime.py +445 -0
  378. tests/plotting/labels/test_elemental_abundance.py +366 -0
  379. tests/plotting/labels/test_init.py +66 -0
  380. tests/plotting/labels/test_labels_base.py +347 -0
  381. tests/plotting/labels/test_special.py +550 -0
  382. tests/plotting/test_agg_plot.py +602 -0
  383. tests/plotting/test_base.py +752 -0
  384. tests/plotting/test_fixtures_utilities.py +775 -0
  385. tests/plotting/test_histograms.py +546 -0
  386. tests/plotting/test_integration.py +675 -0
  387. tests/plotting/test_orbits.py +435 -0
  388. tests/plotting/test_performance.py +708 -0
  389. tests/plotting/test_scatter.py +752 -0
  390. tests/plotting/test_select_data_from_figure.py +1209 -0
  391. tests/plotting/test_spiral.py +573 -0
  392. tests/plotting/test_tools.py +607 -0
  393. tests/plotting/test_visual_validation.py +465 -0
  394. tests/solar_activity/__init__.py +1 -0
  395. tests/solar_activity/lisird/__init__.py +1 -0
  396. tests/solar_activity/lisird/test_extrema_calculator.py +593 -0
  397. tests/solar_activity/lisird/test_lisird_id.py +187 -0
  398. tests/solar_activity/sunspot_number/__init__.py +1 -0
  399. tests/solar_activity/sunspot_number/test_init.py +399 -0
  400. tests/solar_activity/sunspot_number/test_sidc.py +465 -0
  401. tests/solar_activity/sunspot_number/test_sidc_id.py +223 -0
  402. tests/solar_activity/sunspot_number/test_sidc_loader.py +275 -0
  403. tests/solar_activity/sunspot_number/test_ssn_extrema.py +406 -0
  404. tests/solar_activity/test_base.py +656 -0
  405. tests/solar_activity/test_init.py +396 -0
  406. tests/solar_activity/test_plots.py +371 -0
  407. tests/test_circular_imports.py +408 -0
  408. tests/test_issue_titles.py +25 -0
  409. tests/test_statusline.py +298 -0
  410. solarwindpy-0.0.1.dev0.dist-info/METADATA +0 -14
  411. solarwindpy-0.0.1.dev0.dist-info/RECORD +0 -4
  412. solarwindpy-0.0.1.dev0.dist-info/top_level.txt +0 -1
@@ -0,0 +1,752 @@
1
+ #!/usr/bin/env python
2
+ """Tests for solarwindpy.plotting.scatter module.
3
+
4
+ This module provides comprehensive test coverage for the Scatter class used for creating
5
+ scatter plots with optional color mapping functionality.
6
+ """
7
+
8
+ import pytest
9
+ import logging
10
+ import pandas as pd
11
+ import numpy as np
12
+ from pathlib import Path
13
+ from unittest.mock import patch, MagicMock, call
14
+
15
+ import matplotlib
16
+
17
+ matplotlib.use("Agg") # Use non-interactive backend
18
+ from matplotlib import pyplot as plt
19
+ from matplotlib.collections import PathCollection
20
+
21
+ import solarwindpy.plotting.scatter as scatter_module
22
+ from solarwindpy.plotting.scatter import Scatter
23
+ from solarwindpy.plotting.base import PlotWithZdata, CbarMaker, AxesLabels, LogAxes
24
+
25
+
26
+ class TestScatterModuleStructure:
27
+ """Test scatter module structure and imports."""
28
+
29
+ def test_module_imports(self):
30
+ """Test that all required imports are accessible."""
31
+ # Test basic imports
32
+ assert hasattr(scatter_module, "base")
33
+ assert hasattr(scatter_module, "plt")
34
+ assert hasattr(scatter_module, "Scatter")
35
+
36
+ def test_scatter_class_available(self):
37
+ """Test that Scatter class is accessible from module."""
38
+ assert hasattr(scatter_module, "Scatter")
39
+ assert callable(scatter_module.Scatter)
40
+
41
+ def test_scatter_inheritance(self):
42
+ """Test that Scatter inherits from correct base classes."""
43
+ assert issubclass(Scatter, PlotWithZdata)
44
+ assert issubclass(Scatter, CbarMaker)
45
+
46
+ # Test MRO (Method Resolution Order)
47
+ mro = Scatter.__mro__
48
+ assert PlotWithZdata in mro
49
+ assert CbarMaker in mro
50
+
51
+
52
+ class TestScatterInitialization:
53
+ """Test Scatter class initialization."""
54
+
55
+ def setup_method(self):
56
+ """Set up test data for each test method."""
57
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
58
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
59
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
60
+
61
+ def test_basic_initialization(self):
62
+ """Test basic initialization with x, y data only."""
63
+ scatter = Scatter(self.x_data, self.y_data)
64
+
65
+ assert scatter is not None
66
+ assert hasattr(scatter, "data")
67
+ assert hasattr(scatter, "_labels")
68
+ assert hasattr(scatter, "_log")
69
+ assert hasattr(scatter, "clip")
70
+
71
+ def test_initialization_with_z_data(self):
72
+ """Test initialization with z data for color mapping."""
73
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
74
+
75
+ assert scatter is not None
76
+ assert "z" in scatter.data.columns
77
+ assert scatter._labels.z == "z"
78
+
79
+ def test_initialization_with_clip_data_true(self):
80
+ """Test initialization with clip_data=True."""
81
+ scatter = Scatter(self.x_data, self.y_data, clip_data=True)
82
+
83
+ assert scatter.clip is True
84
+
85
+ def test_initialization_with_clip_data_false(self):
86
+ """Test initialization with clip_data=False."""
87
+ scatter = Scatter(self.x_data, self.y_data, clip_data=False)
88
+
89
+ assert scatter.clip is False
90
+
91
+ def test_labels_initialization(self):
92
+ """Test that labels are properly initialized."""
93
+ # Without z data
94
+ scatter = Scatter(self.x_data, self.y_data)
95
+ assert scatter._labels.x == "x"
96
+ assert scatter._labels.y == "y"
97
+ assert scatter._labels.z is None
98
+
99
+ # With z data
100
+ scatter_z = Scatter(self.x_data, self.y_data, self.z_data)
101
+ assert scatter_z._labels.x == "x"
102
+ assert scatter_z._labels.y == "y"
103
+ assert scatter_z._labels.z == "z"
104
+
105
+ def test_log_initialization(self):
106
+ """Test that log axes are properly initialized."""
107
+ scatter = Scatter(self.x_data, self.y_data)
108
+
109
+ assert hasattr(scatter, "_log")
110
+ assert scatter._log.x is False
111
+ assert scatter._log.y is False
112
+
113
+ def test_path_initialization(self):
114
+ """Test that path is initialized to None."""
115
+ scatter = Scatter(self.x_data, self.y_data)
116
+
117
+ assert hasattr(scatter, "_path")
118
+
119
+ def test_invalid_input_types(self):
120
+ """Test behavior with non-pandas Series inputs."""
121
+ # Lists are actually converted to Series internally
122
+ scatter = Scatter([1, 2, 3], self.y_data[:3])
123
+ assert len(scatter.data) == 3
124
+
125
+ # Both as lists
126
+ scatter2 = Scatter([1, 2, 3], [4, 5, 6])
127
+ assert len(scatter2.data) == 3
128
+
129
+ def test_empty_data_handling(self):
130
+ """Test behavior with empty pandas Series."""
131
+ empty_x = pd.Series([], dtype=float)
132
+ empty_y = pd.Series([], dtype=float)
133
+
134
+ with pytest.raises(ValueError, match="exclusively NaNs"):
135
+ Scatter(empty_x, empty_y)
136
+
137
+ def test_mismatched_data_lengths(self):
138
+ """Test error handling for different length x, y, z."""
139
+ short_data = pd.Series([1, 2])
140
+
141
+ # This should work - pandas will align indices
142
+ scatter = Scatter(short_data, self.y_data)
143
+ assert len(scatter.data) == 2 # Should keep only aligned data
144
+
145
+ def test_nan_data_handling(self):
146
+ """Test handling of NaN values in data."""
147
+ x_with_nan = pd.Series([1, 2, np.nan, 4, 5])
148
+ y_with_nan = pd.Series([2, np.nan, 6, 8, 10])
149
+
150
+ scatter = Scatter(x_with_nan, y_with_nan)
151
+
152
+ # NaN rows should be dropped
153
+ assert not scatter.data.isnull().any().any()
154
+ assert len(scatter.data) < 5
155
+
156
+
157
+ class TestScatterDataManagement:
158
+ """Test data management methods and properties."""
159
+
160
+ def setup_method(self):
161
+ """Set up test data for each test method."""
162
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
163
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
164
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
165
+
166
+ def test_set_data_method(self):
167
+ """Test the set_data method."""
168
+ scatter = Scatter(self.x_data, self.y_data)
169
+
170
+ # Test basic data assignment
171
+ assert "x" in scatter.data.columns
172
+ assert "y" in scatter.data.columns
173
+ assert "z" in scatter.data.columns # Should be filled with 1s
174
+
175
+ def test_set_data_with_z(self):
176
+ """Test set_data with z data."""
177
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
178
+
179
+ assert "z" in scatter.data.columns
180
+ assert not (scatter.data["z"] == 1).all() # Should not be all 1s
181
+
182
+ def test_data_property_access(self):
183
+ """Test access to stored data via properties."""
184
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
185
+
186
+ data = scatter.data
187
+ assert isinstance(data, pd.DataFrame)
188
+ assert "x" in data.columns
189
+ assert "y" in data.columns
190
+ assert "z" in data.columns
191
+
192
+ def test_data_integrity(self):
193
+ """Test that data remains unchanged after storage."""
194
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
195
+
196
+ # Check that original values are preserved
197
+ np.testing.assert_array_equal(scatter.data["x"].values, self.x_data.values)
198
+ np.testing.assert_array_equal(scatter.data["y"].values, self.y_data.values)
199
+ np.testing.assert_array_equal(scatter.data["z"].values, self.z_data.values)
200
+
201
+ def test_clip_property(self):
202
+ """Test the clip property."""
203
+ scatter_no_clip = Scatter(self.x_data, self.y_data, clip_data=False)
204
+ scatter_with_clip = Scatter(self.x_data, self.y_data, clip_data=True)
205
+
206
+ assert scatter_no_clip.clip is False
207
+ assert scatter_with_clip.clip is True
208
+
209
+
210
+ class TestScatterLabelsAndAxes:
211
+ """Test label and axis configuration."""
212
+
213
+ def setup_method(self):
214
+ """Set up test data for each test method."""
215
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
216
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
217
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
218
+
219
+ def test_default_labels(self):
220
+ """Test that default labels are set correctly."""
221
+ scatter = Scatter(self.x_data, self.y_data)
222
+
223
+ assert scatter._labels.x == "x"
224
+ assert scatter._labels.y == "y"
225
+ assert scatter._labels.z is None
226
+
227
+ def test_labels_with_z_data(self):
228
+ """Test labels when z data is provided."""
229
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
230
+
231
+ assert scatter._labels.x == "x"
232
+ assert scatter._labels.y == "y"
233
+ assert scatter._labels.z == "z"
234
+
235
+ def test_label_customization(self):
236
+ """Test updating axis labels via namedtuple replacement."""
237
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
238
+
239
+ # AxesLabels is a namedtuple, so we need to replace it entirely
240
+ original_labels = scatter._labels
241
+ new_labels = scatter._labels._replace(x="Custom X", y="Custom Y", z="Custom Z")
242
+ scatter._labels = new_labels
243
+
244
+ assert scatter._labels.x == "Custom X"
245
+ assert scatter._labels.y == "Custom Y"
246
+ assert scatter._labels.z == "Custom Z"
247
+
248
+ def test_label_persistence(self):
249
+ """Test that labels maintain values across operations."""
250
+ scatter = Scatter(self.x_data, self.y_data)
251
+
252
+ original_x = scatter._labels.x
253
+ original_y = scatter._labels.y
254
+
255
+ # Perform some operation (access data)
256
+ _ = scatter.data
257
+
258
+ # Labels should persist
259
+ assert scatter._labels.x == original_x
260
+ assert scatter._labels.y == original_y
261
+
262
+ def test_log_scale_defaults(self):
263
+ """Test default log scale settings."""
264
+ scatter = Scatter(self.x_data, self.y_data)
265
+
266
+ assert scatter._log.x is False
267
+ assert scatter._log.y is False
268
+
269
+ def test_log_scale_configuration(self):
270
+ """Test setting logarithmic scales via namedtuple replacement."""
271
+ scatter = Scatter(self.x_data, self.y_data)
272
+
273
+ # LogAxes is a namedtuple, so we need to replace it entirely
274
+ new_log = scatter._log._replace(x=True, y=True)
275
+ scatter._log = new_log
276
+
277
+ assert scatter._log.x is True
278
+ assert scatter._log.y is True
279
+
280
+
281
+ class TestScatterPlotGeneration:
282
+ """Test plot generation and matplotlib integration."""
283
+
284
+ def setup_method(self):
285
+ """Set up test data for each test method."""
286
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
287
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
288
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
289
+
290
+ @patch("matplotlib.pyplot.subplots")
291
+ def test_make_plot_basic(self, mock_subplots):
292
+ """Test basic scatter plot generation."""
293
+ # Setup mock
294
+ mock_fig = MagicMock()
295
+ mock_ax = MagicMock()
296
+ mock_collection = MagicMock(spec=PathCollection)
297
+ mock_subplots.return_value = (mock_fig, mock_ax)
298
+ mock_ax.scatter.return_value = mock_collection
299
+
300
+ scatter = Scatter(self.x_data, self.y_data)
301
+ ax, cbar = scatter.make_plot()
302
+
303
+ # Verify scatter plot was called
304
+ mock_ax.scatter.assert_called_once()
305
+ assert ax == mock_ax
306
+ assert cbar is None # No colorbar for 2D plot
307
+
308
+ @patch("matplotlib.pyplot.subplots")
309
+ def test_make_plot_with_z_data(self, mock_subplots):
310
+ """Test scatter plot generation with z data."""
311
+ # Setup mock
312
+ mock_fig = MagicMock()
313
+ mock_ax = MagicMock()
314
+ mock_collection = MagicMock(spec=PathCollection)
315
+ mock_subplots.return_value = (mock_fig, mock_ax)
316
+ mock_ax.scatter.return_value = mock_collection
317
+
318
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
319
+
320
+ # Mock the _make_cbar method
321
+ with patch.object(scatter, "_make_cbar") as mock_make_cbar:
322
+ mock_cbar = MagicMock()
323
+ mock_make_cbar.return_value = mock_cbar
324
+
325
+ ax, cbar = scatter.make_plot()
326
+
327
+ # Verify scatter plot was called
328
+ mock_ax.scatter.assert_called_once()
329
+ # Verify colorbar was created
330
+ mock_make_cbar.assert_called_once()
331
+ assert ax == mock_ax
332
+ assert cbar == mock_cbar
333
+
334
+ @patch("matplotlib.pyplot.subplots")
335
+ def test_make_plot_with_provided_ax(self, mock_subplots):
336
+ """Test plot generation with provided axes."""
337
+ # Setup mock
338
+ provided_ax = MagicMock()
339
+ mock_collection = MagicMock(spec=PathCollection)
340
+ provided_ax.scatter.return_value = mock_collection
341
+
342
+ scatter = Scatter(self.x_data, self.y_data)
343
+ ax, cbar = scatter.make_plot(ax=provided_ax)
344
+
345
+ # Should not create new subplot
346
+ mock_subplots.assert_not_called()
347
+ # Should use provided axes
348
+ provided_ax.scatter.assert_called_once()
349
+ assert ax == provided_ax
350
+
351
+ @patch("matplotlib.pyplot.subplots")
352
+ def test_make_plot_no_colorbar(self, mock_subplots):
353
+ """Test plot generation with colorbar disabled."""
354
+ # Setup mock
355
+ mock_fig = MagicMock()
356
+ mock_ax = MagicMock()
357
+ mock_collection = MagicMock(spec=PathCollection)
358
+ mock_subplots.return_value = (mock_fig, mock_ax)
359
+ mock_ax.scatter.return_value = mock_collection
360
+
361
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
362
+ ax, cbar = scatter.make_plot(cbar=False)
363
+
364
+ assert cbar is None
365
+
366
+ @patch("matplotlib.pyplot.subplots")
367
+ def test_make_plot_kwargs_passed(self, mock_subplots):
368
+ """Test that kwargs are passed to ax.scatter."""
369
+ # Setup mock
370
+ mock_fig = MagicMock()
371
+ mock_ax = MagicMock()
372
+ mock_collection = MagicMock(spec=PathCollection)
373
+ mock_subplots.return_value = (mock_fig, mock_ax)
374
+ mock_ax.scatter.return_value = mock_collection
375
+
376
+ scatter = Scatter(self.x_data, self.y_data)
377
+ scatter.make_plot(s=50, alpha=0.7, marker="s")
378
+
379
+ # Check that kwargs were passed
380
+ call_args = mock_ax.scatter.call_args
381
+ assert "s" in call_args.kwargs
382
+ assert "alpha" in call_args.kwargs
383
+ assert "marker" in call_args.kwargs
384
+ assert call_args.kwargs["s"] == 50
385
+ assert call_args.kwargs["alpha"] == 0.7
386
+ assert call_args.kwargs["marker"] == "s"
387
+
388
+ def test_format_axis_method(self):
389
+ """Test the _format_axis method."""
390
+ scatter = Scatter(self.x_data, self.y_data)
391
+
392
+ # Setup mock axes and collection
393
+ mock_ax = MagicMock()
394
+ mock_collection = MagicMock()
395
+ mock_collection.sticky_edges.x = [0, 0]
396
+ mock_collection.sticky_edges.y = [0, 0]
397
+
398
+ # Test the method
399
+ scatter._format_axis(mock_ax, mock_collection)
400
+
401
+ # Verify axes methods were called
402
+ mock_ax.update_datalim.assert_called_once()
403
+ mock_ax.autoscale_view.assert_called_once()
404
+
405
+ # Verify sticky edges were set
406
+ assert mock_collection.sticky_edges.x[0] == self.x_data.min()
407
+ assert mock_collection.sticky_edges.x[1] == self.x_data.max()
408
+ assert mock_collection.sticky_edges.y[0] == self.y_data.min()
409
+ assert mock_collection.sticky_edges.y[1] == self.y_data.max()
410
+
411
+
412
+ class TestScatterColorMapping:
413
+ """Test color mapping and colorbar functionality."""
414
+
415
+ def setup_method(self):
416
+ """Set up test data for each test method."""
417
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
418
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
419
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
420
+ self.uniform_z = pd.Series([5, 5, 5, 5, 5], name="uniform_z")
421
+
422
+ @patch("matplotlib.pyplot.subplots")
423
+ def test_colorbar_creation_with_z_data(self, mock_subplots):
424
+ """Test colorbar creation when z data is provided."""
425
+ # Setup mock
426
+ mock_fig = MagicMock()
427
+ mock_ax = MagicMock()
428
+ mock_collection = MagicMock(spec=PathCollection)
429
+ mock_subplots.return_value = (mock_fig, mock_ax)
430
+ mock_ax.scatter.return_value = mock_collection
431
+
432
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
433
+
434
+ with patch.object(scatter, "_make_cbar") as mock_make_cbar:
435
+ mock_cbar = MagicMock()
436
+ mock_make_cbar.return_value = mock_cbar
437
+
438
+ ax, cbar = scatter.make_plot(cbar=True)
439
+
440
+ mock_make_cbar.assert_called_once()
441
+ assert cbar == mock_cbar
442
+
443
+ @patch("matplotlib.pyplot.subplots")
444
+ def test_no_colorbar_with_uniform_z(self, mock_subplots):
445
+ """Test no colorbar when z data is uniform."""
446
+ # Setup mock
447
+ mock_fig = MagicMock()
448
+ mock_ax = MagicMock()
449
+ mock_collection = MagicMock(spec=PathCollection)
450
+ mock_subplots.return_value = (mock_fig, mock_ax)
451
+ mock_ax.scatter.return_value = mock_collection
452
+
453
+ scatter = Scatter(self.x_data, self.y_data, self.uniform_z)
454
+ ax, cbar = scatter.make_plot()
455
+
456
+ # No colorbar should be created for uniform z data
457
+ assert cbar is None
458
+
459
+ @patch("matplotlib.pyplot.subplots")
460
+ def test_colorbar_kwargs_passed(self, mock_subplots):
461
+ """Test that colorbar kwargs are passed correctly."""
462
+ # Setup mock
463
+ mock_fig = MagicMock()
464
+ mock_ax = MagicMock()
465
+ mock_collection = MagicMock(spec=PathCollection)
466
+ mock_subplots.return_value = (mock_fig, mock_ax)
467
+ mock_ax.scatter.return_value = mock_collection
468
+
469
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
470
+
471
+ cbar_kwargs = {"orientation": "horizontal", "shrink": 0.8}
472
+
473
+ with patch.object(scatter, "_make_cbar") as mock_make_cbar:
474
+ mock_cbar = MagicMock()
475
+ mock_make_cbar.return_value = mock_cbar
476
+
477
+ scatter.make_plot(cbar_kwargs=cbar_kwargs)
478
+
479
+ # Check that kwargs were passed
480
+ call_args = mock_make_cbar.call_args
481
+ assert "orientation" in call_args.kwargs
482
+ assert "shrink" in call_args.kwargs
483
+
484
+
485
+ class TestScatterInheritance:
486
+ """Test integration with base classes."""
487
+
488
+ def setup_method(self):
489
+ """Set up test data for each test method."""
490
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
491
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
492
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
493
+
494
+ def test_plot_with_z_data_inheritance(self):
495
+ """Test inheritance from PlotWithZdata."""
496
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
497
+
498
+ # Should have PlotWithZdata methods and properties
499
+ assert hasattr(scatter, "data")
500
+ assert hasattr(scatter, "clip")
501
+ assert hasattr(scatter, "set_data")
502
+
503
+ # Test inherited functionality
504
+ assert isinstance(scatter.data, pd.DataFrame)
505
+ assert isinstance(scatter.clip, bool)
506
+
507
+ def test_cbar_maker_inheritance(self):
508
+ """Test inheritance from CbarMaker."""
509
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
510
+
511
+ # Should have CbarMaker methods
512
+ assert hasattr(scatter, "_make_cbar")
513
+
514
+ # Test that _make_cbar is callable
515
+ assert callable(scatter._make_cbar)
516
+
517
+ def test_base_class_properties_accessible(self):
518
+ """Test that base class properties are accessible."""
519
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
520
+
521
+ # Should have Base class properties
522
+ assert hasattr(scatter, "labels")
523
+ assert hasattr(scatter, "log")
524
+
525
+ # Test property access
526
+ labels = scatter.labels
527
+ log_settings = scatter.log
528
+ assert labels is not None
529
+ assert log_settings is not None
530
+
531
+
532
+ class TestScatterErrorHandling:
533
+ """Test error handling and edge cases."""
534
+
535
+ def setup_method(self):
536
+ """Set up test data for each test method."""
537
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
538
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
539
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
540
+
541
+ def test_invalid_data_types(self):
542
+ """Test handling of non-pandas Series data types."""
543
+ # Lists are actually converted to Series internally
544
+ scatter1 = Scatter([1, 2, 3], self.y_data[:3])
545
+ assert len(scatter1.data) == 3
546
+
547
+ scatter2 = Scatter(self.x_data[:3], [4, 5, 6])
548
+ assert len(scatter2.data) == 3
549
+
550
+ scatter3 = Scatter(self.x_data, self.y_data, [7, 8, 9, 10, 11])
551
+ assert len(scatter3.data) == 5
552
+
553
+ def test_nan_inf_handling(self):
554
+ """Test handling of NaN and infinite values."""
555
+ x_with_inf = pd.Series([1, 2, np.inf, 4, 5])
556
+ y_with_nan = pd.Series([2, np.nan, 6, 8, 10])
557
+
558
+ # NaN rows are dropped, but inf values may remain
559
+ scatter = Scatter(x_with_inf, y_with_nan)
560
+
561
+ # Check that NaN values are removed
562
+ assert not scatter.data.isnull().any().any()
563
+
564
+ # Inf values might remain in the data (this is the actual behavior)
565
+ assert len(scatter.data) == 4 # Row with NaN is dropped
566
+
567
+ def test_missing_data(self):
568
+ """Test behavior with incomplete data."""
569
+ # Test with missing indices
570
+ x_missing = pd.Series([1, 3, 5], index=[0, 2, 4])
571
+ y_missing = pd.Series([2, 6, 10], index=[0, 2, 4])
572
+
573
+ scatter = Scatter(x_missing, y_missing)
574
+
575
+ # Should handle missing indices correctly
576
+ assert len(scatter.data) == 3
577
+ assert list(scatter.data.index) == [0, 2, 4]
578
+
579
+ def test_single_point_data(self):
580
+ """Test handling of single data point."""
581
+ single_x = pd.Series([1])
582
+ single_y = pd.Series([2])
583
+
584
+ scatter = Scatter(single_x, single_y)
585
+
586
+ assert len(scatter.data) == 1
587
+ assert scatter.data.iloc[0]["x"] == 1
588
+ assert scatter.data.iloc[0]["y"] == 2
589
+
590
+ def test_negative_values_with_log(self):
591
+ """Test behavior with negative values when log scale is set."""
592
+ negative_x = pd.Series([-1, -2, -3])
593
+ positive_y = pd.Series([1, 2, 3])
594
+
595
+ scatter = Scatter(negative_x, positive_y)
596
+ # Set log scale using namedtuple replacement
597
+ new_log = scatter._log._replace(x=True)
598
+ scatter._log = new_log
599
+
600
+ # This should not raise an error during initialization
601
+ # The error would occur during plotting, which matplotlib handles
602
+ assert scatter._log.x is True
603
+
604
+ def test_empty_data_after_processing(self):
605
+ """Test handling when data becomes empty after processing."""
606
+ # Create data that becomes empty after NaN removal
607
+ all_nan_x = pd.Series([np.nan, np.nan, np.nan])
608
+ all_nan_y = pd.Series([np.nan, np.nan, np.nan])
609
+
610
+ with pytest.raises(ValueError, match="exclusively NaNs"):
611
+ Scatter(all_nan_x, all_nan_y)
612
+
613
+
614
+ class TestScatterPerformanceAndMemory:
615
+ """Test performance and memory usage."""
616
+
617
+ def test_large_datasets(self):
618
+ """Test performance with large datasets."""
619
+ # Create large dataset
620
+ n_points = 10000
621
+ large_x = pd.Series(np.random.randn(n_points))
622
+ large_y = pd.Series(np.random.randn(n_points))
623
+ large_z = pd.Series(np.random.randn(n_points))
624
+
625
+ # Should handle large datasets without issues
626
+ scatter = Scatter(large_x, large_y, large_z)
627
+
628
+ assert len(scatter.data) == n_points
629
+ assert "x" in scatter.data.columns
630
+ assert "y" in scatter.data.columns
631
+ assert "z" in scatter.data.columns
632
+
633
+ def test_memory_usage(self):
634
+ """Test efficient memory usage."""
635
+ scatter = Scatter(self.x_data, self.y_data)
636
+
637
+ # Data should be stored efficiently
638
+ data_memory = scatter.data.memory_usage(deep=True).sum()
639
+ assert data_memory > 0 # Should use some memory
640
+
641
+ # Should not create excessive copies
642
+ original_data = scatter.data
643
+ accessed_data = scatter.data
644
+ assert original_data is accessed_data # Should be same object
645
+
646
+ def setup_method(self):
647
+ """Set up test data for each test method."""
648
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
649
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
650
+
651
+
652
+ class TestScatterDocumentation:
653
+ """Test documentation and examples."""
654
+
655
+ def test_class_docstring_exists(self):
656
+ """Test that class has docstring."""
657
+ assert Scatter.__doc__ is not None
658
+ assert len(Scatter.__doc__.strip()) > 0
659
+
660
+ def test_init_docstring_exists(self):
661
+ """Test that __init__ method has docstring."""
662
+ assert Scatter.__init__.__doc__ is not None
663
+ assert len(Scatter.__init__.__doc__.strip()) > 0
664
+
665
+ def test_make_plot_docstring_exists(self):
666
+ """Test that make_plot method has docstring."""
667
+ assert Scatter.make_plot.__doc__ is not None
668
+ assert len(Scatter.make_plot.__doc__.strip()) > 0
669
+
670
+ def test_docstring_parameter_documentation(self):
671
+ """Test that parameters are documented in docstrings."""
672
+ init_doc = Scatter.__init__.__doc__
673
+
674
+ # Check that key parameters are documented
675
+ assert "x" in init_doc
676
+ assert "y" in init_doc
677
+ assert "z" in init_doc
678
+ assert "clip_data" in init_doc
679
+
680
+ make_plot_doc = Scatter.make_plot.__doc__
681
+ assert "ax" in make_plot_doc
682
+ assert "cbar" in make_plot_doc
683
+
684
+
685
+ class TestScatterIntegration:
686
+ """Integration tests for full scatter plot workflow."""
687
+
688
+ def setup_method(self):
689
+ """Set up test data for each test method."""
690
+ self.x_data = pd.Series([1, 2, 3, 4, 5], name="x_values")
691
+ self.y_data = pd.Series([2, 4, 6, 8, 10], name="y_values")
692
+ self.z_data = pd.Series([10, 20, 30, 40, 50], name="z_values")
693
+
694
+ @patch("matplotlib.pyplot.subplots")
695
+ def test_full_workflow_2d(self, mock_subplots):
696
+ """Test complete workflow for 2D scatter plot."""
697
+ # Setup mock
698
+ mock_fig = MagicMock()
699
+ mock_ax = MagicMock()
700
+ mock_collection = MagicMock(spec=PathCollection)
701
+ mock_subplots.return_value = (mock_fig, mock_ax)
702
+ mock_ax.scatter.return_value = mock_collection
703
+
704
+ # Create scatter plot
705
+ scatter = Scatter(self.x_data, self.y_data)
706
+
707
+ # Customize labels using namedtuple replacement
708
+ new_labels = scatter._labels._replace(x="X Values", y="Y Values")
709
+ scatter._labels = new_labels
710
+
711
+ # Generate plot
712
+ ax, cbar = scatter.make_plot()
713
+
714
+ # Verify workflow
715
+ assert ax is not None
716
+ assert cbar is None
717
+ mock_ax.scatter.assert_called_once()
718
+
719
+ @patch("matplotlib.pyplot.subplots")
720
+ def test_full_workflow_3d_with_colorbar(self, mock_subplots):
721
+ """Test complete workflow for 3D scatter plot with colorbar."""
722
+ # Setup mock
723
+ mock_fig = MagicMock()
724
+ mock_ax = MagicMock()
725
+ mock_collection = MagicMock(spec=PathCollection)
726
+ mock_subplots.return_value = (mock_fig, mock_ax)
727
+ mock_ax.scatter.return_value = mock_collection
728
+
729
+ scatter = Scatter(self.x_data, self.y_data, self.z_data)
730
+
731
+ with patch.object(scatter, "_make_cbar") as mock_make_cbar:
732
+ mock_cbar = MagicMock()
733
+ mock_make_cbar.return_value = mock_cbar
734
+
735
+ # Customize labels using namedtuple replacement
736
+ new_labels = scatter._labels._replace(
737
+ x="X Values", y="Y Values", z="Color Values"
738
+ )
739
+ scatter._labels = new_labels
740
+
741
+ # Generate plot with colorbar
742
+ ax, cbar = scatter.make_plot(cbar=True)
743
+
744
+ # Verify workflow
745
+ assert ax is not None
746
+ assert cbar is not None
747
+ mock_ax.scatter.assert_called_once()
748
+ mock_make_cbar.assert_called_once()
749
+
750
+
751
+ if __name__ == "__main__":
752
+ pytest.main([__file__])