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,185 @@
1
+ """
2
+ Drawing of a PieChart.
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
+ import math
11
+ from typing import cast
12
+
13
+ import numpy
14
+ from matplotlib.axes import Axes
15
+ from matplotlib.colors import to_rgba
16
+ from matplotlib.patches import Wedge
17
+ from numpy.typing import NDArray
18
+
19
+ from numdaplot.plots.chart_layer import ChartLayer
20
+ from numdaplot.plots.charts.percentages import Percentages
21
+ from numdaplot.plots.charts.pie_chart import PieChart
22
+ from numdaplot.plots.data.chart_values import ChartValues
23
+ from numdaplot.plots.drawing.drawn_chart import DrawnChart
24
+ from numdaplot.plots.drawing.grid_axes import GridAxes
25
+ from numdaplot.plots.drawing.plot_theme import BACKGROUND_COLOR
26
+ from numdaplot.plots.drawing.series_colors import choose_series_colors
27
+ from numdaplot.plots.drawing.text_contrast import choose_text_color
28
+
29
+ # matplotlib measures angles counterclockwise from the right, so 90 degrees is the top of the disc.
30
+ TOP_ANGLE = 90.0
31
+ SLICE_EDGE_WIDTH = 1.5
32
+ PERCENTAGE_FORMAT = "{share:.1%}"
33
+ # Share of the radius where the percentage of a slice is written, from the center.
34
+ PERCENTAGE_DISTANCE = 0.65
35
+ HALF = 0.5
36
+ CENTERED = "center"
37
+ PIE_TITLE = "{value_name} by {labels_name}"
38
+
39
+
40
+ def draw_pie_chart(axes: Axes, layer: ChartLayer) -> DrawnChart:
41
+ """
42
+ Draw each value as a slice of a disc, from the top and clockwise, each labeled with its text.
43
+
44
+ .. versionadded:: 0.1.0
45
+
46
+ Parameters
47
+ ----------
48
+ axes
49
+ The matplotlib axes drawn on.
50
+ layer
51
+ A PieChart, its labels and its values.
52
+
53
+ Returns
54
+ -------
55
+ DrawnChart
56
+ No default label and no grid lines.
57
+
58
+ Raises
59
+ ------
60
+ InvalidColorCountError
61
+ When the colors of the chart are not one per slice.
62
+
63
+ Examples
64
+ --------
65
+ >>> import numdaplot as ndp
66
+ >>> from matplotlib.figure import Figure
67
+ >>> from numdaplot.plots.chart_layer import ChartLayer
68
+ >>> from numdaplot.plots.data.pie_values import read_pie_values
69
+ >>> from numdaplot.plots.drawing.pie_drawing import draw_pie_chart
70
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon"])
71
+ >>> sales = ndp.Array.from_list([150.0, 50.0])
72
+ >>> shares = ndp.Table.from_arrays({"city": cities, "sales": sales})
73
+ >>> chart = ndp.PieChart(labels="city", values="sales")
74
+ >>> axes = Figure().add_subplot()
75
+ >>> drawn_chart = draw_pie_chart(axes, ChartLayer(chart, read_pie_values(shares, chart)))
76
+ >>> [text.get_text() for text in axes.texts]
77
+ ['Paris', 'Lyon', '75.0%', '25.0%']
78
+ """
79
+ chart = cast(PieChart, layer.chart)
80
+ values = cast(ChartValues, layer.values)
81
+ labels = [str(label) for label in values.positions.values]
82
+ numbers = values.series[0].values
83
+ slice_count = len(labels)
84
+ color_codes = choose_series_colors(chart.colors, slice_count)
85
+ slice_style = {"edgecolor": BACKGROUND_COLOR, "linewidth": SLICE_EDGE_WIDTH}
86
+ axes.pie(
87
+ numbers,
88
+ labels=labels,
89
+ colors=color_codes,
90
+ startangle=TOP_ANGLE,
91
+ counterclock=False,
92
+ wedgeprops=slice_style,
93
+ )
94
+ slices = [patch for patch in axes.patches if isinstance(patch, Wedge)]
95
+
96
+ for pie_slice in slices:
97
+ # The labels are written next to the slices, so the legend leaves the slices out.
98
+ pie_slice.set_label("")
99
+
100
+ if chart.percentages == Percentages.SHOWN:
101
+ write_percentages(axes, slices, numbers)
102
+
103
+ pie_title = PIE_TITLE.format(value_name=values.value_name, labels_name=values.positions.name)
104
+ drawn_chart = DrawnChart(None, None, False, GridAxes.NONE, None, title=pie_title)
105
+
106
+ return drawn_chart
107
+
108
+
109
+ def write_percentages(axes: Axes, slices: list[Wedge], numbers: NDArray[numpy.float64]) -> None:
110
+ """
111
+ Write the share of each slice inside it, in black or white to stay readable over its color.
112
+
113
+ .. versionadded:: 0.1.0
114
+
115
+ Parameters
116
+ ----------
117
+ axes
118
+ The matplotlib axes drawn on.
119
+ slices
120
+ The slices of the disc, in the order of the values.
121
+ numbers
122
+ The value of each slice, adding up to more than 0.
123
+
124
+ Examples
125
+ --------
126
+ >>> import numpy
127
+ >>> from matplotlib.figure import Figure
128
+ >>> from matplotlib.patches import Wedge
129
+ >>> from numdaplot.plots.drawing.pie_drawing import write_percentages
130
+ >>> axes = Figure().add_subplot()
131
+ >>> write_percentages(axes, [Wedge((0.0, 0.0), 1.0, 0.0, 360.0)], numpy.array([4.0]))
132
+ >>> axes.texts[0].get_text()
133
+ '100.0%'
134
+ """
135
+ total = numbers.sum()
136
+ shares = numbers / total
137
+
138
+ for pie_slice, share in zip(slices, shares, strict=True):
139
+ percentage = PERCENTAGE_FORMAT.format(share=share)
140
+ face_color = pie_slice.get_facecolor()
141
+ slice_color = to_rgba(face_color)
142
+ text_color = choose_text_color(slice_color)
143
+ text_x, text_y = find_percentage_place(pie_slice)
144
+ axes.text(
145
+ text_x, text_y, percentage, color=text_color, horizontalalignment=CENTERED, verticalalignment=CENTERED
146
+ )
147
+
148
+
149
+ def find_percentage_place(pie_slice: Wedge) -> tuple[float, float]:
150
+ """
151
+ Return where the percentage of a slice is written: on its middle angle, partway from the center to the edge.
152
+
153
+ .. versionadded:: 0.1.0
154
+
155
+ Parameters
156
+ ----------
157
+ pie_slice
158
+ A slice of the disc.
159
+
160
+ Returns
161
+ -------
162
+ tuple[float, float]
163
+ The horizontal and vertical coordinates.
164
+
165
+ Examples
166
+ --------
167
+ >>> from matplotlib.patches import Wedge
168
+ >>> from numdaplot.plots.drawing.pie_drawing import find_percentage_place
169
+ >>> text_x, text_y = find_percentage_place(Wedge((0.0, 0.0), 1.0, 0.0, 180.0))
170
+ >>> round(text_x, 2), round(text_y, 2)
171
+ (0.0, 0.65)
172
+ """
173
+ angle_sum = pie_slice.theta1 + pie_slice.theta2
174
+ middle_degrees = angle_sum * HALF
175
+ middle_angle = math.radians(middle_degrees)
176
+ distance = pie_slice.r * PERCENTAGE_DISTANCE
177
+ center_x, center_y = pie_slice.center
178
+ cosine = math.cos(middle_angle)
179
+ sine = math.sin(middle_angle)
180
+ x_offset = distance * cosine
181
+ y_offset = distance * sine
182
+ text_x = center_x + x_offset
183
+ text_y = center_y + y_offset
184
+
185
+ return text_x, text_y
@@ -0,0 +1,38 @@
1
+ """
2
+ Axes a Plot is drawn on.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from matplotlib.axes import Axes
10
+
11
+
12
+ @dataclass(frozen=True, eq=False)
13
+ class PlotAxes:
14
+ """
15
+ The matplotlib axes a Plot is drawn on: the main ones, and the ones of the axis on the right if any.
16
+
17
+ .. versionadded:: 0.1.0
18
+
19
+ Parameters
20
+ ----------
21
+ left
22
+ The main axes, measured on the left.
23
+ right
24
+ The axes sharing the ``x`` values and measured on the right, or None without chart on the right.
25
+ right_label
26
+ The default label of the axis on the right: the single column of its first chart, or None.
27
+
28
+ Examples
29
+ --------
30
+ >>> from matplotlib.figure import Figure
31
+ >>> from numdaplot.plots.drawing.plot_axes import PlotAxes
32
+ >>> PlotAxes(Figure().add_subplot(), None, None).right is None
33
+ True
34
+ """
35
+
36
+ left: Axes
37
+ right: Axes | None
38
+ right_label: str | None
@@ -0,0 +1,288 @@
1
+ """
2
+ Drawing of a Plot on a matplotlib figure.
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 collections.abc import Callable
11
+ from dataclasses import dataclass
12
+ from typing import Any, cast
13
+
14
+ import matplotlib
15
+ from matplotlib.axes import Axes
16
+ from matplotlib.figure import Figure, FigureBase
17
+
18
+ from numdaplot.plots.chart_layer import ChartLayer
19
+ from numdaplot.plots.charts.bar_chart import BarChart
20
+ from numdaplot.plots.charts.box_chart import BoxChart
21
+ from numdaplot.plots.charts.chart import Chart
22
+ from numdaplot.plots.charts.heatmap_chart import HeatmapChart
23
+ from numdaplot.plots.charts.histogram_chart import HistogramChart
24
+ from numdaplot.plots.charts.line_chart import LineChart
25
+ from numdaplot.plots.charts.missing_chart import MissingChart
26
+ from numdaplot.plots.charts.missing_map_chart import MissingMapChart
27
+ from numdaplot.plots.charts.pie_chart import PieChart
28
+ from numdaplot.plots.charts.scatter_chart import ScatterChart
29
+ from numdaplot.plots.charts.value_axis import ValueAxis
30
+ from numdaplot.plots.data.renamed_layers import rename_layers
31
+ from numdaplot.plots.data.shown_columns import require_renamed_columns_shown
32
+ from numdaplot.plots.drawing.bar_drawing import draw_bar_chart
33
+ from numdaplot.plots.drawing.box_drawing import draw_box_chart
34
+ from numdaplot.plots.drawing.drawn_chart import DrawnChart
35
+ from numdaplot.plots.drawing.heatmap_drawing import draw_heatmap_chart
36
+ from numdaplot.plots.drawing.histogram_drawing import draw_histogram_chart
37
+ from numdaplot.plots.drawing.layer_alignment import align_layers
38
+ from numdaplot.plots.drawing.layer_colors import continue_color_cycle
39
+ from numdaplot.plots.drawing.line_drawing import draw_line_chart
40
+ from numdaplot.plots.drawing.missing_drawing import draw_missing_chart, draw_missing_map
41
+ from numdaplot.plots.drawing.pie_drawing import draw_pie_chart
42
+ from numdaplot.plots.drawing.plot_axes import PlotAxes
43
+ from numdaplot.plots.drawing.plot_theme import BACKGROUND_COLOR, THEME
44
+ from numdaplot.plots.drawing.scatter_drawing import draw_scatter_chart
45
+ from numdaplot.plots.drawing.style_drawing import apply_style
46
+ from numdaplot.plots.drawing.time_axis import place_value_hours
47
+ from numdaplot.plots.style.image_options import DEFAULT_DPI
48
+ from numdaplot.plots.style.plot_style import PlotStyle
49
+
50
+ type ChartDrawer = Callable[[Axes, ChartLayer], DrawnChart]
51
+ """A function drawing one kind of chart on matplotlib axes.
52
+
53
+ .. versionadded:: 0.1.0
54
+ """
55
+
56
+ CHART_DRAWERS = dict[type[Chart], ChartDrawer](
57
+ {
58
+ LineChart: draw_line_chart,
59
+ BarChart: draw_bar_chart,
60
+ ScatterChart: draw_scatter_chart,
61
+ HistogramChart: draw_histogram_chart,
62
+ BoxChart: draw_box_chart,
63
+ PieChart: draw_pie_chart,
64
+ HeatmapChart: draw_heatmap_chart,
65
+ MissingChart: draw_missing_chart,
66
+ MissingMapChart: draw_missing_map,
67
+ }
68
+ )
69
+ FIGURE_LAYOUT = "constrained"
70
+
71
+
72
+ @dataclass(frozen=True, eq=False)
73
+ class FigureDrawing:
74
+ """
75
+ What a Plot or a Figure draws, and the size of the figure it needs.
76
+
77
+ .. versionadded:: 0.1.0
78
+
79
+ Parameters
80
+ ----------
81
+ draw_on
82
+ The function drawing on an empty matplotlib figure or subfigure.
83
+ size_inches
84
+ The width and the height of the figure, in inches.
85
+
86
+ Examples
87
+ --------
88
+ >>> from numdaplot.plots.drawing.plot_drawing import FigureDrawing
89
+ >>> FigureDrawing(print, (6.4, 4.8)).size_inches
90
+ (6.4, 4.8)
91
+ """
92
+
93
+ draw_on: Callable[[FigureBase], None]
94
+ size_inches: tuple[float, float]
95
+
96
+
97
+ def build_figure(drawing: FigureDrawing) -> Figure:
98
+ """
99
+ Return a new matplotlib figure with a Plot or a Figure drawn on it.
100
+
101
+ No matplotlib window or notebook shows the figure on its own.
102
+
103
+ .. versionadded:: 0.1.0
104
+
105
+ Parameters
106
+ ----------
107
+ drawing
108
+ What is drawn, and the size of the figure.
109
+
110
+ Returns
111
+ -------
112
+ matplotlib.figure.Figure
113
+ The figure, at 100 dots per inch.
114
+
115
+ Examples
116
+ --------
117
+ >>> from numdaplot.plots.drawing.plot_drawing import FigureDrawing, build_figure
118
+ >>> figure = build_figure(FigureDrawing(lambda target: target.suptitle("Sales"), (3.0, 2.0)))
119
+ >>> figure.get_size_inches().tolist()
120
+ [3.0, 2.0]
121
+ """
122
+ figure = Figure(figsize=drawing.size_inches, dpi=DEFAULT_DPI, layout=FIGURE_LAYOUT)
123
+ drawing.draw_on(figure)
124
+
125
+ return figure
126
+
127
+
128
+ def draw_plot(figure: FigureBase, layers: list[ChartLayer], style: PlotStyle) -> None:
129
+ """
130
+ Draw the charts of a Plot on new axes of a figure, then its style.
131
+
132
+ The charts after the first one continue the default colors and share the ``x`` labels of the others.
133
+ The numdaplot look is applied while drawing only, so the global matplotlib settings never change.
134
+
135
+ .. versionadded:: 0.1.0
136
+
137
+ Parameters
138
+ ----------
139
+ figure
140
+ An empty matplotlib figure or subfigure.
141
+ layers
142
+ The charts of the Plot and their values, the first one giving the default labels.
143
+ style
144
+ The look of the Plot.
145
+
146
+ Raises
147
+ ------
148
+ InvalidColorCountError
149
+ When the colors of a chart are not one per series.
150
+ ColumnNotFoundError
151
+ When the style renames a column that no chart shows.
152
+
153
+ Examples
154
+ --------
155
+ >>> import numdaplot as ndp
156
+ >>> from matplotlib.figure import Figure, FigureBase
157
+ >>> from numdaplot.plots.chart_layer import ChartLayer
158
+ >>> from numdaplot.plots.data.array_values import read_array_values
159
+ >>> from numdaplot.plots.drawing.plot_drawing import draw_plot
160
+ >>> prices = ndp.Array.from_list([12.0, 15.5])
161
+ >>> figure = Figure()
162
+ >>> draw_plot(figure, [ChartLayer(ndp.LineChart(), read_array_values(prices, "LineChart"))], ndp.PlotStyle())
163
+ >>> figure.axes[0].spines["top"].get_visible()
164
+ False
165
+ """
166
+ require_renamed_columns_shown(layers, style.renaming)
167
+ shown_layers = rename_layers(layers, style.renaming)
168
+ figure.set_facecolor(BACKGROUND_COLOR)
169
+ colored_layers = continue_color_cycle(shown_layers)
170
+ aligned_layers = align_layers(colored_layers)
171
+
172
+ # Some versions of the matplotlib stubs only accept the names of known settings as keys.
173
+ theme = cast(Any, THEME)
174
+
175
+ with matplotlib.rc_context(theme):
176
+ left_axes = figure.add_subplot()
177
+ plot_axes, first_chart = draw_layers(left_axes, aligned_layers)
178
+ apply_style(plot_axes, first_chart, style)
179
+
180
+
181
+ def draw_layers(left_axes: Axes, layers: list[ChartLayer]) -> tuple[PlotAxes, DrawnChart]:
182
+ """
183
+ Draw each chart of a Plot in order, on the left axes or on axes measured on the right.
184
+
185
+ The axis of the values of each axes is labeled ``HH:MM`` when its lines or points measure times of day.
186
+
187
+ .. versionadded:: 0.1.0
188
+
189
+ Parameters
190
+ ----------
191
+ left_axes
192
+ The main matplotlib axes of the Plot.
193
+ layers
194
+ The charts of the Plot and their values, the first one on the left.
195
+
196
+ Returns
197
+ -------
198
+ tuple[PlotAxes, DrawnChart]
199
+ The axes drawn on, with the default label of the axis on the right, and what the first chart tells the
200
+ style.
201
+
202
+ Examples
203
+ --------
204
+ >>> import numdaplot as ndp
205
+ >>> from dataclasses import replace
206
+ >>> from matplotlib.figure import Figure, FigureBase
207
+ >>> from numdaplot.plots.chart_layer import ChartLayer
208
+ >>> from numdaplot.plots.data.table_values import read_table_values
209
+ >>> from numdaplot.plots.drawing.plot_drawing import draw_layers
210
+ >>> sales = ndp.Table.from_arrays(
211
+ ... {"sales": ndp.Array.from_list([120.0, 80.0]), "price": ndp.Array.from_list([12.5, 11.0])}
212
+ ... )
213
+ >>> bars = ChartLayer(ndp.BarChart(), read_table_values(sales, None, ["sales"], "BarChart"))
214
+ >>> line = ChartLayer(ndp.LineChart(), read_table_values(sales, None, ["price"], "LineChart"))
215
+ >>> right_line = replace(line, value_axis=ndp.ValueAxis.RIGHT)
216
+ >>> plot_axes, first_chart = draw_layers(Figure().add_subplot(), [bars, right_line])
217
+ >>> plot_axes.right_label, first_chart.y_label
218
+ ('price', 'sales')
219
+ """
220
+ right_axes = None
221
+ left_charts = list[DrawnChart]()
222
+ right_charts = list[DrawnChart]()
223
+ left_layers = list[ChartLayer]()
224
+ right_layers = list[ChartLayer]()
225
+
226
+ for layer in layers:
227
+ target_axes = left_axes
228
+ target_charts = left_charts
229
+ target_layers = left_layers
230
+ if layer.value_axis == ValueAxis.RIGHT:
231
+ right_axes = find_right_axes(left_axes, right_axes)
232
+ target_axes = right_axes
233
+ target_charts = right_charts
234
+ target_layers = right_layers
235
+
236
+ chart_class = type(layer.chart)
237
+ draw_chart = CHART_DRAWERS[chart_class]
238
+ drawn_chart = draw_chart(target_axes, layer)
239
+ target_charts.append(drawn_chart)
240
+ target_layers.append(layer)
241
+
242
+ place_value_hours(left_axes, left_layers)
243
+ right_label = None
244
+ if right_axes is not None:
245
+ place_value_hours(right_axes, right_layers)
246
+ right_label = right_charts[0].y_label
247
+
248
+ plot_axes = PlotAxes(left_axes, right_axes, right_label)
249
+
250
+ return plot_axes, left_charts[0]
251
+
252
+
253
+ def find_right_axes(left_axes: Axes, right_axes: Axes | None) -> Axes:
254
+ """
255
+ Return the axes measured on the right, created the first time a chart is drawn on them.
256
+
257
+ .. versionadded:: 0.1.0
258
+
259
+ Parameters
260
+ ----------
261
+ left_axes
262
+ The main matplotlib axes of the Plot.
263
+ right_axes
264
+ The axes on the right already created, or None.
265
+
266
+ Returns
267
+ -------
268
+ matplotlib.axes.Axes
269
+ Axes sharing the ``x`` values of the main ones, with their scale drawn on the right.
270
+
271
+ Examples
272
+ --------
273
+ >>> from matplotlib.figure import Figure, FigureBase
274
+ >>> from numdaplot.plots.drawing.plot_drawing import find_right_axes
275
+ >>> left_axes = Figure().add_subplot()
276
+ >>> right_axes = find_right_axes(left_axes, None)
277
+ >>> find_right_axes(left_axes, right_axes) is right_axes
278
+ True
279
+ """
280
+ if right_axes is not None:
281
+ return right_axes
282
+
283
+ new_axes = left_axes.twinx()
284
+ # The numdaplot look hides the line on the right, which the scale on the right needs.
285
+ right_spine = new_axes.spines["right"]
286
+ right_spine.set_visible(True)
287
+
288
+ return new_axes
@@ -0,0 +1,45 @@
1
+ """
2
+ Look every Plot is drawn with.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ BACKGROUND_COLOR = "#ffffff"
10
+ """Background color of every Plot, behind and inside its axes.
11
+
12
+ .. versionadded:: 0.1.0
13
+ """
14
+
15
+ GRID_COLOR = "#e3e3e3"
16
+ """Light gray of the grid lines, also filling the cells without value of heatmaps and missing value maps.
17
+
18
+ .. versionadded:: 0.1.0
19
+ """
20
+
21
+ THEME = dict[str, Any](
22
+ {
23
+ "font.size": 11,
24
+ "axes.titlesize": 13,
25
+ "axes.titlepad": 12,
26
+ "axes.labelsize": 11,
27
+ "axes.labelcolor": "#333333",
28
+ "axes.edgecolor": "#555555",
29
+ "axes.facecolor": BACKGROUND_COLOR,
30
+ "axes.spines.top": False,
31
+ "axes.spines.right": False,
32
+ "axes.axisbelow": True,
33
+ "xtick.color": "#555555",
34
+ "ytick.color": "#555555",
35
+ "grid.color": GRID_COLOR,
36
+ "grid.linewidth": 0.8,
37
+ "legend.frameon": False,
38
+ "lines.linewidth": 2.0,
39
+ "lines.markersize": 6.0,
40
+ }
41
+ )
42
+ """matplotlib settings applied while a Plot is drawn, never to the global matplotlib settings.
43
+
44
+ .. versionadded:: 0.1.0
45
+ """