numdaplot 0.1.0__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.
Files changed (474) hide show
  1. numdaplot/__init__.py +506 -0
  2. numdaplot/arrays/__init__.py +5 -0
  3. numdaplot/arrays/array.py +92 -0
  4. numdaplot/arrays/array_arithmetic.py +404 -0
  5. numdaplot/arrays/array_calculation.py +143 -0
  6. numdaplot/arrays/array_conversion.py +150 -0
  7. numdaplot/arrays/array_creation.py +371 -0
  8. numdaplot/arrays/array_data.py +281 -0
  9. numdaplot/arrays/array_layout.py +179 -0
  10. numdaplot/arrays/array_logic.py +227 -0
  11. numdaplot/arrays/array_reflected_arithmetic.py +334 -0
  12. numdaplot/arrays/array_refusals.py +339 -0
  13. numdaplot/arrays/array_selection.py +195 -0
  14. numdaplot/arrays/array_sorting.py +59 -0
  15. numdaplot/arrays/axis_number.py +58 -0
  16. numdaplot/arrays/calculation/__init__.py +5 -0
  17. numdaplot/arrays/calculation/counting_statistics.py +325 -0
  18. numdaplot/arrays/calculation/location_statistics.py +268 -0
  19. numdaplot/arrays/calculation/math_function_values.py +183 -0
  20. numdaplot/arrays/calculation/statistic_values.py +209 -0
  21. numdaplot/arrays/calculation/time_function_values.py +419 -0
  22. numdaplot/arrays/conversion/__init__.py +5 -0
  23. numdaplot/arrays/conversion/array_text.py +62 -0
  24. numdaplot/arrays/conversion/equality_check.py +72 -0
  25. numdaplot/arrays/conversion/python_values.py +70 -0
  26. numdaplot/arrays/conversion/time_text.py +290 -0
  27. numdaplot/arrays/creation/__init__.py +5 -0
  28. numdaplot/arrays/creation/date_parts.py +89 -0
  29. numdaplot/arrays/creation/date_parts_values.py +437 -0
  30. numdaplot/arrays/creation/distribution.py +54 -0
  31. numdaplot/arrays/creation/filled_values.py +58 -0
  32. numdaplot/arrays/creation/list_conversion.py +311 -0
  33. numdaplot/arrays/creation/list_shape.py +97 -0
  34. numdaplot/arrays/creation/normal.py +65 -0
  35. numdaplot/arrays/creation/numpy_conversion.py +149 -0
  36. numdaplot/arrays/creation/random_integers.py +104 -0
  37. numdaplot/arrays/creation/random_values.py +97 -0
  38. numdaplot/arrays/creation/range_values.py +73 -0
  39. numdaplot/arrays/creation/spacing.py +84 -0
  40. numdaplot/arrays/creation/spacing_values.py +63 -0
  41. numdaplot/arrays/creation/uniform.py +63 -0
  42. numdaplot/arrays/equality.py +68 -0
  43. numdaplot/arrays/layout/__init__.py +5 -0
  44. numdaplot/arrays/layout/sorting_values.py +113 -0
  45. numdaplot/arrays/layout/unique_values.py +49 -0
  46. numdaplot/arrays/mapping/__init__.py +5 -0
  47. numdaplot/arrays/mapping/mapped_values.py +286 -0
  48. numdaplot/arrays/mapping/unmatched.py +50 -0
  49. numdaplot/arrays/mapping/value_change.py +55 -0
  50. numdaplot/arrays/mapping/value_mapping.py +161 -0
  51. numdaplot/arrays/math_functions/__init__.py +5 -0
  52. numdaplot/arrays/math_functions/absolute.py +27 -0
  53. numdaplot/arrays/math_functions/cosine.py +28 -0
  54. numdaplot/arrays/math_functions/exponential.py +27 -0
  55. numdaplot/arrays/math_functions/logarithm.py +72 -0
  56. numdaplot/arrays/math_functions/math_function.py +58 -0
  57. numdaplot/arrays/math_functions/round.py +58 -0
  58. numdaplot/arrays/math_functions/sine.py +28 -0
  59. numdaplot/arrays/math_functions/square_root.py +27 -0
  60. numdaplot/arrays/operations/__init__.py +5 -0
  61. numdaplot/arrays/operations/boolean_operands.py +48 -0
  62. numdaplot/arrays/operations/combination.py +157 -0
  63. numdaplot/arrays/operations/float_errors.py +170 -0
  64. numdaplot/arrays/operations/integer_bounds.py +175 -0
  65. numdaplot/arrays/operations/integer_rules.py +397 -0
  66. numdaplot/arrays/operations/operand.py +139 -0
  67. numdaplot/arrays/operations/time_arithmetic.py +479 -0
  68. numdaplot/arrays/operations/time_bounds.py +286 -0
  69. numdaplot/arrays/operations/time_result_bounds.py +397 -0
  70. numdaplot/arrays/operations/transformation.py +54 -0
  71. numdaplot/arrays/operations/type_requirements.py +94 -0
  72. numdaplot/arrays/replacement.py +66 -0
  73. numdaplot/arrays/selection/__init__.py +5 -0
  74. numdaplot/arrays/selection/comparison_masks.py +131 -0
  75. numdaplot/arrays/selection/membership_masks.py +118 -0
  76. numdaplot/arrays/selection/missing_mask.py +50 -0
  77. numdaplot/arrays/selection/region_index.py +178 -0
  78. numdaplot/arrays/selection/replaced_values.py +120 -0
  79. numdaplot/arrays/selection/rule_mask.py +83 -0
  80. numdaplot/arrays/selection/time_reference.py +172 -0
  81. numdaplot/arrays/shape.py +74 -0
  82. numdaplot/arrays/type_match.py +51 -0
  83. numdaplot/data_types/__init__.py +5 -0
  84. numdaplot/data_types/library.py +57 -0
  85. numdaplot/data_types/numpy_mapping.py +207 -0
  86. numdaplot/data_types/pandas_mapping.py +114 -0
  87. numdaplot/data_types/time_of_day.py +292 -0
  88. numdaplot/data_types/type.py +224 -0
  89. numdaplot/data_types/value_family.py +149 -0
  90. numdaplot/data_types/value_type.py +147 -0
  91. numdaplot/dates/__init__.py +5 -0
  92. numdaplot/dates/custom_date_format.py +83 -0
  93. numdaplot/dates/date_format.py +120 -0
  94. numdaplot/dates/date_part.py +59 -0
  95. numdaplot/dates/date_part_unit.py +153 -0
  96. numdaplot/dates/date_period.py +57 -0
  97. numdaplot/dates/duration_in.py +58 -0
  98. numdaplot/dates/duration_unit.py +90 -0
  99. numdaplot/dates/period_unit.py +101 -0
  100. numdaplot/dates/time_function.py +56 -0
  101. numdaplot/dates/time_zone.py +68 -0
  102. numdaplot/dates/time_zone_change.py +71 -0
  103. numdaplot/dates/time_zone_mode.py +81 -0
  104. numdaplot/dates/to_duration.py +58 -0
  105. numdaplot/errors/__init__.py +7 -0
  106. numdaplot/errors/broadcast_warning.py +36 -0
  107. numdaplot/errors/calculation_warning.py +35 -0
  108. numdaplot/errors/cell_out_of_range_error.py +77 -0
  109. numdaplot/errors/column_not_found_error.py +64 -0
  110. numdaplot/errors/conflicting_settings_error.py +60 -0
  111. numdaplot/errors/dimension_error.py +62 -0
  112. numdaplot/errors/display_warning.py +32 -0
  113. numdaplot/errors/duplicate_column_error.py +82 -0
  114. numdaplot/errors/duplicate_label_error.py +55 -0
  115. numdaplot/errors/duplicate_statistic_error.py +55 -0
  116. numdaplot/errors/duplicate_value_error.py +54 -0
  117. numdaplot/errors/empty_array_error.py +55 -0
  118. numdaplot/errors/empty_list_error.py +52 -0
  119. numdaplot/errors/empty_region_error.py +34 -0
  120. numdaplot/errors/empty_text_error.py +34 -0
  121. numdaplot/errors/empty_total_error.py +62 -0
  122. numdaplot/errors/empty_values_error.py +34 -0
  123. numdaplot/errors/file_access_error.py +70 -0
  124. numdaplot/errors/file_exists_error.py +62 -0
  125. numdaplot/errors/file_not_found_error.py +56 -0
  126. numdaplot/errors/incompatible_charts_error.py +80 -0
  127. numdaplot/errors/incompatible_types_error.py +104 -0
  128. numdaplot/errors/integer_overflow_error.py +61 -0
  129. numdaplot/errors/invalid_base_error.py +52 -0
  130. numdaplot/errors/invalid_bin_width_error.py +66 -0
  131. numdaplot/errors/invalid_bounds_error.py +58 -0
  132. numdaplot/errors/invalid_chart_data_error.py +81 -0
  133. numdaplot/errors/invalid_color_count_error.py +63 -0
  134. numdaplot/errors/invalid_color_error.py +51 -0
  135. numdaplot/errors/invalid_column_name_error.py +52 -0
  136. numdaplot/errors/invalid_conversion_error.py +119 -0
  137. numdaplot/errors/invalid_count_error.py +61 -0
  138. numdaplot/errors/invalid_date_format_error.py +51 -0
  139. numdaplot/errors/invalid_deviation_error.py +52 -0
  140. numdaplot/errors/invalid_fraction_error.py +51 -0
  141. numdaplot/errors/invalid_label_count_error.py +61 -0
  142. numdaplot/errors/invalid_limits_error.py +111 -0
  143. numdaplot/errors/invalid_opacity_error.py +52 -0
  144. numdaplot/errors/invalid_point_size_error.py +52 -0
  145. numdaplot/errors/invalid_position_error.py +106 -0
  146. numdaplot/errors/invalid_resolution_error.py +51 -0
  147. numdaplot/errors/invalid_rotation_error.py +53 -0
  148. numdaplot/errors/invalid_seed_error.py +53 -0
  149. numdaplot/errors/invalid_separator_error.py +52 -0
  150. numdaplot/errors/invalid_shape_error.py +52 -0
  151. numdaplot/errors/invalid_sheet_name_error.py +54 -0
  152. numdaplot/errors/invalid_size_error.py +58 -0
  153. numdaplot/errors/invalid_step_error.py +77 -0
  154. numdaplot/errors/invalid_suffixes_error.py +61 -0
  155. numdaplot/errors/invalid_time_zone_change_error.py +63 -0
  156. numdaplot/errors/invalid_type_error.py +79 -0
  157. numdaplot/errors/irregular_list_error.py +36 -0
  158. numdaplot/errors/join_relation_error.py +183 -0
  159. numdaplot/errors/missing_dependency_error.py +58 -0
  160. numdaplot/errors/missing_type_error.py +36 -0
  161. numdaplot/errors/missing_value_error.py +62 -0
  162. numdaplot/errors/not_single_value_error.py +53 -0
  163. numdaplot/errors/numdaplot_error.py +25 -0
  164. numdaplot/errors/numdaplot_warning.py +34 -0
  165. numdaplot/errors/occupied_cell_error.py +63 -0
  166. numdaplot/errors/out_of_domain_error.py +70 -0
  167. numdaplot/errors/readability_warning.py +35 -0
  168. numdaplot/errors/refused_operation_error.py +64 -0
  169. numdaplot/errors/refused_setting_error.py +60 -0
  170. numdaplot/errors/rejected_dates.py +60 -0
  171. numdaplot/errors/repeated_key.py +36 -0
  172. numdaplot/errors/shape_mismatch_error.py +67 -0
  173. numdaplot/errors/time_overflow_error.py +131 -0
  174. numdaplot/errors/time_zone_mismatch_error.py +83 -0
  175. numdaplot/errors/unknown_time_zone_error.py +51 -0
  176. numdaplot/errors/unmatched_value_error.py +81 -0
  177. numdaplot/errors/unsupported_image_format_error.py +56 -0
  178. numdaplot/errors/unsupported_index_error.py +38 -0
  179. numdaplot/errors/unsupported_missing_error.py +129 -0
  180. numdaplot/errors/unsupported_type_error.py +62 -0
  181. numdaplot/errors/value_conversion_error.py +215 -0
  182. numdaplot/ordering/__init__.py +5 -0
  183. numdaplot/ordering/missing_position.py +46 -0
  184. numdaplot/ordering/order.py +46 -0
  185. numdaplot/package_version.py +36 -0
  186. numdaplot/plots/__init__.py +5 -0
  187. numdaplot/plots/chart_layer.py +47 -0
  188. numdaplot/plots/charts/__init__.py +5 -0
  189. numdaplot/plots/charts/bar_chart.py +98 -0
  190. numdaplot/plots/charts/bar_layout.py +58 -0
  191. numdaplot/plots/charts/bin_count.py +61 -0
  192. numdaplot/plots/charts/bin_width.py +78 -0
  193. numdaplot/plots/charts/box_chart.py +97 -0
  194. numdaplot/plots/charts/cell_values.py +61 -0
  195. numdaplot/plots/charts/chart.py +59 -0
  196. numdaplot/plots/charts/chart_settings.py +105 -0
  197. numdaplot/plots/charts/color_scale.py +147 -0
  198. numdaplot/plots/charts/heatmap_chart.py +92 -0
  199. numdaplot/plots/charts/histogram_chart.py +93 -0
  200. numdaplot/plots/charts/line_chart.py +100 -0
  201. numdaplot/plots/charts/line_type.py +75 -0
  202. numdaplot/plots/charts/marker_shape.py +113 -0
  203. numdaplot/plots/charts/missing_chart.py +60 -0
  204. numdaplot/plots/charts/missing_map_chart.py +27 -0
  205. numdaplot/plots/charts/orientation.py +58 -0
  206. numdaplot/plots/charts/outliers.py +49 -0
  207. numdaplot/plots/charts/percentages.py +55 -0
  208. numdaplot/plots/charts/pie_chart.py +87 -0
  209. numdaplot/plots/charts/scatter_chart.py +159 -0
  210. numdaplot/plots/charts/value_axis.py +66 -0
  211. numdaplot/plots/data/__init__.py +5 -0
  212. numdaplot/plots/data/array_values.py +128 -0
  213. numdaplot/plots/data/chart_data.py +143 -0
  214. numdaplot/plots/data/chart_values.py +109 -0
  215. numdaplot/plots/data/column_reading.py +468 -0
  216. numdaplot/plots/data/heatmap_values.py +63 -0
  217. numdaplot/plots/data/missing_cells.py +165 -0
  218. numdaplot/plots/data/pie_values.py +215 -0
  219. numdaplot/plots/data/point_values.py +249 -0
  220. numdaplot/plots/data/position_kind.py +83 -0
  221. numdaplot/plots/data/renamed_layers.py +340 -0
  222. numdaplot/plots/data/sample_values.py +160 -0
  223. numdaplot/plots/data/shown_columns.py +248 -0
  224. numdaplot/plots/data/table_values.py +256 -0
  225. numdaplot/plots/data/unique_labels.py +45 -0
  226. numdaplot/plots/drawing/__init__.py +5 -0
  227. numdaplot/plots/drawing/bar_drawing.py +316 -0
  228. numdaplot/plots/drawing/box_drawing.py +344 -0
  229. numdaplot/plots/drawing/cell_merging.py +237 -0
  230. numdaplot/plots/drawing/chart_texts.py +124 -0
  231. numdaplot/plots/drawing/color_bar.py +57 -0
  232. numdaplot/plots/drawing/color_scale_values.py +120 -0
  233. numdaplot/plots/drawing/default_labels.py +41 -0
  234. numdaplot/plots/drawing/drawn_chart.py +50 -0
  235. numdaplot/plots/drawing/grid_axes.py +75 -0
  236. numdaplot/plots/drawing/heatmap_drawing.py +313 -0
  237. numdaplot/plots/drawing/histogram_drawing.py +350 -0
  238. numdaplot/plots/drawing/label_room.py +344 -0
  239. numdaplot/plots/drawing/label_thinning.py +216 -0
  240. numdaplot/plots/drawing/layer_alignment.py +319 -0
  241. numdaplot/plots/drawing/layer_colors.py +123 -0
  242. numdaplot/plots/drawing/line_drawing.py +85 -0
  243. numdaplot/plots/drawing/marker_codes.py +20 -0
  244. numdaplot/plots/drawing/missing_drawing.py +360 -0
  245. numdaplot/plots/drawing/moment_period_formatter.py +253 -0
  246. numdaplot/plots/drawing/pie_drawing.py +185 -0
  247. numdaplot/plots/drawing/plot_axes.py +38 -0
  248. numdaplot/plots/drawing/plot_drawing.py +288 -0
  249. numdaplot/plots/drawing/plot_theme.py +45 -0
  250. numdaplot/plots/drawing/position_axis.py +278 -0
  251. numdaplot/plots/drawing/scatter_drawing.py +364 -0
  252. numdaplot/plots/drawing/series_colors.py +177 -0
  253. numdaplot/plots/drawing/size_inches.py +45 -0
  254. numdaplot/plots/drawing/style_drawing.py +410 -0
  255. numdaplot/plots/drawing/text_contrast.py +44 -0
  256. numdaplot/plots/drawing/tick_rotation.py +354 -0
  257. numdaplot/plots/drawing/time_axis.py +212 -0
  258. numdaplot/plots/drawing/whole_numbers.py +72 -0
  259. numdaplot/plots/figure/__init__.py +5 -0
  260. numdaplot/plots/figure/cell.py +95 -0
  261. numdaplot/plots/figure/figure.py +256 -0
  262. numdaplot/plots/figure/figure_drawing.py +99 -0
  263. numdaplot/plots/figure/figure_style.py +60 -0
  264. numdaplot/plots/figure/layout.py +71 -0
  265. numdaplot/plots/figure/placement.py +150 -0
  266. numdaplot/plots/layer_reading.py +166 -0
  267. numdaplot/plots/output/__init__.py +5 -0
  268. numdaplot/plots/output/image_saving.py +187 -0
  269. numdaplot/plots/output/plot_display.py +181 -0
  270. numdaplot/plots/output/shown_object.py +45 -0
  271. numdaplot/plots/overlay_checks.py +245 -0
  272. numdaplot/plots/plot.py +31 -0
  273. numdaplot/plots/plot_data.py +140 -0
  274. numdaplot/plots/plot_distribution_creation.py +237 -0
  275. numdaplot/plots/plot_output.py +124 -0
  276. numdaplot/plots/plot_overlays.py +273 -0
  277. numdaplot/plots/plot_overview_creation.py +195 -0
  278. numdaplot/plots/plot_series_creation.py +213 -0
  279. numdaplot/plots/style/__init__.py +5 -0
  280. numdaplot/plots/style/axis_settings.py +60 -0
  281. numdaplot/plots/style/color.py +168 -0
  282. numdaplot/plots/style/custom_color.py +65 -0
  283. numdaplot/plots/style/grid_lines.py +49 -0
  284. numdaplot/plots/style/image_options.py +71 -0
  285. numdaplot/plots/style/legend_position.py +149 -0
  286. numdaplot/plots/style/plot_style.py +136 -0
  287. numdaplot/plots/style/size.py +70 -0
  288. numdaplot/plots/style/size_unit.py +62 -0
  289. numdaplot/positions/__init__.py +5 -0
  290. numdaplot/positions/axis.py +54 -0
  291. numdaplot/positions/index.py +51 -0
  292. numdaplot/positions/range.py +90 -0
  293. numdaplot/positions/region.py +92 -0
  294. numdaplot/py.typed +0 -0
  295. numdaplot/ratios/__init__.py +5 -0
  296. numdaplot/ratios/fraction.py +40 -0
  297. numdaplot/ratios/measure.py +48 -0
  298. numdaplot/rules/__init__.py +5 -0
  299. numdaplot/rules/between.py +78 -0
  300. numdaplot/rules/bounds.py +83 -0
  301. numdaplot/rules/case.py +48 -0
  302. numdaplot/rules/contains.py +63 -0
  303. numdaplot/rules/equal.py +43 -0
  304. numdaplot/rules/greater.py +39 -0
  305. numdaplot/rules/greater_or_equal.py +38 -0
  306. numdaplot/rules/is_in.py +67 -0
  307. numdaplot/rules/is_missing.py +25 -0
  308. numdaplot/rules/is_present.py +25 -0
  309. numdaplot/rules/less.py +39 -0
  310. numdaplot/rules/less_or_equal.py +38 -0
  311. numdaplot/rules/not_equal.py +45 -0
  312. numdaplot/rules/rule.py +62 -0
  313. numdaplot/rules/rule_values.py +44 -0
  314. numdaplot/rules/value_rule.py +110 -0
  315. numdaplot/settings/__init__.py +5 -0
  316. numdaplot/settings/argument_types.py +327 -0
  317. numdaplot/settings/field_types.py +593 -0
  318. numdaplot/statistics/__init__.py +5 -0
  319. numdaplot/statistics/count.py +71 -0
  320. numdaplot/statistics/count_distinct.py +27 -0
  321. numdaplot/statistics/counted_missing.py +46 -0
  322. numdaplot/statistics/maximum.py +27 -0
  323. numdaplot/statistics/mean.py +27 -0
  324. numdaplot/statistics/median.py +27 -0
  325. numdaplot/statistics/minimum.py +27 -0
  326. numdaplot/statistics/most_frequent.py +27 -0
  327. numdaplot/statistics/most_frequent_count.py +27 -0
  328. numdaplot/statistics/quantile.py +61 -0
  329. numdaplot/statistics/standard_deviation.py +29 -0
  330. numdaplot/statistics/statistic.py +63 -0
  331. numdaplot/statistics/sum.py +27 -0
  332. numdaplot/tables/__init__.py +5 -0
  333. numdaplot/tables/aggregation/__init__.py +5 -0
  334. numdaplot/tables/aggregation/aggregated_frame.py +189 -0
  335. numdaplot/tables/aggregation/aggregation.py +97 -0
  336. numdaplot/tables/aggregation/calculation.py +123 -0
  337. numdaplot/tables/aggregation/result_column.py +108 -0
  338. numdaplot/tables/aggregation/row_groups.py +96 -0
  339. numdaplot/tables/aggregation/statistic_name.py +122 -0
  340. numdaplot/tables/columns/__init__.py +5 -0
  341. numdaplot/tables/columns/added_column.py +89 -0
  342. numdaplot/tables/columns/boolean_conversion.py +144 -0
  343. numdaplot/tables/columns/boolean_rule.py +59 -0
  344. numdaplot/tables/columns/bracket_end.py +50 -0
  345. numdaplot/tables/columns/bracket_names.py +346 -0
  346. numdaplot/tables/columns/bracketed_column.py +179 -0
  347. numdaplot/tables/columns/brackets.py +234 -0
  348. numdaplot/tables/columns/chosen_columns.py +55 -0
  349. numdaplot/tables/columns/column_choice.py +84 -0
  350. numdaplot/tables/columns/column_mode.py +64 -0
  351. numdaplot/tables/columns/column_names.py +186 -0
  352. numdaplot/tables/columns/conversion.py +103 -0
  353. numdaplot/tables/columns/converted_column.py +669 -0
  354. numdaplot/tables/columns/date_conversion.py +526 -0
  355. numdaplot/tables/columns/date_range.py +135 -0
  356. numdaplot/tables/columns/name_change.py +67 -0
  357. numdaplot/tables/columns/new_column.py +79 -0
  358. numdaplot/tables/columns/number_conversion.py +281 -0
  359. numdaplot/tables/columns/renamed_columns.py +60 -0
  360. numdaplot/tables/columns/renaming.py +81 -0
  361. numdaplot/tables/columns/text_conversion.py +70 -0
  362. numdaplot/tables/columns/time_conversion.py +313 -0
  363. numdaplot/tables/columns/time_zone_conversion.py +128 -0
  364. numdaplot/tables/conflict.py +68 -0
  365. numdaplot/tables/description/__init__.py +5 -0
  366. numdaplot/tables/description/described_frame.py +335 -0
  367. numdaplot/tables/description/description.py +155 -0
  368. numdaplot/tables/duplicates/__init__.py +5 -0
  369. numdaplot/tables/duplicates/deduplicated_frame.py +66 -0
  370. numdaplot/tables/duplicates/deduplication.py +88 -0
  371. numdaplot/tables/duplicates/keep.py +81 -0
  372. numdaplot/tables/files/__init__.py +5 -0
  373. numdaplot/tables/files/column_names.py +60 -0
  374. numdaplot/tables/files/csv_file.py +265 -0
  375. numdaplot/tables/files/csv_read_options.py +89 -0
  376. numdaplot/tables/files/csv_separator.py +41 -0
  377. numdaplot/tables/files/csv_write_options.py +79 -0
  378. numdaplot/tables/files/decimal_count.py +42 -0
  379. numdaplot/tables/files/encoding.py +82 -0
  380. numdaplot/tables/files/excel_file.py +171 -0
  381. numdaplot/tables/files/excel_read_options.py +79 -0
  382. numdaplot/tables/files/excel_sheet.py +50 -0
  383. numdaplot/tables/files/excel_time_cells.py +146 -0
  384. numdaplot/tables/files/excel_write_options.py +63 -0
  385. numdaplot/tables/files/file_access.py +152 -0
  386. numdaplot/tables/files/file_paths.py +106 -0
  387. numdaplot/tables/files/json_decimals.py +387 -0
  388. numdaplot/tables/files/json_file.py +203 -0
  389. numdaplot/tables/files/json_layout.py +63 -0
  390. numdaplot/tables/files/json_read_options.py +64 -0
  391. numdaplot/tables/files/json_write_options.py +71 -0
  392. numdaplot/tables/files/missing_texts.py +63 -0
  393. numdaplot/tables/files/optional_package.py +42 -0
  394. numdaplot/tables/files/pandas_backend.py +11 -0
  395. numdaplot/tables/files/parquet_file.py +91 -0
  396. numdaplot/tables/files/parquet_read_options.py +56 -0
  397. numdaplot/tables/files/sas_file.py +94 -0
  398. numdaplot/tables/files/sas_read_options.py +67 -0
  399. numdaplot/tables/files/stata_file.py +83 -0
  400. numdaplot/tables/files/stata_read_options.py +56 -0
  401. numdaplot/tables/files/xpt_read_options.py +65 -0
  402. numdaplot/tables/filtering/__init__.py +5 -0
  403. numdaplot/tables/filtering/checked_frame.py +60 -0
  404. numdaplot/tables/filtering/column_mask.py +71 -0
  405. numdaplot/tables/filtering/column_match.py +62 -0
  406. numdaplot/tables/filtering/condition.py +94 -0
  407. numdaplot/tables/filtering/filter.py +74 -0
  408. numdaplot/tables/filtering/filter_mode.py +67 -0
  409. numdaplot/tables/filtering/row_mask.py +152 -0
  410. numdaplot/tables/filtering/rule_moments.py +164 -0
  411. numdaplot/tables/frames/__init__.py +5 -0
  412. numdaplot/tables/frames/array_frame.py +95 -0
  413. numdaplot/tables/frames/cleaned_names.py +132 -0
  414. numdaplot/tables/frames/column.py +15 -0
  415. numdaplot/tables/frames/column_values.py +273 -0
  416. numdaplot/tables/frames/frame_equality.py +130 -0
  417. numdaplot/tables/frames/frame_normalization.py +459 -0
  418. numdaplot/tables/frames/named_column_errors.py +85 -0
  419. numdaplot/tables/frames/pandas_decimals.py +113 -0
  420. numdaplot/tables/frames/region_positions.py +113 -0
  421. numdaplot/tables/frames/table_text.py +222 -0
  422. numdaplot/tables/frames/time_columns.py +345 -0
  423. numdaplot/tables/frames/time_range_errors.py +117 -0
  424. numdaplot/tables/frames/time_zones.py +271 -0
  425. numdaplot/tables/joining/__init__.py +5 -0
  426. numdaplot/tables/joining/join.py +110 -0
  427. numdaplot/tables/joining/join_keys.py +367 -0
  428. numdaplot/tables/joining/join_mode.py +93 -0
  429. numdaplot/tables/joining/join_relation.py +149 -0
  430. numdaplot/tables/joining/join_suffixes.py +71 -0
  431. numdaplot/tables/joining/joined_frame.py +166 -0
  432. numdaplot/tables/joining/joined_names.py +107 -0
  433. numdaplot/tables/joining/joined_rows.py +235 -0
  434. numdaplot/tables/joining/key_types.py +57 -0
  435. numdaplot/tables/joining/relation.py +78 -0
  436. numdaplot/tables/missing/__init__.py +5 -0
  437. numdaplot/tables/missing/missing_count.py +59 -0
  438. numdaplot/tables/missing/missing_counts.py +214 -0
  439. numdaplot/tables/missing/missing_drop.py +98 -0
  440. numdaplot/tables/missing/missing_mode.py +63 -0
  441. numdaplot/tables/missing/missing_ratio.py +71 -0
  442. numdaplot/tables/missing/missing_removal.py +257 -0
  443. numdaplot/tables/missing/missing_summary.py +174 -0
  444. numdaplot/tables/missing/ratio_comparison.py +70 -0
  445. numdaplot/tables/pivot/__init__.py +5 -0
  446. numdaplot/tables/pivot/pivot_table.py +104 -0
  447. numdaplot/tables/pivot/pivoted_frame.py +244 -0
  448. numdaplot/tables/preview/__init__.py +5 -0
  449. numdaplot/tables/preview/notebook_display.py +238 -0
  450. numdaplot/tables/preview/preview.py +100 -0
  451. numdaplot/tables/preview/preview_rows.py +55 -0
  452. numdaplot/tables/preview/shown_columns.py +62 -0
  453. numdaplot/tables/preview/side.py +82 -0
  454. numdaplot/tables/sorting/__init__.py +5 -0
  455. numdaplot/tables/sorting/sort_key.py +71 -0
  456. numdaplot/tables/sorting/sorted_frame.py +81 -0
  457. numdaplot/tables/sorting/sorting.py +82 -0
  458. numdaplot/tables/table.py +71 -0
  459. numdaplot/tables/table_calculation.py +172 -0
  460. numdaplot/tables/table_columns.py +214 -0
  461. numdaplot/tables/table_conversion.py +351 -0
  462. numdaplot/tables/table_data.py +321 -0
  463. numdaplot/tables/table_display.py +56 -0
  464. numdaplot/tables/table_joining.py +80 -0
  465. numdaplot/tables/table_layout.py +105 -0
  466. numdaplot/tables/table_missing.py +146 -0
  467. numdaplot/tables/table_reading.py +451 -0
  468. numdaplot/tables/table_refusals.py +295 -0
  469. numdaplot/tables/table_selection.py +163 -0
  470. numdaplot/tables/table_writing.py +269 -0
  471. numdaplot-0.1.0.dist-info/METADATA +176 -0
  472. numdaplot-0.1.0.dist-info/RECORD +474 -0
  473. numdaplot-0.1.0.dist-info/WHEEL +4 -0
  474. numdaplot-0.1.0.dist-info/licenses/LICENSE +28 -0
