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,63 @@
1
+ """
2
+ Values of a HeatmapChart.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from numdaplot.arrays.array import Array
8
+ from numdaplot.plots.charts.heatmap_chart import HeatmapChart
9
+ from numdaplot.plots.data.array_values import read_array_values
10
+ from numdaplot.plots.data.chart_data import require_column_setting, require_no_column_settings
11
+ from numdaplot.plots.data.chart_values import ChartValues
12
+ from numdaplot.plots.data.table_values import read_table_values
13
+ from numdaplot.tables.table import Table
14
+
15
+ CHART_NAME = "HeatmapChart"
16
+ COLUMNS_SETTING = "columns"
17
+ LABELS_SETTING = "labels"
18
+
19
+
20
+ def read_heatmap_values(data: Table | Array, chart: HeatmapChart) -> ChartValues:
21
+ """
22
+ Return the row labels and the columns a HeatmapChart draws.
23
+
24
+ .. versionadded:: 0.1.0
25
+
26
+ Parameters
27
+ ----------
28
+ data
29
+ The Table or the Array drawn.
30
+ chart
31
+ The ``columns`` and the ``labels`` of a Table.
32
+
33
+ Returns
34
+ -------
35
+ ChartValues
36
+ The row labels as positions, and one series per column.
37
+
38
+ Raises
39
+ ------
40
+ InvalidChartDataError
41
+ When a Table has no ``columns``, or an Array has ``columns`` or ``labels``.
42
+
43
+ Examples
44
+ --------
45
+ >>> import numdaplot as ndp
46
+ >>> from numdaplot.plots.data.heatmap_values import read_heatmap_values
47
+ >>> grid = ndp.Array.from_list([[1.0, 2.0], [3.0, 4.0]])
48
+ >>> try:
49
+ ... read_heatmap_values(grid, ndp.HeatmapChart(labels="city"))
50
+ ... except ndp.InvalidChartDataError as error:
51
+ ... print(error)
52
+ HeatmapChart takes no labels for an Array.
53
+ """
54
+ if isinstance(data, Array):
55
+ column_settings = dict[str, object]({COLUMNS_SETTING: chart.columns, LABELS_SETTING: chart.labels})
56
+ require_no_column_settings(CHART_NAME, column_settings)
57
+ array_values = read_array_values(data, CHART_NAME)
58
+ return array_values
59
+
60
+ column_names = require_column_setting(CHART_NAME, COLUMNS_SETTING, chart.columns)
61
+ table_values = read_table_values(data, chart.labels, column_names, CHART_NAME)
62
+
63
+ return table_values
@@ -0,0 +1,165 @@
1
+ """
2
+ Missing values of a Table, read to be drawn.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ import numpy
10
+ from numpy.typing import NDArray
11
+
12
+ from numdaplot.data_types.type import Type
13
+ from numdaplot.plots.data.chart_values import ChartValues, Positions, Series
14
+ from numdaplot.plots.data.position_kind import PositionKind
15
+ from numdaplot.positions.axis import Axis
16
+ from numdaplot.ratios.measure import Measure
17
+ from numdaplot.tables.missing.missing_count import MissingCount
18
+ from numdaplot.tables.missing.missing_counts import (
19
+ COLUMN_NAMES_COLUMN,
20
+ MEASURE_COLUMN_NAMES,
21
+ count_frame_missing,
22
+ find_frame_missing,
23
+ )
24
+ from numdaplot.tables.table import Table
25
+ from numdaplot.tables.table_data import read_stored_frame
26
+
27
+ MEASURE_LABELS = {
28
+ Measure.COUNT: "Missing count",
29
+ Measure.RATIO: "Missing ratio",
30
+ }
31
+ FLOAT_DTYPE = numpy.dtype(numpy.float64)
32
+ COLUMN_SUM_AXIS = 0
33
+ COLUMN_AXIS_NAME = "Column"
34
+ TEXT_DTYPE = numpy.dtype(object)
35
+
36
+
37
+ @dataclass(frozen=True, eq=False)
38
+ class MissingCounts(ChartValues):
39
+ """
40
+ The bars of the missing values of each column, with what their labels show.
41
+
42
+ .. versionadded:: 0.1.0
43
+
44
+ Parameters
45
+ ----------
46
+ positions
47
+ The column names.
48
+ series
49
+ The single series of bars, in the chosen measure.
50
+ rows
51
+ The number of each column.
52
+ value_name
53
+ The label of the axis of the values.
54
+ value_type
55
+ ``FLOAT64``, the type of the counts and the shares.
56
+ counts
57
+ The number of missing values of each column.
58
+ row_count
59
+ The number of rows of the Table.
60
+
61
+ Examples
62
+ --------
63
+ >>> import numdaplot as ndp
64
+ >>> from numdaplot.plots.data.missing_cells import read_missing_counts
65
+ >>> prices = ndp.Array.from_list([12.0, None])
66
+ >>> flats = ndp.Table.from_arrays({"price": prices})
67
+ >>> read_missing_counts(flats, ndp.Measure.RATIO).counts
68
+ array([1.])
69
+ """
70
+
71
+ counts: NDArray[numpy.float64]
72
+ row_count: int
73
+
74
+
75
+ def read_missing_counts(table: Table, measure: Measure) -> MissingCounts:
76
+ """
77
+ Return the number or the share of missing values of each column of a Table, as one series of bars.
78
+
79
+ .. versionadded:: 0.1.0
80
+
81
+ Parameters
82
+ ----------
83
+ table
84
+ The Table counted.
85
+ measure
86
+ ``Measure.COUNT`` for the number of missing values, ``Measure.RATIO`` for their share.
87
+
88
+ Returns
89
+ -------
90
+ MissingCounts
91
+ The column names as text positions, the chosen measure as a single series, ``"Missing count"`` or
92
+ ``"Missing ratio"`` as label of the axis of the values, and the counts for the labels of the bars.
93
+
94
+ Examples
95
+ --------
96
+ >>> import numdaplot as ndp
97
+ >>> from numdaplot.plots.data.missing_cells import read_missing_counts
98
+ >>> prices = ndp.Array.from_list([12.0, None])
99
+ >>> rooms = ndp.Array.from_list([2, 3])
100
+ >>> flats = ndp.Table.from_arrays({"price": prices, "rooms": rooms})
101
+ >>> read_missing_counts(flats, ndp.Measure.RATIO).series[0].values
102
+ array([0.5, 0. ])
103
+ """
104
+ frame = read_stored_frame(table)
105
+ missing_count = MissingCount(measure=measure)
106
+ counts_frame = count_frame_missing(frame, missing_count, Axis.EACH_COLUMN)
107
+ count_name = MEASURE_COLUMN_NAMES[measure]
108
+ column_names = counts_frame[COLUMN_NAMES_COLUMN].to_numpy(dtype=TEXT_DTYPE)
109
+ shown_values = counts_frame[count_name].to_numpy(dtype=FLOAT_DTYPE, na_value=numpy.nan)
110
+ missing_grid = find_frame_missing(frame)
111
+ counts = missing_grid.sum(axis=COLUMN_SUM_AXIS, dtype=FLOAT_DTYPE)
112
+ row_count = len(frame)
113
+ column_count = len(column_names)
114
+ rows = numpy.arange(column_count)
115
+ positions = Positions(PositionKind.TEXTS, column_names, COLUMN_AXIS_NAME)
116
+ count_series = Series(count_name, shown_values)
117
+ measure_label = MEASURE_LABELS[measure]
118
+ count_values = MissingCounts(positions, [count_series], rows, measure_label, Type.FLOAT64, counts, row_count)
119
+
120
+ return count_values
121
+
122
+
123
+ def read_missing_cells(table: Table) -> ChartValues:
124
+ """
125
+ Return where the values of a Table are missing, 1 for a missing value and 0 for a present one.
126
+
127
+ .. versionadded:: 0.1.0
128
+
129
+ Parameters
130
+ ----------
131
+ table
132
+ The Table read.
133
+
134
+ Returns
135
+ -------
136
+ ChartValues
137
+ The row numbers as positions, and one series per column.
138
+
139
+ Examples
140
+ --------
141
+ >>> import numdaplot as ndp
142
+ >>> from numdaplot.plots.data.missing_cells import read_missing_cells
143
+ >>> prices = ndp.Array.from_list([12.0, None])
144
+ >>> flats = ndp.Table.from_arrays({"price": prices})
145
+ >>> read_missing_cells(flats).series[0].values
146
+ array([0., 1.])
147
+ """
148
+ frame = read_stored_frame(table)
149
+ missing_grid = find_frame_missing(frame)
150
+ cells = missing_grid.astype(FLOAT_DTYPE)
151
+ column_names = frame.columns.tolist()
152
+ row_count = len(frame)
153
+ rows = numpy.arange(row_count)
154
+ row_numbers = rows.astype(FLOAT_DTYPE)
155
+ positions = Positions(PositionKind.NUMBERS, row_numbers, None)
156
+ series = list[Series]()
157
+
158
+ for i, column_name in enumerate(column_names):
159
+ column_cells = cells[:, i]
160
+ column_series = Series(column_name, column_cells)
161
+ series.append(column_series)
162
+
163
+ cell_values = ChartValues(positions, series, rows, None, Type.FLOAT64)
164
+
165
+ return cell_values
@@ -0,0 +1,215 @@
1
+ """
2
+ Values a PieChart shares out, read from a Table.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ import warnings
8
+ from typing import Any
9
+
10
+ import numpy
11
+ import pandas
12
+ from numpy.typing import NDArray
13
+
14
+ from numdaplot.errors.empty_total_error import EmptyTotalError
15
+ from numdaplot.errors.missing_value_error import MissingValueError
16
+ from numdaplot.errors.out_of_domain_error import OutOfDomainError
17
+ from numdaplot.errors.readability_warning import ReadabilityWarning
18
+ from numdaplot.plots.charts.pie_chart import PieChart
19
+ from numdaplot.plots.data.chart_values import ChartValues, Positions, Series
20
+ from numdaplot.plots.data.column_reading import read_numbers, read_texts
21
+ from numdaplot.plots.data.position_kind import PositionKind
22
+ from numdaplot.plots.data.unique_labels import require_unique_labels
23
+ from numdaplot.tables.columns.column_names import require_known_columns
24
+ from numdaplot.tables.frames.column_values import find_column_type
25
+ from numdaplot.tables.table import Table
26
+ from numdaplot.tables.table_data import read_stored_frame
27
+
28
+ CHART_NAME = "PieChart"
29
+ MAXIMUM_READABLE_SLICES = 5
30
+ READABILITY_START = "A PieChart with {slice_count} slices is hard to read."
31
+ READABILITY_ADVICE = "Try ndp.Plot.bar with a BarChart, it may compare them better."
32
+ READABILITY_MESSAGE = f"{READABILITY_START} {READABILITY_ADVICE}"
33
+ # The warning points at the line calling Plot.pie, above warn_slice_count, read_pie_values, Plot.pie and its check.
34
+ READABILITY_STACK_LEVEL = 5
35
+
36
+
37
+ def read_pie_values(table: Table, chart: PieChart) -> ChartValues:
38
+ """
39
+ Return the labels and the values of the slices of a PieChart, after checking that they can be shared out.
40
+
41
+ .. versionadded:: 0.1.0
42
+
43
+ Parameters
44
+ ----------
45
+ table
46
+ The Table drawn.
47
+ chart
48
+ The ``labels`` and ``values`` columns.
49
+
50
+ Returns
51
+ -------
52
+ ChartValues
53
+ The labels as text positions, and the values as a single series.
54
+
55
+ Raises
56
+ ------
57
+ ColumnNotFoundError
58
+ When a column does not exist.
59
+ IncompatibleTypesError
60
+ When ``labels`` does not hold texts, or ``values`` does not hold numbers.
61
+ MissingValueError
62
+ When a label or a value is missing.
63
+ OutOfDomainError
64
+ When a value is negative.
65
+ EmptyTotalError
66
+ When the values add up to 0.
67
+ DuplicateLabelError
68
+ When two slices have the same label.
69
+
70
+ Warns
71
+ -----
72
+ ReadabilityWarning
73
+ When there are more than 5 slices.
74
+
75
+ Examples
76
+ --------
77
+ >>> import numdaplot as ndp
78
+ >>> from numdaplot.plots.data.pie_values import read_pie_values
79
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon"])
80
+ >>> sales = ndp.Array.from_list([120.0, 80.0])
81
+ >>> shares = ndp.Table.from_arrays({"city": cities, "sales": sales})
82
+ >>> read_pie_values(shares, ndp.PieChart(labels="city", values="sales")).series[0].values
83
+ array([120., 80.])
84
+ """
85
+ labels_name = chart.labels
86
+ values_name = chart.values
87
+ frame = read_stored_frame(table)
88
+ known_names = frame.columns.tolist()
89
+ require_known_columns([labels_name, values_name], known_names)
90
+ labels = read_texts(frame[labels_name], CHART_NAME)
91
+ numbers = read_numbers(frame[values_name], CHART_NAME)
92
+ require_present_values(labels, labels_name)
93
+ require_present_values(numbers, values_name)
94
+ require_unique_labels(labels)
95
+ require_shares(numbers, values_name)
96
+ slice_count = len(labels)
97
+ warn_slice_count(slice_count)
98
+ rows = numpy.arange(slice_count)
99
+ positions = Positions(PositionKind.TEXTS, labels, labels_name)
100
+ values_series = Series(values_name, numbers)
101
+ values_column = frame[values_name]
102
+ values_type = find_column_type(values_column)
103
+ pie_values = ChartValues(positions, [values_series], rows, values_name, values_type)
104
+
105
+ return pie_values
106
+
107
+
108
+ def require_present_values(values: NDArray[Any], column_name: str) -> None:
109
+ """
110
+ Check that a column drawn by a PieChart has no missing value.
111
+
112
+ .. versionadded:: 0.1.0
113
+
114
+ Parameters
115
+ ----------
116
+ values
117
+ The labels, None where missing, or the numbers, NaN where missing.
118
+ column_name
119
+ The column read, shown in the error message.
120
+
121
+ Raises
122
+ ------
123
+ MissingValueError
124
+ When a value is missing.
125
+
126
+ Examples
127
+ --------
128
+ >>> import numpy
129
+ >>> import numdaplot as ndp
130
+ >>> from numdaplot.plots.data.pie_values import require_present_values
131
+ >>> try:
132
+ ... require_present_values(numpy.array([120.0, numpy.nan]), "sales")
133
+ ... except ndp.MissingValueError as error:
134
+ ... print(error)
135
+ PieChart cannot draw a missing value, found one in 'sales'.
136
+ """
137
+ missing = pandas.isna(values)
138
+ has_missing = bool(missing.any())
139
+ if has_missing:
140
+ raise MissingValueError(CHART_NAME, column_name)
141
+
142
+
143
+ def require_shares(numbers: NDArray[numpy.float64], column_name: str) -> None:
144
+ """
145
+ Check that the values of a PieChart can be shared out: none is negative and their total is above 0.
146
+
147
+ .. versionadded:: 0.1.0
148
+
149
+ Parameters
150
+ ----------
151
+ numbers
152
+ The value of each slice, none missing.
153
+ column_name
154
+ The column of the values, shown in the error message.
155
+
156
+ Raises
157
+ ------
158
+ OutOfDomainError
159
+ At the first negative value.
160
+ EmptyTotalError
161
+ When the values add up to 0.
162
+
163
+ Examples
164
+ --------
165
+ >>> import numpy
166
+ >>> import numdaplot as ndp
167
+ >>> from numdaplot.plots.data.pie_values import require_shares
168
+ >>> try:
169
+ ... require_shares(numpy.array([120.0, -3.0]), "sales")
170
+ ... except ndp.OutOfDomainError as error:
171
+ ... print(error)
172
+ PieChart is not defined for -3.0.
173
+ """
174
+ negative_numbers = numbers[numbers < 0]
175
+ negative_count = len(negative_numbers)
176
+ if negative_count > 0:
177
+ first_negative = float(negative_numbers[0])
178
+ raise OutOfDomainError(CHART_NAME, first_negative)
179
+
180
+ total = numbers.sum()
181
+ if total == 0:
182
+ raise EmptyTotalError(CHART_NAME, column_name)
183
+
184
+
185
+ def warn_slice_count(slice_count: int) -> None:
186
+ """
187
+ Emit a ReadabilityWarning when a PieChart has more than 5 slices.
188
+
189
+ .. versionadded:: 0.1.0
190
+
191
+ Parameters
192
+ ----------
193
+ slice_count
194
+ The number of slices.
195
+
196
+ Warns
197
+ -----
198
+ ReadabilityWarning
199
+ When there are more than 5 slices.
200
+
201
+ Examples
202
+ --------
203
+ >>> import warnings
204
+ >>> from numdaplot.plots.data.pie_values import warn_slice_count
205
+ >>> with warnings.catch_warnings(record=True) as caught_warnings:
206
+ ... warnings.simplefilter("always")
207
+ ... warn_slice_count(6)
208
+ >>> print(caught_warnings[0].message)
209
+ A PieChart with 6 slices is hard to read. Try ndp.Plot.bar with a BarChart, it may compare them better.
210
+ """
211
+ if slice_count <= MAXIMUM_READABLE_SLICES:
212
+ return
213
+
214
+ message = READABILITY_MESSAGE.format(slice_count=slice_count)
215
+ warnings.warn(message, ReadabilityWarning, stacklevel=READABILITY_STACK_LEVEL)
@@ -0,0 +1,249 @@
1
+ """
2
+ Values coloring and sizing the points of a ScatterChart.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass, replace
8
+ from typing import Any
9
+
10
+ import numpy
11
+ import pandas
12
+ from numpy.typing import NDArray
13
+
14
+ from numdaplot.data_types.value_family import ValueFamily
15
+ from numdaplot.errors.refused_setting_error import RefusedSettingError
16
+ from numdaplot.plots.charts.color_scale import ColorScale
17
+ from numdaplot.plots.data.chart_values import ChartValues, Series
18
+ from numdaplot.plots.data.column_reading import read_numbers, read_texts, require_column_family
19
+ from numdaplot.tables.columns.column_names import require_known_columns
20
+ from numdaplot.tables.frames.column import Column
21
+ from numdaplot.tables.table import Table
22
+ from numdaplot.tables.table_data import read_stored_frame
23
+
24
+ CHART_NAME = "ScatterChart"
25
+ NUMBER_COLORS_DTYPE = numpy.dtype(numpy.float64)
26
+ SCALE_ON_TEXTS = "scale without a color_by column of numbers"
27
+ COLOR_FAMILIES = frozenset({ValueFamily.NUMBER, ValueFamily.TEXT, ValueFamily.BOOL, ValueFamily.TIME})
28
+
29
+
30
+ @dataclass(frozen=True, eq=False)
31
+ class PointValues:
32
+ """
33
+ The values coloring and sizing each point of a ScatterChart, one per drawn row.
34
+
35
+ .. versionadded:: 0.1.0
36
+
37
+ Parameters
38
+ ----------
39
+ color_name
40
+ The ``color_by`` column, or None.
41
+ colors
42
+ Its values: float64 numbers or texts, or None.
43
+ size_name
44
+ The ``size_by`` column, or None.
45
+ sizes
46
+ Its float64 numbers, or None.
47
+
48
+ Examples
49
+ --------
50
+ >>> import numpy
51
+ >>> from numdaplot.plots.data.point_values import PointValues
52
+ >>> PointValues("city", numpy.array(["Paris"], dtype=object), None, None).color_name
53
+ 'city'
54
+ """
55
+
56
+ color_name: str | None
57
+ colors: NDArray[Any] | None
58
+ size_name: str | None
59
+ sizes: NDArray[numpy.float64] | None
60
+
61
+
62
+ def read_point_values(
63
+ table: Table, color_name: str | None, size_name: str | None, rows: NDArray[numpy.intp]
64
+ ) -> PointValues:
65
+ """
66
+ Return the values of the ``color_by`` and ``size_by`` columns of a ScatterChart for the drawn rows.
67
+
68
+ .. versionadded:: 0.1.0
69
+
70
+ Parameters
71
+ ----------
72
+ table
73
+ The Table drawn.
74
+ color_name
75
+ The ``color_by`` column, or None.
76
+ size_name
77
+ The ``size_by`` column, or None.
78
+ rows
79
+ The row numbers drawn.
80
+
81
+ Returns
82
+ -------
83
+ PointValues
84
+ The values of each column given, in the order of the drawn rows.
85
+
86
+ Raises
87
+ ------
88
+ ColumnNotFoundError
89
+ When a column does not exist.
90
+ IncompatibleTypesError
91
+ When ``color_by`` holds neither numbers nor texts, or ``size_by`` does not hold numbers.
92
+
93
+ Examples
94
+ --------
95
+ >>> import numpy
96
+ >>> import numdaplot as ndp
97
+ >>> from numdaplot.plots.data.point_values import read_point_values
98
+ >>> surfaces = ndp.Array.from_list([30.0, 45.0])
99
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon"])
100
+ >>> flats = ndp.Table.from_arrays({"surface": surfaces, "city": cities})
101
+ >>> read_point_values(flats, "city", "surface", numpy.arange(2)).sizes
102
+ array([30., 45.])
103
+ """
104
+ frame = read_stored_frame(table)
105
+ column_names = frame.columns.tolist()
106
+ colors = None
107
+ sizes = None
108
+ if color_name is not None:
109
+ require_known_columns([color_name], column_names)
110
+ all_colors = read_colors(frame[color_name])
111
+ colors = all_colors[rows]
112
+
113
+ if size_name is not None:
114
+ require_known_columns([size_name], column_names)
115
+ all_sizes = read_numbers(frame[size_name], CHART_NAME)
116
+ sizes = all_sizes[rows]
117
+
118
+ point_values = PointValues(color_name, colors, size_name, sizes)
119
+
120
+ return point_values
121
+
122
+
123
+ def require_scale_on_numbers(scale: ColorScale | None, colors: NDArray[Any] | None) -> None:
124
+ """
125
+ Check that a color scale colors numbers.
126
+
127
+ .. versionadded:: 0.1.0
128
+
129
+ Parameters
130
+ ----------
131
+ scale
132
+ The ``scale`` of a ScatterChart, or None.
133
+ colors
134
+ The values of its ``color_by`` column, float64 numbers or texts.
135
+
136
+ Raises
137
+ ------
138
+ RefusedSettingError
139
+ When a scale is given for texts or booleans, which take one color per value.
140
+
141
+ Examples
142
+ --------
143
+ >>> import numpy
144
+ >>> import numdaplot as ndp
145
+ >>> from numdaplot.plots.data.point_values import require_scale_on_numbers
146
+ >>> require_scale_on_numbers(ndp.ColorScale.BLUES, numpy.array([1.5]))
147
+ >>> try:
148
+ ... require_scale_on_numbers(ndp.ColorScale.BLUES, numpy.array(["Paris"], dtype=object))
149
+ ... except ndp.RefusedSettingError as error:
150
+ ... print(error)
151
+ ScatterChart does not accept scale without a color_by column of numbers.
152
+ """
153
+ if scale is None or colors is None:
154
+ return
155
+
156
+ if colors.dtype != NUMBER_COLORS_DTYPE:
157
+ raise RefusedSettingError(SCALE_ON_TEXTS, CHART_NAME)
158
+
159
+
160
+ def read_colors(column: Column) -> NDArray[Any]:
161
+ """
162
+ Return the values of a ``color_by`` column: float64 numbers or texts.
163
+
164
+ .. versionadded:: 0.1.0
165
+
166
+ Parameters
167
+ ----------
168
+ column
169
+ A Table column.
170
+
171
+ Returns
172
+ -------
173
+ NDArray
174
+ Numbers with NaN, or texts with None, where a value is missing.
175
+
176
+ Raises
177
+ ------
178
+ IncompatibleTypesError
179
+ When the column holds neither numbers, texts, booleans nor times of day.
180
+
181
+ Examples
182
+ --------
183
+ >>> import pandas
184
+ >>> from numdaplot.plots.data.point_values import read_colors
185
+ >>> read_colors(pandas.Series([2.5, None], dtype="float64"))
186
+ array([2.5, nan])
187
+ """
188
+ family = require_column_family(column, COLOR_FAMILIES, CHART_NAME)
189
+ if family == ValueFamily.NUMBER:
190
+ numbers = read_numbers(column, CHART_NAME)
191
+ return numbers
192
+
193
+ texts = read_texts(column, CHART_NAME)
194
+
195
+ return texts
196
+
197
+
198
+ def hide_missing_points(chart_values: ChartValues, point_values: PointValues) -> ChartValues:
199
+ """
200
+ Return the values of a ScatterChart without the points whose color or size value is missing.
201
+
202
+ .. versionadded:: 0.1.0
203
+
204
+ Parameters
205
+ ----------
206
+ chart_values
207
+ The positions and the series.
208
+ point_values
209
+ The values coloring and sizing the points.
210
+
211
+ Returns
212
+ -------
213
+ ChartValues
214
+ The same values, NaN in the series where a color or size value is missing.
215
+
216
+ Examples
217
+ --------
218
+ >>> import numpy
219
+ >>> import numdaplot as ndp
220
+ >>> from numdaplot.plots.data.chart_values import ChartValues, Positions, Series
221
+ >>> from numdaplot.plots.data.point_values import PointValues, hide_missing_points
222
+ >>> from numdaplot.plots.data.position_kind import PositionKind
223
+ >>> positions = Positions(PositionKind.NUMBERS, numpy.array([0.0, 1.0]), None)
224
+ >>> price_series = Series("price", numpy.array([1.0, 2.0]))
225
+ >>> chart_values = ChartValues(positions, [price_series], numpy.arange(2), "price", ndp.Type.FLOAT64)
226
+ >>> point_values = PointValues(None, None, "surface", numpy.array([30.0, numpy.nan]))
227
+ >>> hide_missing_points(chart_values, point_values).series[0].values
228
+ array([ 1., nan])
229
+ """
230
+ row_count = len(chart_values.rows)
231
+ missing = numpy.zeros(row_count, dtype=numpy.bool_)
232
+
233
+ for point_column in (point_values.colors, point_values.sizes):
234
+ if point_column is None:
235
+ continue
236
+
237
+ missing_values = pandas.isna(point_column)
238
+ missing = missing | missing_values
239
+
240
+ shown_series = list[Series]()
241
+
242
+ for series in chart_values.series:
243
+ shown_numbers = numpy.where(missing, numpy.nan, series.values)
244
+ series_copy = Series(series.name, shown_numbers)
245
+ shown_series.append(series_copy)
246
+
247
+ shown_values = replace(chart_values, series=shown_series)
248
+
249
+ return shown_values