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,143 @@
1
+ """
2
+ Checks of the column settings of a chart against the data it draws.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from numdaplot.arrays.array import Array
8
+ from numdaplot.errors.invalid_chart_data_error import InvalidChartDataError
9
+ from numdaplot.plots.data.array_values import read_array_values
10
+ from numdaplot.plots.data.chart_values import ChartValues
11
+ from numdaplot.plots.data.table_values import read_table_values
12
+ from numdaplot.tables.table import Table
13
+
14
+ TABLE_NAME = "a Table"
15
+ ARRAY_NAME = "an Array"
16
+ X_SETTING = "x"
17
+ Y_SETTING = "y"
18
+
19
+
20
+ def require_no_column_settings(chart_name: str, column_settings: dict[str, object]) -> None:
21
+ """
22
+ Check that a chart drawing an Array names no column.
23
+
24
+ .. versionadded:: 0.1.0
25
+
26
+ Parameters
27
+ ----------
28
+ chart_name
29
+ Name of the chart class, shown in the error message.
30
+ column_settings
31
+ Each column setting of the chart by name, such as ``{"x": None, "y": None}``.
32
+
33
+ Raises
34
+ ------
35
+ InvalidChartDataError
36
+ At the first setting that is not None.
37
+
38
+ Examples
39
+ --------
40
+ >>> import numdaplot as ndp
41
+ >>> from numdaplot.plots.data.chart_data import require_no_column_settings
42
+ >>> try:
43
+ ... require_no_column_settings("LineChart", {"x": "day", "y": None})
44
+ ... except ndp.InvalidChartDataError as error:
45
+ ... print(error)
46
+ LineChart takes no x for an Array.
47
+ """
48
+ for setting_name, setting_value in column_settings.items():
49
+ if setting_value is not None:
50
+ raise InvalidChartDataError(chart_name, setting_name, ARRAY_NAME, False)
51
+
52
+
53
+ def require_column_setting[SettingValue](
54
+ chart_name: str, setting_name: str, setting_value: SettingValue | None
55
+ ) -> SettingValue:
56
+ """
57
+ Check that a chart drawing a Table has a column setting it needs, and return it.
58
+
59
+ .. versionadded:: 0.1.0
60
+
61
+ Parameters
62
+ ----------
63
+ chart_name
64
+ Name of the chart class, shown in the error message.
65
+ setting_name
66
+ Name of the setting, such as ``y``.
67
+ setting_value
68
+ The value of the setting.
69
+
70
+ Returns
71
+ -------
72
+ SettingValue
73
+ The value, known not to be None.
74
+
75
+ Raises
76
+ ------
77
+ InvalidChartDataError
78
+ When the value is None.
79
+
80
+ Examples
81
+ --------
82
+ >>> import numdaplot as ndp
83
+ >>> from numdaplot.plots.data.chart_data import require_column_setting
84
+ >>> try:
85
+ ... require_column_setting("LineChart", "y", None)
86
+ ... except ndp.InvalidChartDataError as error:
87
+ ... print(error)
88
+ LineChart needs y for a Table.
89
+ """
90
+ if setting_value is None:
91
+ raise InvalidChartDataError(chart_name, setting_name, TABLE_NAME, True)
92
+
93
+ return setting_value
94
+
95
+
96
+ def read_chart_values(
97
+ data: Table | Array, x_name: str | None, y_names: list[str] | None, chart_name: str
98
+ ) -> ChartValues:
99
+ """
100
+ Return the positions and the series a line or bar chart draws from a Table or an Array.
101
+
102
+ .. versionadded:: 0.1.0
103
+
104
+ Parameters
105
+ ----------
106
+ data
107
+ The Table or the Array drawn.
108
+ x_name
109
+ The ``x`` column of a Table, None for its row numbers and for an Array.
110
+ y_names
111
+ The ``y`` columns of a Table, None for an Array.
112
+ chart_name
113
+ Name of the chart class, shown in error messages.
114
+
115
+ Returns
116
+ -------
117
+ ChartValues
118
+ The values read by ``read_table_values`` or ``read_array_values``.
119
+
120
+ Raises
121
+ ------
122
+ InvalidChartDataError
123
+ When a Table has no ``y`` columns, or an Array has ``x`` or ``y`` columns.
124
+
125
+ Examples
126
+ --------
127
+ >>> import numdaplot as ndp
128
+ >>> from numdaplot.plots.data.chart_data import read_chart_values
129
+ >>> prices = ndp.Array.from_list([12.0, 15.5])
130
+ >>> sales = ndp.Table.from_arrays({"price": prices})
131
+ >>> read_chart_values(sales, None, ["price"], "LineChart").value_name
132
+ 'price'
133
+ """
134
+ if isinstance(data, Array):
135
+ column_settings = dict[str, object]({X_SETTING: x_name, Y_SETTING: y_names})
136
+ require_no_column_settings(chart_name, column_settings)
137
+ array_values = read_array_values(data, chart_name)
138
+ return array_values
139
+
140
+ required_y_names = require_column_setting(chart_name, Y_SETTING, y_names)
141
+ table_values = read_table_values(data, x_name, required_y_names, chart_name)
142
+
143
+ return table_values
@@ -0,0 +1,109 @@
1
+ """
2
+ Values a chart draws, read from a Table or an Array.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+ from typing import Any
9
+
10
+ import numpy
11
+ from numpy.typing import NDArray
12
+
13
+ from numdaplot.data_types.type import Type
14
+ from numdaplot.plots.data.position_kind import PositionKind
15
+
16
+
17
+ @dataclass(frozen=True, eq=False)
18
+ class Positions:
19
+ """
20
+ The ``x`` values of a chart.
21
+
22
+ .. versionadded:: 0.1.0
23
+
24
+ Parameters
25
+ ----------
26
+ kind
27
+ Numbers, moments, texts or times of day.
28
+ values
29
+ One value per row: float64 numbers with NaN, datetime64[ns] clock times with NaT, texts, or float64 hours
30
+ since midnight with NaN.
31
+ name
32
+ The name of the ``x`` column, or None for row numbers.
33
+
34
+ Examples
35
+ --------
36
+ >>> import numpy
37
+ >>> from numdaplot.plots.data.chart_values import Positions
38
+ >>> from numdaplot.plots.data.position_kind import PositionKind
39
+ >>> Positions(PositionKind.NUMBERS, numpy.array([0.0, 1.0]), None).values
40
+ array([0., 1.])
41
+ """
42
+
43
+ kind: PositionKind
44
+ values: NDArray[Any]
45
+ name: str | None
46
+
47
+
48
+ @dataclass(frozen=True, eq=False)
49
+ class Series:
50
+ """
51
+ One series of values drawn by a chart, as numbers.
52
+
53
+ .. versionadded:: 0.1.0
54
+
55
+ Parameters
56
+ ----------
57
+ name
58
+ The name shown in the legend: the column name, or the column number of an Array.
59
+ values
60
+ One float64 number per row, NaN where the value is missing or not drawn. A time of day is its hours since
61
+ midnight, such as 15.5 for 15:30.
62
+
63
+ Examples
64
+ --------
65
+ >>> import numpy
66
+ >>> from numdaplot.plots.data.chart_values import Series
67
+ >>> Series("price", numpy.array([12.0, numpy.nan])).name
68
+ 'price'
69
+ """
70
+
71
+ name: str
72
+ values: NDArray[numpy.float64]
73
+
74
+
75
+ @dataclass(frozen=True, eq=False)
76
+ class ChartValues:
77
+ """
78
+ The positions and the series a chart draws.
79
+
80
+ .. versionadded:: 0.1.0
81
+
82
+ Parameters
83
+ ----------
84
+ positions
85
+ The ``x`` values.
86
+ series
87
+ The series of numbers, each with one value per position.
88
+ rows
89
+ The row numbers of the source kept for drawing, to read other columns of the same rows.
90
+ value_name
91
+ The default label of the axis of the series: the name of the single ``y`` column of a Table, None
92
+ otherwise.
93
+ value_type
94
+ The type of the first series, of the family of every series: numbers or times of day.
95
+
96
+ Examples
97
+ --------
98
+ >>> import numdaplot as ndp
99
+ >>> from numdaplot.plots.data.array_values import read_array_values
100
+ >>> grid = ndp.Array.from_list([[1.0, 2.0], [3.0, 4.0]])
101
+ >>> [series.name for series in read_array_values(grid, "LineChart").series]
102
+ ['0', '1']
103
+ """
104
+
105
+ positions: Positions
106
+ series: list[Series]
107
+ rows: NDArray[numpy.intp]
108
+ value_name: str | None
109
+ value_type: Type
@@ -0,0 +1,468 @@
1
+ """
2
+ Reading of the Table columns a chart draws.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ import numpy
10
+ from numpy.typing import NDArray
11
+
12
+ from numdaplot.data_types.time_of_day import read_times
13
+ from numdaplot.data_types.type import Type
14
+ from numdaplot.data_types.value_family import ValueFamily, find_family
15
+ from numdaplot.errors.incompatible_types_error import IncompatibleTypesError
16
+ from numdaplot.plots.charts.box_chart import BoxChart
17
+ from numdaplot.plots.charts.histogram_chart import HistogramChart
18
+ from numdaplot.plots.charts.line_chart import LineChart
19
+ from numdaplot.plots.charts.scatter_chart import ScatterChart
20
+ from numdaplot.plots.data.position_kind import PositionKind
21
+ from numdaplot.tables.frames.column import Column
22
+ from numdaplot.tables.frames.column_values import find_column_missing, find_column_type
23
+ from numdaplot.tables.frames.named_column_errors import NamedColumnErrors
24
+ from numdaplot.tables.frames.time_zones import find_column_time_zone
25
+
26
+ POSITION_KINDS = {
27
+ ValueFamily.NUMBER: PositionKind.NUMBERS,
28
+ ValueFamily.MOMENT: PositionKind.MOMENTS,
29
+ ValueFamily.TEXT: PositionKind.TEXTS,
30
+ ValueFamily.BOOL: PositionKind.TEXTS,
31
+ ValueFamily.TIME: PositionKind.TIMES,
32
+ }
33
+ NUMBER_FAMILIES = frozenset({ValueFamily.NUMBER})
34
+ VALUE_FAMILIES = frozenset({ValueFamily.NUMBER, ValueFamily.TIME})
35
+ TIME_VALUE_CHARTS = frozenset({LineChart.__name__, ScatterChart.__name__, HistogramChart.__name__, BoxChart.__name__})
36
+ LABEL_FAMILIES = frozenset({ValueFamily.TEXT, ValueFamily.BOOL, ValueFamily.TIME})
37
+ HOUR_LABEL_PATTERN = "%H:%M"
38
+ MICROSECONDS_PER_HOUR = 3_600_000_000
39
+ TIME_DTYPE = numpy.dtype("timedelta64[us]")
40
+ MOMENT_DTYPE = numpy.dtype("datetime64[ns]")
41
+ TEXT_DTYPE = "string"
42
+ PYTHON_OBJECT_DTYPE = numpy.dtype(object)
43
+
44
+
45
+ def require_column_family(column: Column, accepted_families: frozenset[ValueFamily], chart_name: str) -> ValueFamily:
46
+ """
47
+ Check that a column holds values a chart draws, and return their family.
48
+
49
+ .. versionadded:: 0.1.0
50
+
51
+ Parameters
52
+ ----------
53
+ column
54
+ A Table column.
55
+ accepted_families
56
+ The families the chart draws in this column.
57
+ chart_name
58
+ Name of the chart class, shown in the error message.
59
+
60
+ Returns
61
+ -------
62
+ ValueFamily
63
+ The family of the column.
64
+
65
+ Raises
66
+ ------
67
+ IncompatibleTypesError
68
+ When the column holds values of another family, such as durations.
69
+
70
+ Examples
71
+ --------
72
+ >>> import pandas
73
+ >>> import numdaplot as ndp
74
+ >>> from numdaplot.plots.data.column_reading import NUMBER_FAMILIES, require_column_family
75
+ >>> try:
76
+ ... require_column_family(pandas.Series([True], dtype="boolean"), NUMBER_FAMILIES, "LineChart")
77
+ ... except ndp.IncompatibleTypesError as error:
78
+ ... print(error)
79
+ Cannot apply LineChart to BOOL.
80
+ """
81
+ column_type = find_column_type(column)
82
+ family = find_family(column_type)
83
+ if family not in accepted_families:
84
+ with NamedColumnErrors(column):
85
+ raise IncompatibleTypesError(chart_name, [column_type.name])
86
+
87
+ return family
88
+
89
+
90
+ def read_numbers(column: Column, chart_name: str) -> NDArray[numpy.float64]:
91
+ """
92
+ Return a column of numbers as float64 values, NaN where a value is missing.
93
+
94
+ .. versionadded:: 0.1.0
95
+
96
+ Parameters
97
+ ----------
98
+ column
99
+ A Table column.
100
+ chart_name
101
+ Name of the chart class, shown in the error message.
102
+
103
+ Returns
104
+ -------
105
+ NDArray[numpy.float64]
106
+ One number per row.
107
+
108
+ Raises
109
+ ------
110
+ IncompatibleTypesError
111
+ When the column does not hold numbers.
112
+
113
+ Examples
114
+ --------
115
+ >>> import pandas
116
+ >>> from numdaplot.plots.data.column_reading import read_numbers
117
+ >>> read_numbers(pandas.Series([3, None], dtype="Int64"), "LineChart")
118
+ array([ 3., nan])
119
+ """
120
+ require_column_family(column, NUMBER_FAMILIES, chart_name)
121
+ numbers = column.to_numpy(dtype=numpy.float64, na_value=numpy.nan)
122
+
123
+ return numbers
124
+
125
+
126
+ def find_value_families(chart_name: str) -> frozenset[ValueFamily]:
127
+ """
128
+ Return the families of the values a chart draws: numbers, and times of day for the charts measuring them.
129
+
130
+ .. versionadded:: 0.1.0
131
+
132
+ Parameters
133
+ ----------
134
+ chart_name
135
+ Name of the chart class.
136
+
137
+ Returns
138
+ -------
139
+ frozenset[ValueFamily]
140
+ Numbers and times of day for a LineChart, a ScatterChart, a HistogramChart or a BoxChart, numbers only
141
+ otherwise.
142
+
143
+ Examples
144
+ --------
145
+ >>> from numdaplot.plots.data.column_reading import find_value_families
146
+ >>> sorted(family.name for family in find_value_families("BoxChart"))
147
+ ['NUMBER', 'TIME']
148
+ >>> sorted(family.name for family in find_value_families("BarChart"))
149
+ ['NUMBER']
150
+ """
151
+ if chart_name in TIME_VALUE_CHARTS:
152
+ return VALUE_FAMILIES
153
+
154
+ return NUMBER_FAMILIES
155
+
156
+
157
+ def read_values(column: Column, chart_name: str) -> NDArray[numpy.float64]:
158
+ """
159
+ Return a column of values a chart draws as float64 numbers, a time of day being its hours since midnight.
160
+
161
+ .. versionadded:: 0.1.0
162
+
163
+ Parameters
164
+ ----------
165
+ column
166
+ A Table column.
167
+ chart_name
168
+ Name of the chart class, shown in the error message.
169
+
170
+ Returns
171
+ -------
172
+ NDArray[numpy.float64]
173
+ One number per row, NaN where a value is missing.
174
+
175
+ Raises
176
+ ------
177
+ IncompatibleTypesError
178
+ When the column does not hold numbers, or times of day for a chart measuring them.
179
+
180
+ Examples
181
+ --------
182
+ >>> import numpy
183
+ >>> import pandas
184
+ >>> from numdaplot.plots.data.column_reading import read_values
185
+ >>> read_values(pandas.Series(numpy.array([55800000000], dtype="timedelta64[us]")), "BoxChart")
186
+ array([15.5])
187
+ """
188
+ value_families = find_value_families(chart_name)
189
+ family = require_column_family(column, value_families, chart_name)
190
+ if family == ValueFamily.TIME:
191
+ hours = read_hours(column)
192
+ return hours
193
+
194
+ numbers = read_numbers(column, chart_name)
195
+
196
+ return numbers
197
+
198
+
199
+ def require_same_family(column: Column, value_type: Type, chart_name: str) -> None:
200
+ """
201
+ Check that a column holds values of the family of the first column a chart draws on the same axis.
202
+
203
+ .. versionadded:: 0.1.0
204
+
205
+ Parameters
206
+ ----------
207
+ column
208
+ A Table column.
209
+ value_type
210
+ The type of the first column.
211
+ chart_name
212
+ Name of the chart class, shown in the error message.
213
+
214
+ Raises
215
+ ------
216
+ IncompatibleTypesError
217
+ When one holds numbers and the other times of day.
218
+
219
+ Examples
220
+ --------
221
+ >>> import numpy
222
+ >>> import pandas
223
+ >>> import numdaplot as ndp
224
+ >>> from numdaplot.plots.data.column_reading import require_same_family
225
+ >>> counts = pandas.Series([3.0], name="count")
226
+ >>> try:
227
+ ... require_same_family(counts, ndp.Type.TIME, "BoxChart")
228
+ ... except ndp.IncompatibleTypesError as error:
229
+ ... print(error)
230
+ Cannot apply BoxChart to the FLOAT64 column 'count' and TIME.
231
+ """
232
+ column_type = find_column_type(column)
233
+ column_family = find_family(column_type)
234
+ value_family = find_family(value_type)
235
+ if column_family != value_family:
236
+ with NamedColumnErrors(column):
237
+ raise IncompatibleTypesError(chart_name, [column_type.name, value_type.name])
238
+
239
+
240
+ def read_texts(column: Column, chart_name: str) -> NDArray[Any]:
241
+ """
242
+ Return a column of texts, categories, booleans or times of day as Python texts, None where a value is missing.
243
+
244
+ A time of day is written ``HH:MM``.
245
+
246
+ .. versionadded:: 0.1.0
247
+
248
+ Parameters
249
+ ----------
250
+ column
251
+ A Table column.
252
+ chart_name
253
+ Name of the chart class, shown in the error message.
254
+
255
+ Returns
256
+ -------
257
+ NDArray
258
+ One text per row, in a numpy array of Python objects.
259
+
260
+ Raises
261
+ ------
262
+ IncompatibleTypesError
263
+ When the column does not hold texts.
264
+
265
+ Examples
266
+ --------
267
+ >>> import pandas
268
+ >>> from numdaplot.plots.data.column_reading import read_texts
269
+ >>> read_texts(pandas.Series(["Paris", None], dtype="string"), "BarChart")
270
+ array(['Paris', None], dtype=object)
271
+ """
272
+ family = require_column_family(column, LABEL_FAMILIES, chart_name)
273
+ if family == ValueFamily.TIME:
274
+ hour_texts = write_hour_labels(column)
275
+ return hour_texts
276
+
277
+ text_column = column.astype(TEXT_DTYPE)
278
+ text_values = text_column.tolist()
279
+ missing = find_column_missing(column)
280
+ value_pairs = zip(text_values, missing, strict=True)
281
+ present_texts = [None if is_missing else text for text, is_missing in value_pairs]
282
+ texts = numpy.array(present_texts, dtype=PYTHON_OBJECT_DTYPE)
283
+
284
+ return texts
285
+
286
+
287
+ def read_moments(column: Column) -> NDArray[numpy.datetime64]:
288
+ """
289
+ Return a column of dates or datetimes as the clock times shown in its time zone, NaT where a value is missing.
290
+
291
+ .. versionadded:: 0.1.0
292
+
293
+ Parameters
294
+ ----------
295
+ column
296
+ A date or datetime column.
297
+
298
+ Returns
299
+ -------
300
+ NDArray[numpy.datetime64]
301
+ One datetime64[ns] value per row, without time zone.
302
+
303
+ Examples
304
+ --------
305
+ >>> import pandas
306
+ >>> from numdaplot.plots.data.column_reading import read_moments
307
+ >>> utc_times = pandas.Series(pandas.to_datetime(["2026-07-01 10:30"])).dt.tz_localize("UTC")
308
+ >>> read_moments(utc_times.dt.tz_convert("Europe/Paris"))
309
+ array(['2026-07-01T12:30:00.000000000'], dtype='datetime64[ns]')
310
+ """
311
+ clock_times = column
312
+ time_zone = find_column_time_zone(column)
313
+ if time_zone is not None:
314
+ clock_times = column.dt.tz_localize(None)
315
+
316
+ moments = clock_times.to_numpy(dtype=MOMENT_DTYPE)
317
+
318
+ return moments
319
+
320
+
321
+ def read_positions(column: Column, chart_name: str) -> tuple[PositionKind, NDArray[Any]]:
322
+ """
323
+ Return the ``x`` values of a chart read from a column, with their kind.
324
+
325
+ .. versionadded:: 0.1.0
326
+
327
+ Parameters
328
+ ----------
329
+ column
330
+ A Table column of numbers, dates, datetimes or texts.
331
+ chart_name
332
+ Name of the chart class, shown in the error message.
333
+
334
+ Returns
335
+ -------
336
+ tuple[PositionKind, NDArray]
337
+ The kind and the values, read by ``read_numbers``, ``read_moments`` or ``read_texts``.
338
+
339
+ Raises
340
+ ------
341
+ IncompatibleTypesError
342
+ When the column holds durations.
343
+
344
+ Examples
345
+ --------
346
+ >>> import pandas
347
+ >>> from numdaplot.plots.data.column_reading import read_positions
348
+ >>> read_positions(pandas.Series(["Paris"], dtype="string"), "BarChart")
349
+ (<PositionKind.TEXTS: 3>, array(['Paris'], dtype=object))
350
+ """
351
+ accepted_families = frozenset(POSITION_KINDS)
352
+ family = require_column_family(column, accepted_families, chart_name)
353
+ kind = POSITION_KINDS[family]
354
+ if kind == PositionKind.NUMBERS:
355
+ numbers = read_numbers(column, chart_name)
356
+ return kind, numbers
357
+
358
+ if kind == PositionKind.MOMENTS:
359
+ moments = read_moments(column)
360
+ return kind, moments
361
+
362
+ if kind == PositionKind.TIMES:
363
+ hours = read_hours(column)
364
+ return kind, hours
365
+
366
+ texts = read_texts(column, chart_name)
367
+
368
+ return kind, texts
369
+
370
+
371
+ def read_hours(column: Column) -> NDArray[numpy.float64]:
372
+ """
373
+ Return a column of times of day as the hours since midnight, NaN where a time is missing.
374
+
375
+ .. versionadded:: 0.1.0
376
+
377
+ Parameters
378
+ ----------
379
+ column
380
+ A Table column of times of day.
381
+
382
+ Returns
383
+ -------
384
+ NDArray[numpy.float64]
385
+ The hours, such as 15.5 for 15:30.
386
+
387
+ Examples
388
+ --------
389
+ >>> import numpy
390
+ >>> import pandas
391
+ >>> from numdaplot.plots.data.column_reading import read_hours
392
+ >>> read_hours(pandas.Series(numpy.array([55800000000, "NaT"], dtype="timedelta64[us]")))
393
+ array([15.5, nan])
394
+ """
395
+ stored_times = column.to_numpy(dtype=TIME_DTYPE)
396
+ hours = count_hours(stored_times)
397
+
398
+ return hours
399
+
400
+
401
+ def count_hours(stored_times: NDArray[numpy.timedelta64]) -> NDArray[numpy.float64]:
402
+ """
403
+ Return stored times of day as the hours since midnight, NaN where a time is missing.
404
+
405
+ .. versionadded:: 0.1.0
406
+
407
+ Parameters
408
+ ----------
409
+ stored_times
410
+ Times of day as ``timedelta64[us]`` values since midnight, of any shape.
411
+
412
+ Returns
413
+ -------
414
+ NDArray[numpy.float64]
415
+ The hours, of the same shape, such as 15.5 for 15:30.
416
+
417
+ Examples
418
+ --------
419
+ >>> import numpy
420
+ >>> from numdaplot.plots.data.column_reading import count_hours
421
+ >>> count_hours(numpy.array([[55800000000, "NaT"]], dtype="timedelta64[us]"))
422
+ array([[15.5, nan]])
423
+ """
424
+ missing = numpy.isnat(stored_times)
425
+ microseconds = stored_times.astype(numpy.float64)
426
+ hours = microseconds / MICROSECONDS_PER_HOUR
427
+ present_hours = numpy.where(missing, numpy.nan, hours)
428
+
429
+ return present_hours
430
+
431
+
432
+ def write_hour_labels(column: Column) -> NDArray[Any]:
433
+ """
434
+ Return a column of times of day as ``HH:MM`` texts, None where a time is missing.
435
+
436
+ .. versionadded:: 0.1.0
437
+
438
+ Parameters
439
+ ----------
440
+ column
441
+ A Table column of times of day.
442
+
443
+ Returns
444
+ -------
445
+ NDArray
446
+ One text per row, in a numpy array of Python objects.
447
+
448
+ Examples
449
+ --------
450
+ >>> import numpy
451
+ >>> import pandas
452
+ >>> from numdaplot.plots.data.column_reading import write_hour_labels
453
+ >>> write_hour_labels(pandas.Series(numpy.array([55800000000, "NaT"], dtype="timedelta64[us]")))
454
+ array(['15:30', None], dtype=object)
455
+ """
456
+ stored_times = column.to_numpy(dtype=TIME_DTYPE)
457
+ times = read_times(stored_times)
458
+ hour_labels = list[str | None]()
459
+ for time_of_day in times:
460
+ hour_label = None
461
+ if time_of_day is not None:
462
+ hour_label = time_of_day.strftime(HOUR_LABEL_PATTERN)
463
+
464
+ hour_labels.append(hour_label)
465
+
466
+ label_values = numpy.array(hour_labels, dtype=PYTHON_OBJECT_DTYPE)
467
+
468
+ return label_values