@@ -0,0 +1,360 @@
1
+ """
2
+ Drawing of the missing values of a Table: bars per column and a map of every value.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ # The matplotlib stubs leave the keyword arguments of most drawing methods untyped.
8
+ # pyright: reportUnknownMemberType=false
9
+
10
+ from typing import cast
11
+
12
+ import numpy
13
+ from matplotlib.axes import Axes
14
+ from matplotlib.colors import ListedColormap
15
+ from matplotlib.container import BarContainer
16
+ from matplotlib.patches import Rectangle
17
+
18
+ from numdaplot.plots.chart_layer import ChartLayer
19
+ from numdaplot.plots.charts.bar_chart import BarChart
20
+ from numdaplot.plots.charts.missing_chart import MissingChart
21
+ from numdaplot.plots.data.chart_values import ChartValues
22
+ from numdaplot.plots.data.missing_cells import MissingCounts
23
+ from numdaplot.plots.drawing.bar_drawing import draw_bar_chart
24
+ from numdaplot.plots.drawing.cell_merging import find_cell_limits, fit_cells_to_axes, merge_cells
25
+ from numdaplot.plots.drawing.default_labels import COLUMN_LABEL, ROW_LABEL
26
+ from numdaplot.plots.drawing.drawn_chart import DrawnChart
27
+ from numdaplot.plots.drawing.grid_axes import GridAxes
28
+ from numdaplot.plots.drawing.heatmap_drawing import (
29
+ CELL_ASPECT,
30
+ CELL_INTERPOLATION,
31
+ hide_frame,
32
+ place_column_names,
33
+ stack_columns,
34
+ )
35
+ from numdaplot.plots.drawing.plot_theme import GRID_COLOR
36
+ from numdaplot.plots.drawing.whole_numbers import place_whole_ticks
37
+ from numdaplot.ratios.measure import Measure
38
+
39
+ MISSING_COLOR = "#33415c"
40
+ PRESENT_COLOR = GRID_COLOR
41
+ MISSING_TOTAL_LABEL = "Missing ({missing_total})"
42
+ PRESENT_LABEL = "Present"
43
+ MAP_TITLE = "Map of missing values"
44
+ LOWEST_RATIO = 0.0
45
+ HIGHEST_RATIO = 1.0
46
+ RATIO_TICK_COUNT = 6
47
+ # A patch placed nowhere draws nothing, yet the legend shows its colors.
48
+ LEGEND_SWATCH_CORNER = (numpy.nan, numpy.nan)
49
+ LEGEND_SWATCH_SIZE = 0.0
50
+ LEGEND_SWATCH_EDGE_WIDTH = 0.5
51
+ PERCENT_FACTOR = 100.0
52
+ STACKED_BAR_LABEL = "{count}\n{percent:.1f} %"
53
+ ONE_LINE_BAR_LABEL = "{count} ({percent:.1f} %)"
54
+ BAR_LABEL_FONT_SIZE = 9
55
+ BAR_LABEL_PADDING = 3
56
+ STACKED_LABEL_MINIMUM_WIDTH = 34.0
57
+ ONE_LINE_LABEL_MINIMUM_WIDTH = 13.0
58
+ # Heights in pixels, kept high enough for the layout narrowing the axes afterwards.
59
+ STACKED_LABEL_HEIGHT = 40.0
60
+ ONE_LINE_LABEL_HEIGHT = 90.0
61
+ UPWARD_ROTATION = 90
62
+ HIGHEST_HEADROOM_SHARE = 0.5
63
+ EMPTY_BAR_TOP = 1.0
64
+
65
+
66
+ def draw_missing_chart(axes: Axes, layer: ChartLayer) -> DrawnChart:
67
+ """
68
+ Draw one bar per column of a Table, as high as its missing values.
69
+
70
+ Ratios have ticks from 0 to 1, and counts have ticks on whole numbers. Each bar is labeled with its number of
71
+ missing values and their share of the rows, when the bars leave room for it.
72
+
73
+ .. versionadded:: 0.1.0
74
+
75
+ Parameters
76
+ ----------
77
+ axes
78
+ The matplotlib axes drawn on.
79
+ layer
80
+ A MissingChart and the missing values of each column.
81
+
82
+ Returns
83
+ -------
84
+ DrawnChart
85
+ ``"Missing count"`` or ``"Missing ratio"`` as label of the values, and grid lines across their axis only.
86
+
87
+ Examples
88
+ --------
89
+ >>> import numdaplot as ndp
90
+ >>> from matplotlib.figure import Figure
91
+ >>> from numdaplot.plots.chart_layer import ChartLayer
92
+ >>> from numdaplot.plots.data.missing_cells import read_missing_counts
93
+ >>> from numdaplot.plots.drawing.missing_drawing import draw_missing_chart
94
+ >>> prices = ndp.Array.from_list([12.0, None])
95
+ >>> flats = ndp.Table.from_arrays({"price": prices})
96
+ >>> axes = Figure().add_subplot()
97
+ >>> chart = ndp.MissingChart(measure=ndp.Measure.RATIO)
98
+ >>> drawn_chart = draw_missing_chart(axes, ChartLayer(chart, read_missing_counts(flats, chart.measure)))
99
+ >>> [float(tick) for tick in axes.get_yticks()][-1]
100
+ 1.0
101
+ """
102
+ chart = cast(MissingChart, layer.chart)
103
+ values = cast(MissingCounts, layer.values)
104
+ bar_layer = ChartLayer(BarChart(), values)
105
+ drawn_chart = draw_bar_chart(axes, bar_layer)
106
+ label_height = write_bar_labels(axes, values)
107
+ shown_values = values.series[0].values
108
+ highest_bar = float(numpy.max(shown_values, initial=0.0))
109
+ if chart.measure == Measure.RATIO:
110
+ highest_bar = HIGHEST_RATIO
111
+
112
+ bar_top = highest_bar
113
+ if bar_top == 0:
114
+ bar_top = EMPTY_BAR_TOP
115
+
116
+ axis_top = find_axis_top(bar_top, label_height, axes.bbox.height)
117
+ axes.set_ylim(LOWEST_RATIO, axis_top)
118
+ if chart.measure == Measure.RATIO:
119
+ ratio_ticks = numpy.linspace(LOWEST_RATIO, HIGHEST_RATIO, RATIO_TICK_COUNT)
120
+ axes.set_yticks(ratio_ticks)
121
+ return drawn_chart
122
+
123
+ place_whole_ticks(axes.yaxis, shown_values)
124
+
125
+ return drawn_chart
126
+
127
+
128
+ def write_bar_labels(axes: Axes, values: MissingCounts) -> float:
129
+ """
130
+ Write the number of missing values and their share of the rows above each bar, with the room the bars leave.
131
+
132
+ .. versionadded:: 0.1.0
133
+
134
+ Parameters
135
+ ----------
136
+ axes
137
+ The matplotlib axes holding the bars.
138
+ values
139
+ The counts of each column and the number of rows.
140
+
141
+ Returns
142
+ -------
143
+ float
144
+ The height in pixels the labels need above the bars, 0 when the bars are too narrow for them.
145
+
146
+ Examples
147
+ --------
148
+ >>> import numdaplot as ndp
149
+ >>> from matplotlib.figure import Figure
150
+ >>> from numdaplot.plots.chart_layer import ChartLayer
151
+ >>> from numdaplot.plots.data.missing_cells import read_missing_counts
152
+ >>> from numdaplot.plots.drawing.bar_drawing import draw_bar_chart
153
+ >>> from numdaplot.plots.drawing.missing_drawing import write_bar_labels
154
+ >>> flats = ndp.Table.from_arrays({"price": ndp.Array.from_list([12.0, None])})
155
+ >>> values = read_missing_counts(flats, ndp.Measure.COUNT)
156
+ >>> axes = Figure().add_subplot()
157
+ >>> drawn_chart = draw_bar_chart(axes, ChartLayer(ndp.BarChart(), values))
158
+ >>> write_bar_labels(axes, values)
159
+ 40.0
160
+ >>> axes.texts[0].get_text().splitlines()
161
+ ['1', '50.0 %']
162
+ """
163
+ column_count = len(values.counts)
164
+ if column_count == 0:
165
+ return 0.0
166
+
167
+ column_width = axes.bbox.width / column_count
168
+ if column_width < ONE_LINE_LABEL_MINIMUM_WIDTH:
169
+ return 0.0
170
+
171
+ is_stacked = column_width >= STACKED_LABEL_MINIMUM_WIDTH
172
+ label_format = ONE_LINE_BAR_LABEL
173
+ rotation = UPWARD_ROTATION
174
+ label_height = ONE_LINE_LABEL_HEIGHT
175
+ if is_stacked:
176
+ label_format = STACKED_BAR_LABEL
177
+ rotation = 0
178
+ label_height = STACKED_LABEL_HEIGHT
179
+
180
+ labels = format_bar_labels(values, label_format)
181
+ bars = cast(BarContainer, axes.containers[0])
182
+ axes.bar_label(
183
+ bars,
184
+ labels=labels,
185
+ padding=BAR_LABEL_PADDING,
186
+ fontsize=BAR_LABEL_FONT_SIZE,
187
+ rotation=rotation,
188
+ )
189
+
190
+ return label_height
191
+
192
+
193
+ def format_bar_labels(values: MissingCounts, label_format: str) -> list[str]:
194
+ """
195
+ Return the label of each bar, with its number of missing values and their percentage of the rows.
196
+
197
+ .. versionadded:: 0.1.0
198
+
199
+ Parameters
200
+ ----------
201
+ values
202
+ The counts of each column and the number of rows.
203
+ label_format
204
+ The text of a label, with the fields ``count`` and ``percent``.
205
+
206
+ Returns
207
+ -------
208
+ list[str]
209
+ One label per bar. The percentages of a Table without rows are 0.
210
+
211
+ Examples
212
+ --------
213
+ >>> import numdaplot as ndp
214
+ >>> from numdaplot.plots.data.missing_cells import read_missing_counts
215
+ >>> from numdaplot.plots.drawing.missing_drawing import ONE_LINE_BAR_LABEL, format_bar_labels
216
+ >>> flats = ndp.Table.from_arrays({"price": ndp.Array.from_list([12.0, None])})
217
+ >>> format_bar_labels(read_missing_counts(flats, ndp.Measure.COUNT), ONE_LINE_BAR_LABEL)
218
+ ['1 (50.0 %)']
219
+ """
220
+ row_count = max(values.row_count, 1)
221
+ labels = list[str]()
222
+
223
+ for count in values.counts:
224
+ whole_count = int(count)
225
+ percent = whole_count * PERCENT_FACTOR / row_count
226
+ label = label_format.format(count=whole_count, percent=percent)
227
+ labels.append(label)
228
+
229
+ return labels
230
+
231
+
232
+ def find_axis_top(bar_top: float, label_height: float, axes_height: float) -> float:
233
+ """
234
+ Return the top of the axis of the values, high enough to leave the labels room above the highest bar.
235
+
236
+ .. versionadded:: 0.1.0
237
+
238
+ Parameters
239
+ ----------
240
+ bar_top
241
+ The highest value the axis must show, above 0.
242
+ label_height
243
+ The height in pixels the labels need.
244
+ axes_height
245
+ The height of the axes in pixels.
246
+
247
+ Returns
248
+ -------
249
+ float
250
+ The top of the axis, at most twice the highest value.
251
+
252
+ Examples
253
+ --------
254
+ >>> from numdaplot.plots.drawing.missing_drawing import find_axis_top
255
+ >>> find_axis_top(30.0, 40.0, 400.0)
256
+ 33.333333333333336
257
+ """
258
+ headroom_share = min(label_height / axes_height, HIGHEST_HEADROOM_SHARE)
259
+ axis_top = bar_top / (1 - headroom_share)
260
+
261
+ return axis_top
262
+
263
+
264
+ def draw_missing_map(axes: Axes, layer: ChartLayer) -> DrawnChart:
265
+ """
266
+ Draw each value of a Table as a cell, light gray when present and dark when missing.
267
+
268
+ The columns are side by side and the rows go down from the first one. When the axes have too few pixels for the
269
+ cells, a dark band marks at least one missing value among the cells it covers. A legend names the two colors and
270
+ gives the total of missing values, past the axes with ``LegendPosition.BEST``.
271
+
272
+ .. versionadded:: 0.1.0
273
+
274
+ Parameters
275
+ ----------
276
+ axes
277
+ The matplotlib axes drawn on.
278
+ layer
279
+ The chart of the map and where each value is missing.
280
+
281
+ Returns
282
+ -------
283
+ DrawnChart
284
+ ``Column`` and ``Row`` as labels, the title of the map, no grid lines, and the legend past the axes.
285
+
286
+ Examples
287
+ --------
288
+ >>> import numdaplot as ndp
289
+ >>> from matplotlib.figure import Figure
290
+ >>> from numdaplot.plots.chart_layer import ChartLayer
291
+ >>> from numdaplot.plots.charts.missing_map_chart import MissingMapChart
292
+ >>> from numdaplot.plots.data.missing_cells import read_missing_cells
293
+ >>> from numdaplot.plots.drawing.missing_drawing import draw_missing_map
294
+ >>> prices = ndp.Array.from_list([12.0, None])
295
+ >>> flats = ndp.Table.from_arrays({"price": prices})
296
+ >>> axes = Figure().add_subplot()
297
+ >>> drawn_chart = draw_missing_map(axes, ChartLayer(MissingMapChart(), read_missing_cells(flats)))
298
+ >>> axes.images[0].get_array().tolist()
299
+ [[0.0], [1.0]]
300
+ """
301
+ values = cast(ChartValues, layer.values)
302
+ grid = stack_columns(values.series)
303
+ shown_cells = fit_cells_to_axes(grid, axes, merge_cells)
304
+ cell_colors = ListedColormap([PRESENT_COLOR, MISSING_COLOR])
305
+ cell_limits = find_cell_limits(grid)
306
+ axes.imshow(
307
+ shown_cells,
308
+ cmap=cell_colors,
309
+ vmin=LOWEST_RATIO,
310
+ vmax=HIGHEST_RATIO,
311
+ aspect=CELL_ASPECT,
312
+ interpolation=CELL_INTERPOLATION,
313
+ extent=cell_limits,
314
+ )
315
+ place_column_names(axes, values.series)
316
+ place_whole_ticks(axes.yaxis, values.positions.values)
317
+ hide_frame(axes)
318
+ missing_total = int(grid.sum())
319
+ missing_label = MISSING_TOTAL_LABEL.format(missing_total=missing_total)
320
+ add_legend_swatch(axes, MISSING_COLOR, missing_label)
321
+ add_legend_swatch(axes, PRESENT_COLOR, PRESENT_LABEL)
322
+ drawn_chart = DrawnChart(COLUMN_LABEL, ROW_LABEL, False, GridAxes.NONE, None, title=MAP_TITLE, legend_outside=True)
323
+
324
+ return drawn_chart
325
+
326
+
327
+ def add_legend_swatch(axes: Axes, color_code: str, label: str) -> None:
328
+ """
329
+ Add an invisible patch of a color, which the legend shows with a thin border and its label.
330
+
331
+ .. versionadded:: 0.1.0
332
+
333
+ Parameters
334
+ ----------
335
+ axes
336
+ The matplotlib axes drawn on.
337
+ color_code
338
+ The ``#rrggbb`` code shown in the legend.
339
+ label
340
+ The name of the color in the legend.
341
+
342
+ Examples
343
+ --------
344
+ >>> from matplotlib.figure import Figure
345
+ >>> from numdaplot.plots.drawing.missing_drawing import add_legend_swatch
346
+ >>> axes = Figure().add_subplot()
347
+ >>> add_legend_swatch(axes, "#33415c", "Missing (3)")
348
+ >>> axes.get_legend_handles_labels()[1]
349
+ ['Missing (3)']
350
+ """
351
+ swatch = Rectangle(
352
+ LEGEND_SWATCH_CORNER,
353
+ LEGEND_SWATCH_SIZE,
354
+ LEGEND_SWATCH_SIZE,
355
+ facecolor=color_code,
356
+ edgecolor=MISSING_COLOR,
357
+ linewidth=LEGEND_SWATCH_EDGE_WIDTH,
358
+ label=label,
359
+ )
360
+ axes.add_patch(swatch)
@@ -0,0 +1,253 @@
1
+ """
2
+ Labels of a time axis, with a corner label giving the period of the drawn values.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ # The matplotlib stubs leave the arguments of the date functions and of the shared axes untyped.
8
+ # pyright: reportUnknownMemberType=false, reportUnknownVariableType=false
9
+
10
+ from typing import cast
11
+
12
+ from matplotlib.axes import Axes
13
+ from matplotlib.dates import AutoDateLocator, ConciseDateFormatter, num2date
14
+
15
+ # strftime turns each %% into %, so the corner label matplotlib writes is the format to read the period with.
16
+ PERIOD_FORMATS = ["", "%%Y", "%%Y-%%b", "%%Y-%%b-%%d", "%%Y-%%b-%%d", "%%Y-%%b-%%d %%H:%%M"]
17
+ PERIOD_TEXT = "{start} to {stop}"
18
+
19
+
20
+ class MomentPeriodFormatter(ConciseDateFormatter):
21
+ """
22
+ The concise labels of matplotlib, with a corner label giving the period of the visible values.
23
+
24
+ matplotlib writes the date of the last tick in that corner, which can be a month without any value.
25
+
26
+ .. versionadded:: 0.1.0
27
+
28
+ Parameters
29
+ ----------
30
+ locator
31
+ The locator choosing the ticks of the axis.
32
+ axes
33
+ The matplotlib axes drawn on.
34
+ on_vertical_axis
35
+ True when the moments are on the vertical axis.
36
+
37
+ Examples
38
+ --------
39
+ >>> import numpy
40
+ >>> from matplotlib.dates import AutoDateLocator
41
+ >>> from matplotlib.figure import Figure
42
+ >>> from numdaplot.plots.drawing.moment_period_formatter import MomentPeriodFormatter
43
+ >>> figure = Figure()
44
+ >>> axes = figure.add_subplot()
45
+ >>> days = numpy.array(["2019-03-01", "2019-03-31"], dtype="datetime64[ns]")
46
+ >>> _ = axes.plot(days, [1.0, 2.0])
47
+ >>> locator = AutoDateLocator()
48
+ >>> axes.xaxis.set_major_locator(locator)
49
+ >>> axes.xaxis.set_major_formatter(MomentPeriodFormatter(locator, axes, False))
50
+ >>> figure.draw_without_rendering()
51
+ >>> axes.xaxis.get_offset_text().get_text()
52
+ '2019-Mar'
53
+ """
54
+
55
+ def __init__(self, locator: AutoDateLocator, axes: Axes, on_vertical_axis: bool) -> None:
56
+ super().__init__(locator, offset_formats=PERIOD_FORMATS)
57
+ self.drawn_axes = axes
58
+ self.on_vertical_axis = on_vertical_axis
59
+
60
+ def get_offset(self) -> str:
61
+ """
62
+ Return the text of the corner label.
63
+
64
+ .. versionadded:: 0.1.0
65
+
66
+ Returns
67
+ -------
68
+ str
69
+ The period of the visible values, as one value or as two values separated by ``to``,
70
+ and an empty text when the ticks already give it.
71
+
72
+ Examples
73
+ --------
74
+ >>> import numpy
75
+ >>> from matplotlib.dates import AutoDateLocator
76
+ >>> from matplotlib.figure import Figure
77
+ >>> from numdaplot.plots.drawing.moment_period_formatter import MomentPeriodFormatter
78
+ >>> figure = Figure()
79
+ >>> axes = figure.add_subplot()
80
+ >>> days = numpy.array(["2019-03-15", "2019-05-15"], dtype="datetime64[ns]")
81
+ >>> _ = axes.plot(days, [1.0, 2.0])
82
+ >>> locator = AutoDateLocator()
83
+ >>> axes.xaxis.set_major_locator(locator)
84
+ >>> formatter = MomentPeriodFormatter(locator, axes, False)
85
+ >>> axes.xaxis.set_major_formatter(formatter)
86
+ >>> figure.draw_without_rendering()
87
+ >>> formatter.get_offset()
88
+ '2019-Mar to 2019-May'
89
+ """
90
+ period_format = super().get_offset()
91
+ if period_format == "":
92
+ return ""
93
+
94
+ start, stop = find_visible_period(self.drawn_axes, self.on_vertical_axis)
95
+ period_text = write_period(start, stop, period_format)
96
+
97
+ return period_text
98
+
99
+
100
+ def find_visible_period(axes: Axes, on_vertical_axis: bool) -> tuple[float, float]:
101
+ """
102
+ Return the first and the last visible coordinates holding values.
103
+
104
+ .. versionadded:: 0.1.0
105
+
106
+ Parameters
107
+ ----------
108
+ axes
109
+ The matplotlib axes drawn on.
110
+ on_vertical_axis
111
+ True when the moments are on the vertical axis.
112
+
113
+ Returns
114
+ -------
115
+ tuple[float, float]
116
+ The start and the stop of the visible values, or of the visible axis when it shows no value.
117
+
118
+ Examples
119
+ --------
120
+ >>> from matplotlib.figure import Figure
121
+ >>> from numdaplot.plots.drawing.moment_period_formatter import find_visible_period
122
+ >>> axes = Figure().add_subplot()
123
+ >>> _ = axes.plot([10.0, 20.0], [1.0, 2.0])
124
+ >>> find_visible_period(axes, False)
125
+ (10.0, 20.0)
126
+ """
127
+ view_start, view_stop = find_view_bounds(axes, on_vertical_axis)
128
+ data_start, data_stop = find_data_bounds(axes, on_vertical_axis)
129
+ visible_start = max(view_start, data_start)
130
+ visible_stop = min(view_stop, data_stop)
131
+ if visible_start > visible_stop:
132
+ return view_start, view_stop
133
+
134
+ return visible_start, visible_stop
135
+
136
+
137
+ def find_data_bounds(axes: Axes, on_vertical_axis: bool) -> tuple[float, float]:
138
+ """
139
+ Return the lowest and the highest coordinates of the values of axes and of the axes sharing their axis.
140
+
141
+ .. versionadded:: 0.1.0
142
+
143
+ Parameters
144
+ ----------
145
+ axes
146
+ The matplotlib axes drawn on.
147
+ on_vertical_axis
148
+ True when the moments are on the vertical axis.
149
+
150
+ Returns
151
+ -------
152
+ tuple[float, float]
153
+ The two bounds. The low bound is above the high bound without any value.
154
+
155
+ Examples
156
+ --------
157
+ >>> from matplotlib.figure import Figure
158
+ >>> from numdaplot.plots.drawing.moment_period_formatter import find_data_bounds
159
+ >>> axes = Figure().add_subplot()
160
+ >>> right_axes = axes.twinx()
161
+ >>> _ = axes.plot([10.0, 20.0], [1.0, 2.0])
162
+ >>> _ = right_axes.plot([15.0, 30.0], [1.0, 2.0])
163
+ >>> find_data_bounds(axes, False)
164
+ (10.0, 30.0)
165
+ """
166
+ shared_axes = axes.get_shared_y_axes() if on_vertical_axis else axes.get_shared_x_axes()
167
+ sibling_axes = cast(list[Axes], shared_axes.get_siblings(axes))
168
+ data_limits = [sibling.dataLim for sibling in sibling_axes]
169
+ low_bounds = [limits.y0 if on_vertical_axis else limits.x0 for limits in data_limits]
170
+ high_bounds = [limits.y1 if on_vertical_axis else limits.x1 for limits in data_limits]
171
+ lowest_bound = min(low_bounds)
172
+ highest_bound = max(high_bounds)
173
+ low_bound = float(lowest_bound)
174
+ high_bound = float(highest_bound)
175
+
176
+ return low_bound, high_bound
177
+
178
+
179
+ def find_view_bounds(axes: Axes, on_vertical_axis: bool) -> tuple[float, float]:
180
+ """
181
+ Return the lowest and the highest visible coordinates of an axis, even when it is inverted.
182
+
183
+ .. versionadded:: 0.1.0
184
+
185
+ Parameters
186
+ ----------
187
+ axes
188
+ The matplotlib axes drawn on.
189
+ on_vertical_axis
190
+ True for the vertical axis.
191
+
192
+ Returns
193
+ -------
194
+ tuple[float, float]
195
+ The two bounds.
196
+
197
+ Examples
198
+ --------
199
+ >>> from matplotlib.figure import Figure
200
+ >>> from numdaplot.plots.drawing.moment_period_formatter import find_view_bounds
201
+ >>> axes = Figure().add_subplot()
202
+ >>> axes.set_xlim(20.0, 10.0)
203
+ (20.0, 10.0)
204
+ >>> find_view_bounds(axes, False)
205
+ (10.0, 20.0)
206
+ """
207
+ first_bound, second_bound = axes.get_ybound() if on_vertical_axis else axes.get_xbound()
208
+ low_bound = float(first_bound)
209
+ high_bound = float(second_bound)
210
+
211
+ return low_bound, high_bound
212
+
213
+
214
+ def write_period(start: float, stop: float, period_format: str) -> str:
215
+ """
216
+ Return the text of a period, as one value when both ends read the same.
217
+
218
+ .. versionadded:: 0.1.0
219
+
220
+ Parameters
221
+ ----------
222
+ start
223
+ The matplotlib date number of the start.
224
+ stop
225
+ The matplotlib date number of the stop.
226
+ period_format
227
+ The strftime format of each end.
228
+
229
+ Returns
230
+ -------
231
+ str
232
+ The text of the period.
233
+
234
+ Examples
235
+ --------
236
+ >>> from datetime import date
237
+ >>> from matplotlib.dates import date2num
238
+ >>> from numdaplot.plots.drawing.moment_period_formatter import write_period
239
+ >>> write_period(date2num(date(2019, 3, 1)), date2num(date(2019, 3, 31)), "%Y-%b")
240
+ '2019-Mar'
241
+ >>> write_period(date2num(date(2019, 11, 1)), date2num(date(2020, 2, 15)), "%Y-%b")
242
+ '2019-Nov to 2020-Feb'
243
+ """
244
+ start_date = num2date(start)
245
+ stop_date = num2date(stop)
246
+ start_text = start_date.strftime(period_format)
247
+ stop_text = stop_date.strftime(period_format)
248
+ if start_text == stop_text:
249
+ return start_text
250
+
251
+ period_text = PERIOD_TEXT.format(start=start_text, stop=stop_text)
252
+
253
+ return period_text