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,278 @@
1
+ """
2
+ Placement of the ``x`` values of a chart along its axis.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ # The matplotlib stubs leave the keyword arguments of most drawing methods untyped.
8
+ # pyright: reportUnknownMemberType=false
9
+
10
+ from typing import Any, cast
11
+
12
+ import numpy
13
+ from matplotlib.axes import Axes
14
+ from matplotlib.axis import Axis
15
+ from matplotlib.dates import AutoDateLocator
16
+ from matplotlib.ticker import FixedFormatter, FixedLocator
17
+ from numpy.typing import NDArray
18
+
19
+ from numdaplot.arrays.conversion.time_text import format_datetimes
20
+ from numdaplot.plots.data.chart_values import Positions
21
+ from numdaplot.plots.data.position_kind import PositionKind
22
+ from numdaplot.plots.drawing.moment_period_formatter import MomentPeriodFormatter
23
+ from numdaplot.plots.drawing.time_axis import format_hour, place_hour_ticks
24
+ from numdaplot.plots.drawing.whole_numbers import place_whole_ticks
25
+
26
+ DAY_UNIT = "D"
27
+ DAY_DTYPE = numpy.dtype("datetime64[D]")
28
+ TRIMMED_ZEROS = "-"
29
+
30
+
31
+ def place_positions(axes: Axes, positions: Positions, on_vertical_axis: bool) -> NDArray[Any]:
32
+ """
33
+ Return the coordinates of the ``x`` values of a line or scatter chart, and set the ticks of their axis.
34
+
35
+ Numbers keep their value, with ticks on whole numbers only when every number is whole, moments are
36
+ placed on a time axis whose corner label gives their period, and texts are placed at 0, 1, 2 and so on,
37
+ each labeled with its text.
38
+
39
+ .. versionadded:: 0.1.0
40
+
41
+ Parameters
42
+ ----------
43
+ axes
44
+ The matplotlib axes drawn on.
45
+ positions
46
+ The ``x`` values.
47
+ on_vertical_axis
48
+ True to place them on the vertical axis.
49
+
50
+ Returns
51
+ -------
52
+ NDArray
53
+ The coordinates given to matplotlib.
54
+
55
+ Examples
56
+ --------
57
+ >>> import numpy
58
+ >>> from matplotlib.figure import Figure
59
+ >>> from numdaplot.plots.data.chart_values import Positions
60
+ >>> from numdaplot.plots.data.position_kind import PositionKind
61
+ >>> from numdaplot.plots.drawing.position_axis import place_positions
62
+ >>> axes = Figure().add_subplot()
63
+ >>> place_positions(axes, Positions(PositionKind.TEXTS, numpy.array(["Paris", "Lyon"]), "city"), False)
64
+ array([0., 1.])
65
+ >>> [label.get_text() for label in axes.get_xticklabels()]
66
+ ['Paris', 'Lyon']
67
+ """
68
+ if positions.kind == PositionKind.TEXTS:
69
+ categories = place_categories(axes, positions, on_vertical_axis)
70
+ return categories
71
+
72
+ position_axis = find_axis(axes, on_vertical_axis)
73
+ if positions.kind == PositionKind.NUMBERS:
74
+ place_whole_ticks(position_axis, positions.values)
75
+ return positions.values
76
+
77
+ if positions.kind == PositionKind.TIMES:
78
+ place_hour_ticks(position_axis, positions.values)
79
+ return positions.values
80
+
81
+ if positions.kind == PositionKind.MOMENTS:
82
+ date_locator = AutoDateLocator()
83
+ date_formatter = MomentPeriodFormatter(date_locator, axes, on_vertical_axis)
84
+ position_axis.set_major_locator(date_locator)
85
+ position_axis.set_major_formatter(date_formatter)
86
+
87
+ return positions.values
88
+
89
+
90
+ def place_categories(axes: Axes, positions: Positions, on_vertical_axis: bool) -> NDArray[numpy.float64]:
91
+ """
92
+ Return the coordinates 0, 1, 2 and so on of the ``x`` values, each tick labeled with its value.
93
+
94
+ .. versionadded:: 0.1.0
95
+
96
+ Parameters
97
+ ----------
98
+ axes
99
+ The matplotlib axes drawn on.
100
+ positions
101
+ The ``x`` values.
102
+ on_vertical_axis
103
+ True to place them on the vertical axis.
104
+
105
+ Returns
106
+ -------
107
+ NDArray[numpy.float64]
108
+ One coordinate per value.
109
+
110
+ Examples
111
+ --------
112
+ >>> import numpy
113
+ >>> from matplotlib.figure import Figure
114
+ >>> from numdaplot.plots.data.chart_values import Positions
115
+ >>> from numdaplot.plots.data.position_kind import PositionKind
116
+ >>> from numdaplot.plots.drawing.position_axis import place_categories
117
+ >>> axes = Figure().add_subplot()
118
+ >>> place_categories(axes, Positions(PositionKind.NUMBERS, numpy.array([2025.0, 2026.0]), "year"), False)
119
+ array([0., 1.])
120
+ >>> [label.get_text() for label in axes.get_xticklabels()]
121
+ ['2025', '2026']
122
+ """
123
+ position_count = len(positions.values)
124
+ coordinates = numpy.arange(position_count, dtype=numpy.float64)
125
+ labels = write_position_labels(positions)
126
+ position_axis = find_axis(axes, on_vertical_axis)
127
+ set_fixed_labels(position_axis, coordinates, labels)
128
+
129
+ return coordinates
130
+
131
+
132
+ def set_fixed_labels(axis: Axis, coordinates: NDArray[numpy.float64], labels: list[str]) -> None:
133
+ """
134
+ Place a label at each coordinate of an axis, without creating the matplotlib ticks yet.
135
+
136
+ ``Axis.set_ticks`` creates one tick per label, about 3 milliseconds each, when only the labels that fit stay.
137
+
138
+ .. versionadded:: 0.1.0
139
+
140
+ Parameters
141
+ ----------
142
+ axis
143
+ The axis.
144
+ coordinates
145
+ The coordinate of each label.
146
+ labels
147
+ The text of each label.
148
+
149
+ Examples
150
+ --------
151
+ >>> import numpy
152
+ >>> from matplotlib.figure import Figure
153
+ >>> from numdaplot.plots.drawing.position_axis import set_fixed_labels
154
+ >>> axes = Figure().add_subplot()
155
+ >>> set_fixed_labels(axes.xaxis, numpy.array([0.0, 1.0]), ["Paris", "Lyon"])
156
+ >>> [label.get_text() for label in axes.get_xticklabels()]
157
+ ['Paris', 'Lyon']
158
+ """
159
+ label_places = cast(list[float], coordinates.tolist())
160
+ label_locator = FixedLocator(label_places)
161
+ label_formatter = FixedFormatter(labels)
162
+ axis.set_major_locator(label_locator)
163
+ axis.set_major_formatter(label_formatter)
164
+
165
+
166
+ def find_axis(axes: Axes, on_vertical_axis: bool) -> Axis:
167
+ """
168
+ Return the horizontal or the vertical axis of matplotlib axes.
169
+
170
+ .. versionadded:: 0.1.0
171
+
172
+ Parameters
173
+ ----------
174
+ axes
175
+ The matplotlib axes.
176
+ on_vertical_axis
177
+ True for the vertical axis.
178
+
179
+ Returns
180
+ -------
181
+ matplotlib.axis.Axis
182
+ The ``yaxis`` or the ``xaxis``.
183
+
184
+ Examples
185
+ --------
186
+ >>> from matplotlib.figure import Figure
187
+ >>> from numdaplot.plots.drawing.position_axis import find_axis
188
+ >>> find_axis(Figure().add_subplot(), True).axis_name
189
+ 'y'
190
+ """
191
+ if on_vertical_axis:
192
+ return axes.yaxis
193
+
194
+ return axes.xaxis
195
+
196
+
197
+ def write_position_labels(positions: Positions) -> list[str]:
198
+ """
199
+ Return the text labeling each ``x`` value.
200
+
201
+ .. versionadded:: 0.1.0
202
+
203
+ Parameters
204
+ ----------
205
+ positions
206
+ The ``x`` values.
207
+
208
+ Returns
209
+ -------
210
+ list[str]
211
+ Numbers without trailing zeros, dates without time when every value is at midnight, texts as they are.
212
+
213
+ Examples
214
+ --------
215
+ >>> import numpy
216
+ >>> from numdaplot.plots.data.chart_values import Positions
217
+ >>> from numdaplot.plots.data.position_kind import PositionKind
218
+ >>> from numdaplot.plots.drawing.position_axis import write_position_labels
219
+ >>> days = numpy.array(["2026-01-01", "2026-01-02"], dtype="datetime64[ns]")
220
+ >>> write_position_labels(Positions(PositionKind.MOMENTS, days, "day"))
221
+ ['2026-01-01', '2026-01-02']
222
+ """
223
+ if positions.kind == PositionKind.NUMBERS:
224
+ number_labels = [numpy.format_float_positional(value, trim=TRIMMED_ZEROS) for value in positions.values]
225
+ return number_labels
226
+
227
+ if positions.kind == PositionKind.MOMENTS:
228
+ moment_labels = write_moment_labels(positions.values)
229
+ return moment_labels
230
+
231
+ if positions.kind == PositionKind.TIMES:
232
+ hour_labels = [format_hour(value) for value in positions.values]
233
+ return hour_labels
234
+
235
+ text_labels = [str(value) for value in positions.values]
236
+
237
+ return text_labels
238
+
239
+
240
+ def write_moment_labels(moments: NDArray[numpy.datetime64]) -> list[str]:
241
+ """
242
+ Return the text of each date or datetime, without time when every value is at midnight.
243
+
244
+ .. versionadded:: 0.1.0
245
+
246
+ Parameters
247
+ ----------
248
+ moments
249
+ datetime64 values.
250
+
251
+ Returns
252
+ -------
253
+ list[str]
254
+ One text per value, ``NaT`` for a missing value.
255
+
256
+ Examples
257
+ --------
258
+ >>> import numpy
259
+ >>> from numdaplot.plots.drawing.position_axis import write_moment_labels
260
+ >>> write_moment_labels(numpy.array(["2026-01-01T10:30"], dtype="datetime64[ns]"))
261
+ ['2026-01-01 10:30:00']
262
+ """
263
+ days = moments.astype(DAY_DTYPE)
264
+ day_starts = days.astype(moments.dtype)
265
+ at_midnight = day_starts == moments
266
+ missing = numpy.isnat(moments)
267
+ is_whole_day = at_midnight | missing
268
+ all_whole_days = bool(numpy.all(is_whole_day))
269
+ if all_whole_days:
270
+ day_texts = numpy.datetime_as_string(days, unit=DAY_UNIT)
271
+ # Some versions of the numpy stubs type the list of a text array as nested lists.
272
+ day_labels = cast(list[str], day_texts.tolist())
273
+ return day_labels
274
+
275
+ moment_texts = format_datetimes(moments)
276
+ moment_labels = cast(list[str], moment_texts.tolist())
277
+
278
+ return moment_labels
@@ -0,0 +1,364 @@
1
+ """
2
+ Drawing of a ScatterChart.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ # The matplotlib stubs leave the keyword arguments of most drawing methods untyped.
8
+ # pyright: reportUnknownMemberType=false
9
+
10
+ from dataclasses import dataclass
11
+ from typing import Any, cast
12
+
13
+ import numpy
14
+ import pandas
15
+ from matplotlib.axes import Axes
16
+ from matplotlib.collections import PathCollection
17
+ from numpy.typing import NDArray
18
+
19
+ from numdaplot.plots.chart_layer import ChartLayer
20
+ from numdaplot.plots.charts.color_scale import ColorScale
21
+ from numdaplot.plots.charts.scatter_chart import ScatterChart
22
+ from numdaplot.plots.data.chart_values import ChartValues, Series
23
+ from numdaplot.plots.data.point_values import PointValues
24
+ from numdaplot.plots.drawing.color_bar import add_color_bar
25
+ from numdaplot.plots.drawing.color_scale_values import find_point_colors, find_scale_limits
26
+ from numdaplot.plots.drawing.default_labels import find_position_label
27
+ from numdaplot.plots.drawing.drawn_chart import DrawnChart
28
+ from numdaplot.plots.drawing.grid_axes import GridAxes
29
+ from numdaplot.plots.drawing.marker_codes import MARKER_CODES
30
+ from numdaplot.plots.drawing.position_axis import place_positions
31
+ from numdaplot.plots.drawing.series_colors import choose_series_colors
32
+ from numdaplot.plots.style.color import Color
33
+ from numdaplot.plots.style.custom_color import CustomColor
34
+
35
+ DEFAULT_POINT_SIZE = 6.0
36
+ SMALLEST_POINT_AREA = 16.0
37
+ LARGEST_POINT_AREA = 256.0
38
+ DEFAULT_COLOR_SCALE = ColorScale.VIRIDIS
39
+ NO_POINT_VALUES = PointValues(None, None, None, None)
40
+
41
+
42
+ @dataclass(frozen=True, eq=False)
43
+ class PointLook:
44
+ """
45
+ The look shared by the points of a ScatterChart.
46
+
47
+ .. versionadded:: 0.1.0
48
+
49
+ Parameters
50
+ ----------
51
+ coordinates
52
+ The coordinates of the ``x`` values.
53
+ areas
54
+ The area of each point in square points.
55
+ marker_code
56
+ The matplotlib code of the marker shape.
57
+ opacity
58
+ How opaque the points are, from 0 to 1.
59
+ scale
60
+ The colors of the points colored by numbers.
61
+
62
+ Examples
63
+ --------
64
+ >>> import numdaplot as ndp
65
+ >>> import numpy
66
+ >>> from numdaplot.plots.drawing.scatter_drawing import PointLook
67
+ >>> PointLook(numpy.array([0.0]), numpy.array([36.0]), "o", 1.0, ndp.ColorScale.VIRIDIS).marker_code
68
+ 'o'
69
+ """
70
+
71
+ coordinates: NDArray[Any]
72
+ areas: NDArray[numpy.float64]
73
+ marker_code: str
74
+ opacity: float
75
+ scale: ColorScale
76
+
77
+
78
+ def draw_scatter_chart(axes: Axes, layer: ChartLayer) -> DrawnChart:
79
+ """
80
+ Draw each row of a ScatterChart as a point, colored and sized by the ``color_by`` and ``size_by`` columns.
81
+
82
+ .. versionadded:: 0.1.0
83
+
84
+ Parameters
85
+ ----------
86
+ axes
87
+ The matplotlib axes drawn on.
88
+ layer
89
+ A ScatterChart, its values and the values of its points.
90
+
91
+ Returns
92
+ -------
93
+ DrawnChart
94
+ The default labels, grid lines across both axes, and the ``color_by`` column as legend title when it
95
+ holds texts.
96
+
97
+ Raises
98
+ ------
99
+ InvalidColorCountError
100
+ When ``color`` is given for an Array of several columns.
101
+
102
+ Examples
103
+ --------
104
+ >>> import numdaplot as ndp
105
+ >>> from matplotlib.figure import Figure
106
+ >>> from numdaplot.plots.chart_layer import ChartLayer
107
+ >>> from numdaplot.plots.data.array_values import read_array_values
108
+ >>> from numdaplot.plots.drawing.scatter_drawing import draw_scatter_chart
109
+ >>> prices = ndp.Array.from_list([12.0, 15.5])
110
+ >>> axes = Figure().add_subplot()
111
+ >>> layer = ChartLayer(ndp.ScatterChart(), read_array_values(prices, "ScatterChart"))
112
+ >>> drawn_chart = draw_scatter_chart(axes, layer)
113
+ >>> axes.collections[0].get_offsets().tolist()
114
+ [[0.0, 12.0], [1.0, 15.5]]
115
+ """
116
+ chart = cast(ScatterChart, layer.chart)
117
+ values = cast(ChartValues, layer.values)
118
+ points = NO_POINT_VALUES
119
+ if layer.points is not None:
120
+ points = layer.points
121
+
122
+ coordinates = place_positions(axes, values.positions, False)
123
+ row_count = len(coordinates)
124
+ areas = choose_areas(points.sizes, row_count, chart.point_size)
125
+ marker_code = MARKER_CODES[chart.marker]
126
+ scale = DEFAULT_COLOR_SCALE if chart.scale is None else chart.scale
127
+ point_look = PointLook(coordinates, areas, marker_code, chart.opacity, scale)
128
+ x_label = find_position_label(values.positions)
129
+ no_legend_chart = DrawnChart(x_label, values.value_name, False, GridAxes.BOTH, None)
130
+ if points.colors is None:
131
+ draw_colored_series(axes, chart.color, values.series, point_look)
132
+ return no_legend_chart
133
+
134
+ color_name = cast(str, points.color_name)
135
+ first_series = values.series[0]
136
+ if points.colors.dtype == numpy.float64:
137
+ scaled_points = draw_color_scale(axes, first_series, points.colors, point_look)
138
+ add_color_bar(axes, scaled_points, color_name, points.colors)
139
+ return no_legend_chart
140
+
141
+ draw_color_groups(axes, first_series, points.colors, point_look)
142
+ group_chart = DrawnChart(x_label, values.value_name, False, GridAxes.BOTH, color_name)
143
+
144
+ return group_chart
145
+
146
+
147
+ def choose_areas(
148
+ sizes: NDArray[numpy.float64] | None, row_count: int, point_size: float | None
149
+ ) -> NDArray[numpy.float64]:
150
+ """
151
+ Return the area of each point, scaled from the smallest to the largest ``size_by`` value.
152
+
153
+ .. versionadded:: 0.1.0
154
+
155
+ Parameters
156
+ ----------
157
+ sizes
158
+ The ``size_by`` values, NaN where a value is missing, or None for points of the same size.
159
+ row_count
160
+ The number of points.
161
+ point_size
162
+ The diameter of every point without ``size_by``, or None for the default diameter.
163
+
164
+ Returns
165
+ -------
166
+ NDArray[numpy.float64]
167
+ Areas from 16 to 256 square points, the square of the diameter for every point without ``size_by``, 36 by
168
+ default, and the middle area when every value is the same. A point with a missing size is not drawn, its area
169
+ is 0.
170
+
171
+ Examples
172
+ --------
173
+ >>> import numpy
174
+ >>> from numdaplot.plots.drawing.scatter_drawing import choose_areas
175
+ >>> choose_areas(numpy.array([10.0, 20.0, 30.0]), 3, None)
176
+ array([ 16., 136., 256.])
177
+ """
178
+ if sizes is None:
179
+ diameter = DEFAULT_POINT_SIZE if point_size is None else point_size
180
+ same_areas = numpy.full(row_count, diameter**2)
181
+ return same_areas
182
+
183
+ area_range = LARGEST_POINT_AREA - SMALLEST_POINT_AREA
184
+ middle_area = SMALLEST_POINT_AREA + area_range / 2
185
+ present = ~numpy.isnan(sizes)
186
+ present_sizes = sizes[present]
187
+ areas = numpy.full(row_count, middle_area)
188
+ present_count = len(present_sizes)
189
+ if present_count == 0:
190
+ return areas
191
+
192
+ smallest_size = present_sizes.min()
193
+ largest_size = present_sizes.max()
194
+ size_range = largest_size - smallest_size
195
+ if size_range > 0:
196
+ size_shares = (sizes - smallest_size) / size_range
197
+ areas = SMALLEST_POINT_AREA + size_shares * area_range
198
+
199
+ drawn_areas = numpy.where(present, areas, 0.0)
200
+
201
+ return drawn_areas
202
+
203
+
204
+ def draw_colored_series(
205
+ axes: Axes, color: Color | CustomColor | None, series_list: list[Series], point_look: PointLook
206
+ ) -> None:
207
+ """
208
+ Draw the points of each series in one color.
209
+
210
+ .. versionadded:: 0.1.0
211
+
212
+ Parameters
213
+ ----------
214
+ axes
215
+ The matplotlib axes drawn on.
216
+ color
217
+ The color of the points of a single series, or None for the colors of the default cycle.
218
+ series_list
219
+ The series drawn.
220
+ point_look
221
+ The coordinates, the areas and the marker of the points.
222
+
223
+ Raises
224
+ ------
225
+ InvalidColorCountError
226
+ When a color is given for several series.
227
+
228
+ Examples
229
+ --------
230
+ >>> import numpy
231
+ >>> import numdaplot as ndp
232
+ >>> from matplotlib.figure import Figure
233
+ >>> from numdaplot.plots.data.chart_values import Series
234
+ >>> from numdaplot.plots.drawing.scatter_drawing import PointLook, draw_colored_series
235
+ >>> axes = Figure().add_subplot()
236
+ >>> point_look = PointLook(numpy.array([0.0]), numpy.array([36.0]), "o", 1.0, ndp.ColorScale.VIRIDIS)
237
+ >>> draw_colored_series(axes, ndp.Color.RED, [Series("price", numpy.array([12.0]))], point_look)
238
+ >>> axes.collections[0].get_facecolor().round(2).tolist()
239
+ [[0.84, 0.15, 0.16, 1.0]]
240
+ """
241
+ chosen_colors = None
242
+ if color is not None:
243
+ chosen_colors = [color]
244
+
245
+ series_count = len(series_list)
246
+ color_codes = choose_series_colors(chosen_colors, series_count)
247
+
248
+ for series, color_code in zip(series_list, color_codes, strict=True):
249
+ axes.scatter(
250
+ point_look.coordinates,
251
+ series.values,
252
+ s=point_look.areas,
253
+ color=color_code,
254
+ marker=point_look.marker_code,
255
+ alpha=point_look.opacity,
256
+ label=series.name,
257
+ )
258
+
259
+
260
+ def draw_color_scale(
261
+ axes: Axes, series: Series, color_numbers: NDArray[numpy.float64], point_look: PointLook
262
+ ) -> PathCollection:
263
+ """
264
+ Draw points colored along a color scale, from the smallest to the largest ``color_by`` number.
265
+
266
+ .. versionadded:: 0.1.0
267
+
268
+ Parameters
269
+ ----------
270
+ axes
271
+ The matplotlib axes drawn on.
272
+ series
273
+ The series drawn.
274
+ color_numbers
275
+ The ``color_by`` numbers.
276
+ point_look
277
+ The coordinates, the areas and the marker of the points.
278
+
279
+ Returns
280
+ -------
281
+ matplotlib.collections.PathCollection
282
+ The drawn points, which the color bar describes.
283
+
284
+ Examples
285
+ --------
286
+ >>> import numdaplot as ndp
287
+ >>> import numpy
288
+ >>> from matplotlib.figure import Figure
289
+ >>> from numdaplot.plots.data.chart_values import Series
290
+ >>> from numdaplot.plots.drawing.scatter_drawing import PointLook, draw_color_scale
291
+ >>> axes = Figure().add_subplot()
292
+ >>> point_look = PointLook(numpy.array([0.0, 1.0]), numpy.array([36.0, 36.0]), "o", 1.0, ndp.ColorScale.VIRIDIS)
293
+ >>> series = Series("price", numpy.array([1.0, 2.0]))
294
+ >>> scaled_points = draw_color_scale(axes, series, numpy.array([5.0, 9.0]), point_look)
295
+ >>> [float(limit) for limit in scaled_points.get_clim()]
296
+ [5.0, 9.0]
297
+ """
298
+ point_colors = find_point_colors(point_look.scale)
299
+ lowest_color, highest_color = find_scale_limits(color_numbers, point_look.scale)
300
+ scaled_points = axes.scatter(
301
+ point_look.coordinates,
302
+ series.values,
303
+ s=point_look.areas,
304
+ c=color_numbers,
305
+ cmap=point_colors,
306
+ vmin=lowest_color,
307
+ vmax=highest_color,
308
+ marker=point_look.marker_code,
309
+ alpha=point_look.opacity,
310
+ )
311
+
312
+ return scaled_points
313
+
314
+
315
+ def draw_color_groups(axes: Axes, series: Series, color_texts: NDArray[Any], point_look: PointLook) -> None:
316
+ """
317
+ Draw the points of each ``color_by`` text in its own color, named in the legend.
318
+
319
+ The texts take the colors of the default cycle in the order they first appear.
320
+
321
+ .. versionadded:: 0.1.0
322
+
323
+ Parameters
324
+ ----------
325
+ axes
326
+ The matplotlib axes drawn on.
327
+ series
328
+ The series drawn.
329
+ color_texts
330
+ The ``color_by`` texts, None where a text is missing.
331
+ point_look
332
+ The coordinates, the areas and the marker of the points.
333
+
334
+ Examples
335
+ --------
336
+ >>> import numdaplot as ndp
337
+ >>> import numpy
338
+ >>> from matplotlib.figure import Figure
339
+ >>> from numdaplot.plots.data.chart_values import Series
340
+ >>> from numdaplot.plots.drawing.scatter_drawing import PointLook, draw_color_groups
341
+ >>> axes = Figure().add_subplot()
342
+ >>> point_look = PointLook(numpy.array([0.0, 1.0]), numpy.array([36.0, 36.0]), "o", 1.0, ndp.ColorScale.VIRIDIS)
343
+ >>> texts = numpy.array(["Pau", "Lyon"], dtype=object)
344
+ >>> draw_color_groups(axes, Series("price", numpy.array([1.0, 2.0])), texts, point_look)
345
+ >>> [points.get_label() for points in axes.collections]
346
+ ['Pau', 'Lyon']
347
+ """
348
+ present = pandas.notna(color_texts)
349
+ present_texts = color_texts[present]
350
+ groups = pandas.unique(present_texts)
351
+ group_count = len(groups)
352
+ color_codes = choose_series_colors(None, group_count)
353
+
354
+ for group, color_code in zip(groups, color_codes, strict=True):
355
+ in_group = color_texts == group
356
+ axes.scatter(
357
+ point_look.coordinates[in_group],
358
+ series.values[in_group],
359
+ s=point_look.areas[in_group],
360
+ color=color_code,
361
+ marker=point_look.marker_code,
362
+ alpha=point_look.opacity,
363
+ label=group,
364
+ )