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.
- numdaplot/__init__.py +506 -0
- numdaplot/arrays/__init__.py +5 -0
- numdaplot/arrays/array.py +92 -0
- numdaplot/arrays/array_arithmetic.py +404 -0
- numdaplot/arrays/array_calculation.py +143 -0
- numdaplot/arrays/array_conversion.py +150 -0
- numdaplot/arrays/array_creation.py +371 -0
- numdaplot/arrays/array_data.py +281 -0
- numdaplot/arrays/array_layout.py +179 -0
- numdaplot/arrays/array_logic.py +227 -0
- numdaplot/arrays/array_reflected_arithmetic.py +334 -0
- numdaplot/arrays/array_refusals.py +339 -0
- numdaplot/arrays/array_selection.py +195 -0
- numdaplot/arrays/array_sorting.py +59 -0
- numdaplot/arrays/axis_number.py +58 -0
- numdaplot/arrays/calculation/__init__.py +5 -0
- numdaplot/arrays/calculation/counting_statistics.py +325 -0
- numdaplot/arrays/calculation/location_statistics.py +268 -0
- numdaplot/arrays/calculation/math_function_values.py +183 -0
- numdaplot/arrays/calculation/statistic_values.py +209 -0
- numdaplot/arrays/calculation/time_function_values.py +419 -0
- numdaplot/arrays/conversion/__init__.py +5 -0
- numdaplot/arrays/conversion/array_text.py +62 -0
- numdaplot/arrays/conversion/equality_check.py +72 -0
- numdaplot/arrays/conversion/python_values.py +70 -0
- numdaplot/arrays/conversion/time_text.py +290 -0
- numdaplot/arrays/creation/__init__.py +5 -0
- numdaplot/arrays/creation/date_parts.py +89 -0
- numdaplot/arrays/creation/date_parts_values.py +437 -0
- numdaplot/arrays/creation/distribution.py +54 -0
- numdaplot/arrays/creation/filled_values.py +58 -0
- numdaplot/arrays/creation/list_conversion.py +311 -0
- numdaplot/arrays/creation/list_shape.py +97 -0
- numdaplot/arrays/creation/normal.py +65 -0
- numdaplot/arrays/creation/numpy_conversion.py +149 -0
- numdaplot/arrays/creation/random_integers.py +104 -0
- numdaplot/arrays/creation/random_values.py +97 -0
- numdaplot/arrays/creation/range_values.py +73 -0
- numdaplot/arrays/creation/spacing.py +84 -0
- numdaplot/arrays/creation/spacing_values.py +63 -0
- numdaplot/arrays/creation/uniform.py +63 -0
- numdaplot/arrays/equality.py +68 -0
- numdaplot/arrays/layout/__init__.py +5 -0
- numdaplot/arrays/layout/sorting_values.py +113 -0
- numdaplot/arrays/layout/unique_values.py +49 -0
- numdaplot/arrays/mapping/__init__.py +5 -0
- numdaplot/arrays/mapping/mapped_values.py +286 -0
- numdaplot/arrays/mapping/unmatched.py +50 -0
- numdaplot/arrays/mapping/value_change.py +55 -0
- numdaplot/arrays/mapping/value_mapping.py +161 -0
- numdaplot/arrays/math_functions/__init__.py +5 -0
- numdaplot/arrays/math_functions/absolute.py +27 -0
- numdaplot/arrays/math_functions/cosine.py +28 -0
- numdaplot/arrays/math_functions/exponential.py +27 -0
- numdaplot/arrays/math_functions/logarithm.py +72 -0
- numdaplot/arrays/math_functions/math_function.py +58 -0
- numdaplot/arrays/math_functions/round.py +58 -0
- numdaplot/arrays/math_functions/sine.py +28 -0
- numdaplot/arrays/math_functions/square_root.py +27 -0
- numdaplot/arrays/operations/__init__.py +5 -0
- numdaplot/arrays/operations/boolean_operands.py +48 -0
- numdaplot/arrays/operations/combination.py +157 -0
- numdaplot/arrays/operations/float_errors.py +170 -0
- numdaplot/arrays/operations/integer_bounds.py +175 -0
- numdaplot/arrays/operations/integer_rules.py +397 -0
- numdaplot/arrays/operations/operand.py +139 -0
- numdaplot/arrays/operations/time_arithmetic.py +479 -0
- numdaplot/arrays/operations/time_bounds.py +286 -0
- numdaplot/arrays/operations/time_result_bounds.py +397 -0
- numdaplot/arrays/operations/transformation.py +54 -0
- numdaplot/arrays/operations/type_requirements.py +94 -0
- numdaplot/arrays/replacement.py +66 -0
- numdaplot/arrays/selection/__init__.py +5 -0
- numdaplot/arrays/selection/comparison_masks.py +131 -0
- numdaplot/arrays/selection/membership_masks.py +118 -0
- numdaplot/arrays/selection/missing_mask.py +50 -0
- numdaplot/arrays/selection/region_index.py +178 -0
- numdaplot/arrays/selection/replaced_values.py +120 -0
- numdaplot/arrays/selection/rule_mask.py +83 -0
- numdaplot/arrays/selection/time_reference.py +172 -0
- numdaplot/arrays/shape.py +74 -0
- numdaplot/arrays/type_match.py +51 -0
- numdaplot/data_types/__init__.py +5 -0
- numdaplot/data_types/library.py +57 -0
- numdaplot/data_types/numpy_mapping.py +207 -0
- numdaplot/data_types/pandas_mapping.py +114 -0
- numdaplot/data_types/time_of_day.py +292 -0
- numdaplot/data_types/type.py +224 -0
- numdaplot/data_types/value_family.py +149 -0
- numdaplot/data_types/value_type.py +147 -0
- numdaplot/dates/__init__.py +5 -0
- numdaplot/dates/custom_date_format.py +83 -0
- numdaplot/dates/date_format.py +120 -0
- numdaplot/dates/date_part.py +59 -0
- numdaplot/dates/date_part_unit.py +153 -0
- numdaplot/dates/date_period.py +57 -0
- numdaplot/dates/duration_in.py +58 -0
- numdaplot/dates/duration_unit.py +90 -0
- numdaplot/dates/period_unit.py +101 -0
- numdaplot/dates/time_function.py +56 -0
- numdaplot/dates/time_zone.py +68 -0
- numdaplot/dates/time_zone_change.py +71 -0
- numdaplot/dates/time_zone_mode.py +81 -0
- numdaplot/dates/to_duration.py +58 -0
- numdaplot/errors/__init__.py +7 -0
- numdaplot/errors/broadcast_warning.py +36 -0
- numdaplot/errors/calculation_warning.py +35 -0
- numdaplot/errors/cell_out_of_range_error.py +77 -0
- numdaplot/errors/column_not_found_error.py +64 -0
- numdaplot/errors/conflicting_settings_error.py +60 -0
- numdaplot/errors/dimension_error.py +62 -0
- numdaplot/errors/display_warning.py +32 -0
- numdaplot/errors/duplicate_column_error.py +82 -0
- numdaplot/errors/duplicate_label_error.py +55 -0
- numdaplot/errors/duplicate_statistic_error.py +55 -0
- numdaplot/errors/duplicate_value_error.py +54 -0
- numdaplot/errors/empty_array_error.py +55 -0
- numdaplot/errors/empty_list_error.py +52 -0
- numdaplot/errors/empty_region_error.py +34 -0
- numdaplot/errors/empty_text_error.py +34 -0
- numdaplot/errors/empty_total_error.py +62 -0
- numdaplot/errors/empty_values_error.py +34 -0
- numdaplot/errors/file_access_error.py +70 -0
- numdaplot/errors/file_exists_error.py +62 -0
- numdaplot/errors/file_not_found_error.py +56 -0
- numdaplot/errors/incompatible_charts_error.py +80 -0
- numdaplot/errors/incompatible_types_error.py +104 -0
- numdaplot/errors/integer_overflow_error.py +61 -0
- numdaplot/errors/invalid_base_error.py +52 -0
- numdaplot/errors/invalid_bin_width_error.py +66 -0
- numdaplot/errors/invalid_bounds_error.py +58 -0
- numdaplot/errors/invalid_chart_data_error.py +81 -0
- numdaplot/errors/invalid_color_count_error.py +63 -0
- numdaplot/errors/invalid_color_error.py +51 -0
- numdaplot/errors/invalid_column_name_error.py +52 -0
- numdaplot/errors/invalid_conversion_error.py +119 -0
- numdaplot/errors/invalid_count_error.py +61 -0
- numdaplot/errors/invalid_date_format_error.py +51 -0
- numdaplot/errors/invalid_deviation_error.py +52 -0
- numdaplot/errors/invalid_fraction_error.py +51 -0
- numdaplot/errors/invalid_label_count_error.py +61 -0
- numdaplot/errors/invalid_limits_error.py +111 -0
- numdaplot/errors/invalid_opacity_error.py +52 -0
- numdaplot/errors/invalid_point_size_error.py +52 -0
- numdaplot/errors/invalid_position_error.py +106 -0
- numdaplot/errors/invalid_resolution_error.py +51 -0
- numdaplot/errors/invalid_rotation_error.py +53 -0
- numdaplot/errors/invalid_seed_error.py +53 -0
- numdaplot/errors/invalid_separator_error.py +52 -0
- numdaplot/errors/invalid_shape_error.py +52 -0
- numdaplot/errors/invalid_sheet_name_error.py +54 -0
- numdaplot/errors/invalid_size_error.py +58 -0
- numdaplot/errors/invalid_step_error.py +77 -0
- numdaplot/errors/invalid_suffixes_error.py +61 -0
- numdaplot/errors/invalid_time_zone_change_error.py +63 -0
- numdaplot/errors/invalid_type_error.py +79 -0
- numdaplot/errors/irregular_list_error.py +36 -0
- numdaplot/errors/join_relation_error.py +183 -0
- numdaplot/errors/missing_dependency_error.py +58 -0
- numdaplot/errors/missing_type_error.py +36 -0
- numdaplot/errors/missing_value_error.py +62 -0
- numdaplot/errors/not_single_value_error.py +53 -0
- numdaplot/errors/numdaplot_error.py +25 -0
- numdaplot/errors/numdaplot_warning.py +34 -0
- numdaplot/errors/occupied_cell_error.py +63 -0
- numdaplot/errors/out_of_domain_error.py +70 -0
- numdaplot/errors/readability_warning.py +35 -0
- numdaplot/errors/refused_operation_error.py +64 -0
- numdaplot/errors/refused_setting_error.py +60 -0
- numdaplot/errors/rejected_dates.py +60 -0
- numdaplot/errors/repeated_key.py +36 -0
- numdaplot/errors/shape_mismatch_error.py +67 -0
- numdaplot/errors/time_overflow_error.py +131 -0
- numdaplot/errors/time_zone_mismatch_error.py +83 -0
- numdaplot/errors/unknown_time_zone_error.py +51 -0
- numdaplot/errors/unmatched_value_error.py +81 -0
- numdaplot/errors/unsupported_image_format_error.py +56 -0
- numdaplot/errors/unsupported_index_error.py +38 -0
- numdaplot/errors/unsupported_missing_error.py +129 -0
- numdaplot/errors/unsupported_type_error.py +62 -0
- numdaplot/errors/value_conversion_error.py +215 -0
- numdaplot/ordering/__init__.py +5 -0
- numdaplot/ordering/missing_position.py +46 -0
- numdaplot/ordering/order.py +46 -0
- numdaplot/package_version.py +36 -0
- numdaplot/plots/__init__.py +5 -0
- numdaplot/plots/chart_layer.py +47 -0
- numdaplot/plots/charts/__init__.py +5 -0
- numdaplot/plots/charts/bar_chart.py +98 -0
- numdaplot/plots/charts/bar_layout.py +58 -0
- numdaplot/plots/charts/bin_count.py +61 -0
- numdaplot/plots/charts/bin_width.py +78 -0
- numdaplot/plots/charts/box_chart.py +97 -0
- numdaplot/plots/charts/cell_values.py +61 -0
- numdaplot/plots/charts/chart.py +59 -0
- numdaplot/plots/charts/chart_settings.py +105 -0
- numdaplot/plots/charts/color_scale.py +147 -0
- numdaplot/plots/charts/heatmap_chart.py +92 -0
- numdaplot/plots/charts/histogram_chart.py +93 -0
- numdaplot/plots/charts/line_chart.py +100 -0
- numdaplot/plots/charts/line_type.py +75 -0
- numdaplot/plots/charts/marker_shape.py +113 -0
- numdaplot/plots/charts/missing_chart.py +60 -0
- numdaplot/plots/charts/missing_map_chart.py +27 -0
- numdaplot/plots/charts/orientation.py +58 -0
- numdaplot/plots/charts/outliers.py +49 -0
- numdaplot/plots/charts/percentages.py +55 -0
- numdaplot/plots/charts/pie_chart.py +87 -0
- numdaplot/plots/charts/scatter_chart.py +159 -0
- numdaplot/plots/charts/value_axis.py +66 -0
- numdaplot/plots/data/__init__.py +5 -0
- numdaplot/plots/data/array_values.py +128 -0
- numdaplot/plots/data/chart_data.py +143 -0
- numdaplot/plots/data/chart_values.py +109 -0
- numdaplot/plots/data/column_reading.py +468 -0
- numdaplot/plots/data/heatmap_values.py +63 -0
- numdaplot/plots/data/missing_cells.py +165 -0
- numdaplot/plots/data/pie_values.py +215 -0
- numdaplot/plots/data/point_values.py +249 -0
- numdaplot/plots/data/position_kind.py +83 -0
- numdaplot/plots/data/renamed_layers.py +340 -0
- numdaplot/plots/data/sample_values.py +160 -0
- numdaplot/plots/data/shown_columns.py +248 -0
- numdaplot/plots/data/table_values.py +256 -0
- numdaplot/plots/data/unique_labels.py +45 -0
- numdaplot/plots/drawing/__init__.py +5 -0
- numdaplot/plots/drawing/bar_drawing.py +316 -0
- numdaplot/plots/drawing/box_drawing.py +344 -0
- numdaplot/plots/drawing/cell_merging.py +237 -0
- numdaplot/plots/drawing/chart_texts.py +124 -0
- numdaplot/plots/drawing/color_bar.py +57 -0
- numdaplot/plots/drawing/color_scale_values.py +120 -0
- numdaplot/plots/drawing/default_labels.py +41 -0
- numdaplot/plots/drawing/drawn_chart.py +50 -0
- numdaplot/plots/drawing/grid_axes.py +75 -0
- numdaplot/plots/drawing/heatmap_drawing.py +313 -0
- numdaplot/plots/drawing/histogram_drawing.py +350 -0
- numdaplot/plots/drawing/label_room.py +344 -0
- numdaplot/plots/drawing/label_thinning.py +216 -0
- numdaplot/plots/drawing/layer_alignment.py +319 -0
- numdaplot/plots/drawing/layer_colors.py +123 -0
- numdaplot/plots/drawing/line_drawing.py +85 -0
- numdaplot/plots/drawing/marker_codes.py +20 -0
- numdaplot/plots/drawing/missing_drawing.py +360 -0
- numdaplot/plots/drawing/moment_period_formatter.py +253 -0
- numdaplot/plots/drawing/pie_drawing.py +185 -0
- numdaplot/plots/drawing/plot_axes.py +38 -0
- numdaplot/plots/drawing/plot_drawing.py +288 -0
- numdaplot/plots/drawing/plot_theme.py +45 -0
- numdaplot/plots/drawing/position_axis.py +278 -0
- numdaplot/plots/drawing/scatter_drawing.py +364 -0
- numdaplot/plots/drawing/series_colors.py +177 -0
- numdaplot/plots/drawing/size_inches.py +45 -0
- numdaplot/plots/drawing/style_drawing.py +410 -0
- numdaplot/plots/drawing/text_contrast.py +44 -0
- numdaplot/plots/drawing/tick_rotation.py +354 -0
- numdaplot/plots/drawing/time_axis.py +212 -0
- numdaplot/plots/drawing/whole_numbers.py +72 -0
- numdaplot/plots/figure/__init__.py +5 -0
- numdaplot/plots/figure/cell.py +95 -0
- numdaplot/plots/figure/figure.py +256 -0
- numdaplot/plots/figure/figure_drawing.py +99 -0
- numdaplot/plots/figure/figure_style.py +60 -0
- numdaplot/plots/figure/layout.py +71 -0
- numdaplot/plots/figure/placement.py +150 -0
- numdaplot/plots/layer_reading.py +166 -0
- numdaplot/plots/output/__init__.py +5 -0
- numdaplot/plots/output/image_saving.py +187 -0
- numdaplot/plots/output/plot_display.py +181 -0
- numdaplot/plots/output/shown_object.py +45 -0
- numdaplot/plots/overlay_checks.py +245 -0
- numdaplot/plots/plot.py +31 -0
- numdaplot/plots/plot_data.py +140 -0
- numdaplot/plots/plot_distribution_creation.py +237 -0
- numdaplot/plots/plot_output.py +124 -0
- numdaplot/plots/plot_overlays.py +273 -0
- numdaplot/plots/plot_overview_creation.py +195 -0
- numdaplot/plots/plot_series_creation.py +213 -0
- numdaplot/plots/style/__init__.py +5 -0
- numdaplot/plots/style/axis_settings.py +60 -0
- numdaplot/plots/style/color.py +168 -0
- numdaplot/plots/style/custom_color.py +65 -0
- numdaplot/plots/style/grid_lines.py +49 -0
- numdaplot/plots/style/image_options.py +71 -0
- numdaplot/plots/style/legend_position.py +149 -0
- numdaplot/plots/style/plot_style.py +136 -0
- numdaplot/plots/style/size.py +70 -0
- numdaplot/plots/style/size_unit.py +62 -0
- numdaplot/positions/__init__.py +5 -0
- numdaplot/positions/axis.py +54 -0
- numdaplot/positions/index.py +51 -0
- numdaplot/positions/range.py +90 -0
- numdaplot/positions/region.py +92 -0
- numdaplot/py.typed +0 -0
- numdaplot/ratios/__init__.py +5 -0
- numdaplot/ratios/fraction.py +40 -0
- numdaplot/ratios/measure.py +48 -0
- numdaplot/rules/__init__.py +5 -0
- numdaplot/rules/between.py +78 -0
- numdaplot/rules/bounds.py +83 -0
- numdaplot/rules/case.py +48 -0
- numdaplot/rules/contains.py +63 -0
- numdaplot/rules/equal.py +43 -0
- numdaplot/rules/greater.py +39 -0
- numdaplot/rules/greater_or_equal.py +38 -0
- numdaplot/rules/is_in.py +67 -0
- numdaplot/rules/is_missing.py +25 -0
- numdaplot/rules/is_present.py +25 -0
- numdaplot/rules/less.py +39 -0
- numdaplot/rules/less_or_equal.py +38 -0
- numdaplot/rules/not_equal.py +45 -0
- numdaplot/rules/rule.py +62 -0
- numdaplot/rules/rule_values.py +44 -0
- numdaplot/rules/value_rule.py +110 -0
- numdaplot/settings/__init__.py +5 -0
- numdaplot/settings/argument_types.py +327 -0
- numdaplot/settings/field_types.py +593 -0
- numdaplot/statistics/__init__.py +5 -0
- numdaplot/statistics/count.py +71 -0
- numdaplot/statistics/count_distinct.py +27 -0
- numdaplot/statistics/counted_missing.py +46 -0
- numdaplot/statistics/maximum.py +27 -0
- numdaplot/statistics/mean.py +27 -0
- numdaplot/statistics/median.py +27 -0
- numdaplot/statistics/minimum.py +27 -0
- numdaplot/statistics/most_frequent.py +27 -0
- numdaplot/statistics/most_frequent_count.py +27 -0
- numdaplot/statistics/quantile.py +61 -0
- numdaplot/statistics/standard_deviation.py +29 -0
- numdaplot/statistics/statistic.py +63 -0
- numdaplot/statistics/sum.py +27 -0
- numdaplot/tables/__init__.py +5 -0
- numdaplot/tables/aggregation/__init__.py +5 -0
- numdaplot/tables/aggregation/aggregated_frame.py +189 -0
- numdaplot/tables/aggregation/aggregation.py +97 -0
- numdaplot/tables/aggregation/calculation.py +123 -0
- numdaplot/tables/aggregation/result_column.py +108 -0
- numdaplot/tables/aggregation/row_groups.py +96 -0
- numdaplot/tables/aggregation/statistic_name.py +122 -0
- numdaplot/tables/columns/__init__.py +5 -0
- numdaplot/tables/columns/added_column.py +89 -0
- numdaplot/tables/columns/boolean_conversion.py +144 -0
- numdaplot/tables/columns/boolean_rule.py +59 -0
- numdaplot/tables/columns/bracket_end.py +50 -0
- numdaplot/tables/columns/bracket_names.py +346 -0
- numdaplot/tables/columns/bracketed_column.py +179 -0
- numdaplot/tables/columns/brackets.py +234 -0
- numdaplot/tables/columns/chosen_columns.py +55 -0
- numdaplot/tables/columns/column_choice.py +84 -0
- numdaplot/tables/columns/column_mode.py +64 -0
- numdaplot/tables/columns/column_names.py +186 -0
- numdaplot/tables/columns/conversion.py +103 -0
- numdaplot/tables/columns/converted_column.py +669 -0
- numdaplot/tables/columns/date_conversion.py +526 -0
- numdaplot/tables/columns/date_range.py +135 -0
- numdaplot/tables/columns/name_change.py +67 -0
- numdaplot/tables/columns/new_column.py +79 -0
- numdaplot/tables/columns/number_conversion.py +281 -0
- numdaplot/tables/columns/renamed_columns.py +60 -0
- numdaplot/tables/columns/renaming.py +81 -0
- numdaplot/tables/columns/text_conversion.py +70 -0
- numdaplot/tables/columns/time_conversion.py +313 -0
- numdaplot/tables/columns/time_zone_conversion.py +128 -0
- numdaplot/tables/conflict.py +68 -0
- numdaplot/tables/description/__init__.py +5 -0
- numdaplot/tables/description/described_frame.py +335 -0
- numdaplot/tables/description/description.py +155 -0
- numdaplot/tables/duplicates/__init__.py +5 -0
- numdaplot/tables/duplicates/deduplicated_frame.py +66 -0
- numdaplot/tables/duplicates/deduplication.py +88 -0
- numdaplot/tables/duplicates/keep.py +81 -0
- numdaplot/tables/files/__init__.py +5 -0
- numdaplot/tables/files/column_names.py +60 -0
- numdaplot/tables/files/csv_file.py +265 -0
- numdaplot/tables/files/csv_read_options.py +89 -0
- numdaplot/tables/files/csv_separator.py +41 -0
- numdaplot/tables/files/csv_write_options.py +79 -0
- numdaplot/tables/files/decimal_count.py +42 -0
- numdaplot/tables/files/encoding.py +82 -0
- numdaplot/tables/files/excel_file.py +171 -0
- numdaplot/tables/files/excel_read_options.py +79 -0
- numdaplot/tables/files/excel_sheet.py +50 -0
- numdaplot/tables/files/excel_time_cells.py +146 -0
- numdaplot/tables/files/excel_write_options.py +63 -0
- numdaplot/tables/files/file_access.py +152 -0
- numdaplot/tables/files/file_paths.py +106 -0
- numdaplot/tables/files/json_decimals.py +387 -0
- numdaplot/tables/files/json_file.py +203 -0
- numdaplot/tables/files/json_layout.py +63 -0
- numdaplot/tables/files/json_read_options.py +64 -0
- numdaplot/tables/files/json_write_options.py +71 -0
- numdaplot/tables/files/missing_texts.py +63 -0
- numdaplot/tables/files/optional_package.py +42 -0
- numdaplot/tables/files/pandas_backend.py +11 -0
- numdaplot/tables/files/parquet_file.py +91 -0
- numdaplot/tables/files/parquet_read_options.py +56 -0
- numdaplot/tables/files/sas_file.py +94 -0
- numdaplot/tables/files/sas_read_options.py +67 -0
- numdaplot/tables/files/stata_file.py +83 -0
- numdaplot/tables/files/stata_read_options.py +56 -0
- numdaplot/tables/files/xpt_read_options.py +65 -0
- numdaplot/tables/filtering/__init__.py +5 -0
- numdaplot/tables/filtering/checked_frame.py +60 -0
- numdaplot/tables/filtering/column_mask.py +71 -0
- numdaplot/tables/filtering/column_match.py +62 -0
- numdaplot/tables/filtering/condition.py +94 -0
- numdaplot/tables/filtering/filter.py +74 -0
- numdaplot/tables/filtering/filter_mode.py +67 -0
- numdaplot/tables/filtering/row_mask.py +152 -0
- numdaplot/tables/filtering/rule_moments.py +164 -0
- numdaplot/tables/frames/__init__.py +5 -0
- numdaplot/tables/frames/array_frame.py +95 -0
- numdaplot/tables/frames/cleaned_names.py +132 -0
- numdaplot/tables/frames/column.py +15 -0
- numdaplot/tables/frames/column_values.py +273 -0
- numdaplot/tables/frames/frame_equality.py +130 -0
- numdaplot/tables/frames/frame_normalization.py +459 -0
- numdaplot/tables/frames/named_column_errors.py +85 -0
- numdaplot/tables/frames/pandas_decimals.py +113 -0
- numdaplot/tables/frames/region_positions.py +113 -0
- numdaplot/tables/frames/table_text.py +222 -0
- numdaplot/tables/frames/time_columns.py +345 -0
- numdaplot/tables/frames/time_range_errors.py +117 -0
- numdaplot/tables/frames/time_zones.py +271 -0
- numdaplot/tables/joining/__init__.py +5 -0
- numdaplot/tables/joining/join.py +110 -0
- numdaplot/tables/joining/join_keys.py +367 -0
- numdaplot/tables/joining/join_mode.py +93 -0
- numdaplot/tables/joining/join_relation.py +149 -0
- numdaplot/tables/joining/join_suffixes.py +71 -0
- numdaplot/tables/joining/joined_frame.py +166 -0
- numdaplot/tables/joining/joined_names.py +107 -0
- numdaplot/tables/joining/joined_rows.py +235 -0
- numdaplot/tables/joining/key_types.py +57 -0
- numdaplot/tables/joining/relation.py +78 -0
- numdaplot/tables/missing/__init__.py +5 -0
- numdaplot/tables/missing/missing_count.py +59 -0
- numdaplot/tables/missing/missing_counts.py +214 -0
- numdaplot/tables/missing/missing_drop.py +98 -0
- numdaplot/tables/missing/missing_mode.py +63 -0
- numdaplot/tables/missing/missing_ratio.py +71 -0
- numdaplot/tables/missing/missing_removal.py +257 -0
- numdaplot/tables/missing/missing_summary.py +174 -0
- numdaplot/tables/missing/ratio_comparison.py +70 -0
- numdaplot/tables/pivot/__init__.py +5 -0
- numdaplot/tables/pivot/pivot_table.py +104 -0
- numdaplot/tables/pivot/pivoted_frame.py +244 -0
- numdaplot/tables/preview/__init__.py +5 -0
- numdaplot/tables/preview/notebook_display.py +238 -0
- numdaplot/tables/preview/preview.py +100 -0
- numdaplot/tables/preview/preview_rows.py +55 -0
- numdaplot/tables/preview/shown_columns.py +62 -0
- numdaplot/tables/preview/side.py +82 -0
- numdaplot/tables/sorting/__init__.py +5 -0
- numdaplot/tables/sorting/sort_key.py +71 -0
- numdaplot/tables/sorting/sorted_frame.py +81 -0
- numdaplot/tables/sorting/sorting.py +82 -0
- numdaplot/tables/table.py +71 -0
- numdaplot/tables/table_calculation.py +172 -0
- numdaplot/tables/table_columns.py +214 -0
- numdaplot/tables/table_conversion.py +351 -0
- numdaplot/tables/table_data.py +321 -0
- numdaplot/tables/table_display.py +56 -0
- numdaplot/tables/table_joining.py +80 -0
- numdaplot/tables/table_layout.py +105 -0
- numdaplot/tables/table_missing.py +146 -0
- numdaplot/tables/table_reading.py +451 -0
- numdaplot/tables/table_refusals.py +295 -0
- numdaplot/tables/table_selection.py +163 -0
- numdaplot/tables/table_writing.py +269 -0
- numdaplot-0.1.0.dist-info/METADATA +176 -0
- numdaplot-0.1.0.dist-info/RECORD +474 -0
- numdaplot-0.1.0.dist-info/WHEEL +4 -0
- numdaplot-0.1.0.dist-info/licenses/LICENSE +28 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Values of a HeatmapChart.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from numdaplot.arrays.array import Array
|
|
8
|
+
from numdaplot.plots.charts.heatmap_chart import HeatmapChart
|
|
9
|
+
from numdaplot.plots.data.array_values import read_array_values
|
|
10
|
+
from numdaplot.plots.data.chart_data import require_column_setting, require_no_column_settings
|
|
11
|
+
from numdaplot.plots.data.chart_values import ChartValues
|
|
12
|
+
from numdaplot.plots.data.table_values import read_table_values
|
|
13
|
+
from numdaplot.tables.table import Table
|
|
14
|
+
|
|
15
|
+
CHART_NAME = "HeatmapChart"
|
|
16
|
+
COLUMNS_SETTING = "columns"
|
|
17
|
+
LABELS_SETTING = "labels"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def read_heatmap_values(data: Table | Array, chart: HeatmapChart) -> ChartValues:
|
|
21
|
+
"""
|
|
22
|
+
Return the row labels and the columns a HeatmapChart draws.
|
|
23
|
+
|
|
24
|
+
.. versionadded:: 0.1.0
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
data
|
|
29
|
+
The Table or the Array drawn.
|
|
30
|
+
chart
|
|
31
|
+
The ``columns`` and the ``labels`` of a Table.
|
|
32
|
+
|
|
33
|
+
Returns
|
|
34
|
+
-------
|
|
35
|
+
ChartValues
|
|
36
|
+
The row labels as positions, and one series per column.
|
|
37
|
+
|
|
38
|
+
Raises
|
|
39
|
+
------
|
|
40
|
+
InvalidChartDataError
|
|
41
|
+
When a Table has no ``columns``, or an Array has ``columns`` or ``labels``.
|
|
42
|
+
|
|
43
|
+
Examples
|
|
44
|
+
--------
|
|
45
|
+
>>> import numdaplot as ndp
|
|
46
|
+
>>> from numdaplot.plots.data.heatmap_values import read_heatmap_values
|
|
47
|
+
>>> grid = ndp.Array.from_list([[1.0, 2.0], [3.0, 4.0]])
|
|
48
|
+
>>> try:
|
|
49
|
+
... read_heatmap_values(grid, ndp.HeatmapChart(labels="city"))
|
|
50
|
+
... except ndp.InvalidChartDataError as error:
|
|
51
|
+
... print(error)
|
|
52
|
+
HeatmapChart takes no labels for an Array.
|
|
53
|
+
"""
|
|
54
|
+
if isinstance(data, Array):
|
|
55
|
+
column_settings = dict[str, object]({COLUMNS_SETTING: chart.columns, LABELS_SETTING: chart.labels})
|
|
56
|
+
require_no_column_settings(CHART_NAME, column_settings)
|
|
57
|
+
array_values = read_array_values(data, CHART_NAME)
|
|
58
|
+
return array_values
|
|
59
|
+
|
|
60
|
+
column_names = require_column_setting(CHART_NAME, COLUMNS_SETTING, chart.columns)
|
|
61
|
+
table_values = read_table_values(data, chart.labels, column_names, CHART_NAME)
|
|
62
|
+
|
|
63
|
+
return table_values
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Missing values of a Table, read to be drawn.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
import numpy
|
|
10
|
+
from numpy.typing import NDArray
|
|
11
|
+
|
|
12
|
+
from numdaplot.data_types.type import Type
|
|
13
|
+
from numdaplot.plots.data.chart_values import ChartValues, Positions, Series
|
|
14
|
+
from numdaplot.plots.data.position_kind import PositionKind
|
|
15
|
+
from numdaplot.positions.axis import Axis
|
|
16
|
+
from numdaplot.ratios.measure import Measure
|
|
17
|
+
from numdaplot.tables.missing.missing_count import MissingCount
|
|
18
|
+
from numdaplot.tables.missing.missing_counts import (
|
|
19
|
+
COLUMN_NAMES_COLUMN,
|
|
20
|
+
MEASURE_COLUMN_NAMES,
|
|
21
|
+
count_frame_missing,
|
|
22
|
+
find_frame_missing,
|
|
23
|
+
)
|
|
24
|
+
from numdaplot.tables.table import Table
|
|
25
|
+
from numdaplot.tables.table_data import read_stored_frame
|
|
26
|
+
|
|
27
|
+
MEASURE_LABELS = {
|
|
28
|
+
Measure.COUNT: "Missing count",
|
|
29
|
+
Measure.RATIO: "Missing ratio",
|
|
30
|
+
}
|
|
31
|
+
FLOAT_DTYPE = numpy.dtype(numpy.float64)
|
|
32
|
+
COLUMN_SUM_AXIS = 0
|
|
33
|
+
COLUMN_AXIS_NAME = "Column"
|
|
34
|
+
TEXT_DTYPE = numpy.dtype(object)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(frozen=True, eq=False)
|
|
38
|
+
class MissingCounts(ChartValues):
|
|
39
|
+
"""
|
|
40
|
+
The bars of the missing values of each column, with what their labels show.
|
|
41
|
+
|
|
42
|
+
.. versionadded:: 0.1.0
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
positions
|
|
47
|
+
The column names.
|
|
48
|
+
series
|
|
49
|
+
The single series of bars, in the chosen measure.
|
|
50
|
+
rows
|
|
51
|
+
The number of each column.
|
|
52
|
+
value_name
|
|
53
|
+
The label of the axis of the values.
|
|
54
|
+
value_type
|
|
55
|
+
``FLOAT64``, the type of the counts and the shares.
|
|
56
|
+
counts
|
|
57
|
+
The number of missing values of each column.
|
|
58
|
+
row_count
|
|
59
|
+
The number of rows of the Table.
|
|
60
|
+
|
|
61
|
+
Examples
|
|
62
|
+
--------
|
|
63
|
+
>>> import numdaplot as ndp
|
|
64
|
+
>>> from numdaplot.plots.data.missing_cells import read_missing_counts
|
|
65
|
+
>>> prices = ndp.Array.from_list([12.0, None])
|
|
66
|
+
>>> flats = ndp.Table.from_arrays({"price": prices})
|
|
67
|
+
>>> read_missing_counts(flats, ndp.Measure.RATIO).counts
|
|
68
|
+
array([1.])
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
counts: NDArray[numpy.float64]
|
|
72
|
+
row_count: int
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def read_missing_counts(table: Table, measure: Measure) -> MissingCounts:
|
|
76
|
+
"""
|
|
77
|
+
Return the number or the share of missing values of each column of a Table, as one series of bars.
|
|
78
|
+
|
|
79
|
+
.. versionadded:: 0.1.0
|
|
80
|
+
|
|
81
|
+
Parameters
|
|
82
|
+
----------
|
|
83
|
+
table
|
|
84
|
+
The Table counted.
|
|
85
|
+
measure
|
|
86
|
+
``Measure.COUNT`` for the number of missing values, ``Measure.RATIO`` for their share.
|
|
87
|
+
|
|
88
|
+
Returns
|
|
89
|
+
-------
|
|
90
|
+
MissingCounts
|
|
91
|
+
The column names as text positions, the chosen measure as a single series, ``"Missing count"`` or
|
|
92
|
+
``"Missing ratio"`` as label of the axis of the values, and the counts for the labels of the bars.
|
|
93
|
+
|
|
94
|
+
Examples
|
|
95
|
+
--------
|
|
96
|
+
>>> import numdaplot as ndp
|
|
97
|
+
>>> from numdaplot.plots.data.missing_cells import read_missing_counts
|
|
98
|
+
>>> prices = ndp.Array.from_list([12.0, None])
|
|
99
|
+
>>> rooms = ndp.Array.from_list([2, 3])
|
|
100
|
+
>>> flats = ndp.Table.from_arrays({"price": prices, "rooms": rooms})
|
|
101
|
+
>>> read_missing_counts(flats, ndp.Measure.RATIO).series[0].values
|
|
102
|
+
array([0.5, 0. ])
|
|
103
|
+
"""
|
|
104
|
+
frame = read_stored_frame(table)
|
|
105
|
+
missing_count = MissingCount(measure=measure)
|
|
106
|
+
counts_frame = count_frame_missing(frame, missing_count, Axis.EACH_COLUMN)
|
|
107
|
+
count_name = MEASURE_COLUMN_NAMES[measure]
|
|
108
|
+
column_names = counts_frame[COLUMN_NAMES_COLUMN].to_numpy(dtype=TEXT_DTYPE)
|
|
109
|
+
shown_values = counts_frame[count_name].to_numpy(dtype=FLOAT_DTYPE, na_value=numpy.nan)
|
|
110
|
+
missing_grid = find_frame_missing(frame)
|
|
111
|
+
counts = missing_grid.sum(axis=COLUMN_SUM_AXIS, dtype=FLOAT_DTYPE)
|
|
112
|
+
row_count = len(frame)
|
|
113
|
+
column_count = len(column_names)
|
|
114
|
+
rows = numpy.arange(column_count)
|
|
115
|
+
positions = Positions(PositionKind.TEXTS, column_names, COLUMN_AXIS_NAME)
|
|
116
|
+
count_series = Series(count_name, shown_values)
|
|
117
|
+
measure_label = MEASURE_LABELS[measure]
|
|
118
|
+
count_values = MissingCounts(positions, [count_series], rows, measure_label, Type.FLOAT64, counts, row_count)
|
|
119
|
+
|
|
120
|
+
return count_values
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def read_missing_cells(table: Table) -> ChartValues:
|
|
124
|
+
"""
|
|
125
|
+
Return where the values of a Table are missing, 1 for a missing value and 0 for a present one.
|
|
126
|
+
|
|
127
|
+
.. versionadded:: 0.1.0
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
table
|
|
132
|
+
The Table read.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
ChartValues
|
|
137
|
+
The row numbers as positions, and one series per column.
|
|
138
|
+
|
|
139
|
+
Examples
|
|
140
|
+
--------
|
|
141
|
+
>>> import numdaplot as ndp
|
|
142
|
+
>>> from numdaplot.plots.data.missing_cells import read_missing_cells
|
|
143
|
+
>>> prices = ndp.Array.from_list([12.0, None])
|
|
144
|
+
>>> flats = ndp.Table.from_arrays({"price": prices})
|
|
145
|
+
>>> read_missing_cells(flats).series[0].values
|
|
146
|
+
array([0., 1.])
|
|
147
|
+
"""
|
|
148
|
+
frame = read_stored_frame(table)
|
|
149
|
+
missing_grid = find_frame_missing(frame)
|
|
150
|
+
cells = missing_grid.astype(FLOAT_DTYPE)
|
|
151
|
+
column_names = frame.columns.tolist()
|
|
152
|
+
row_count = len(frame)
|
|
153
|
+
rows = numpy.arange(row_count)
|
|
154
|
+
row_numbers = rows.astype(FLOAT_DTYPE)
|
|
155
|
+
positions = Positions(PositionKind.NUMBERS, row_numbers, None)
|
|
156
|
+
series = list[Series]()
|
|
157
|
+
|
|
158
|
+
for i, column_name in enumerate(column_names):
|
|
159
|
+
column_cells = cells[:, i]
|
|
160
|
+
column_series = Series(column_name, column_cells)
|
|
161
|
+
series.append(column_series)
|
|
162
|
+
|
|
163
|
+
cell_values = ChartValues(positions, series, rows, None, Type.FLOAT64)
|
|
164
|
+
|
|
165
|
+
return cell_values
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Values a PieChart shares out, read from a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import warnings
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
import numpy
|
|
11
|
+
import pandas
|
|
12
|
+
from numpy.typing import NDArray
|
|
13
|
+
|
|
14
|
+
from numdaplot.errors.empty_total_error import EmptyTotalError
|
|
15
|
+
from numdaplot.errors.missing_value_error import MissingValueError
|
|
16
|
+
from numdaplot.errors.out_of_domain_error import OutOfDomainError
|
|
17
|
+
from numdaplot.errors.readability_warning import ReadabilityWarning
|
|
18
|
+
from numdaplot.plots.charts.pie_chart import PieChart
|
|
19
|
+
from numdaplot.plots.data.chart_values import ChartValues, Positions, Series
|
|
20
|
+
from numdaplot.plots.data.column_reading import read_numbers, read_texts
|
|
21
|
+
from numdaplot.plots.data.position_kind import PositionKind
|
|
22
|
+
from numdaplot.plots.data.unique_labels import require_unique_labels
|
|
23
|
+
from numdaplot.tables.columns.column_names import require_known_columns
|
|
24
|
+
from numdaplot.tables.frames.column_values import find_column_type
|
|
25
|
+
from numdaplot.tables.table import Table
|
|
26
|
+
from numdaplot.tables.table_data import read_stored_frame
|
|
27
|
+
|
|
28
|
+
CHART_NAME = "PieChart"
|
|
29
|
+
MAXIMUM_READABLE_SLICES = 5
|
|
30
|
+
READABILITY_START = "A PieChart with {slice_count} slices is hard to read."
|
|
31
|
+
READABILITY_ADVICE = "Try ndp.Plot.bar with a BarChart, it may compare them better."
|
|
32
|
+
READABILITY_MESSAGE = f"{READABILITY_START} {READABILITY_ADVICE}"
|
|
33
|
+
# The warning points at the line calling Plot.pie, above warn_slice_count, read_pie_values, Plot.pie and its check.
|
|
34
|
+
READABILITY_STACK_LEVEL = 5
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def read_pie_values(table: Table, chart: PieChart) -> ChartValues:
|
|
38
|
+
"""
|
|
39
|
+
Return the labels and the values of the slices of a PieChart, after checking that they can be shared out.
|
|
40
|
+
|
|
41
|
+
.. versionadded:: 0.1.0
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
table
|
|
46
|
+
The Table drawn.
|
|
47
|
+
chart
|
|
48
|
+
The ``labels`` and ``values`` columns.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
ChartValues
|
|
53
|
+
The labels as text positions, and the values as a single series.
|
|
54
|
+
|
|
55
|
+
Raises
|
|
56
|
+
------
|
|
57
|
+
ColumnNotFoundError
|
|
58
|
+
When a column does not exist.
|
|
59
|
+
IncompatibleTypesError
|
|
60
|
+
When ``labels`` does not hold texts, or ``values`` does not hold numbers.
|
|
61
|
+
MissingValueError
|
|
62
|
+
When a label or a value is missing.
|
|
63
|
+
OutOfDomainError
|
|
64
|
+
When a value is negative.
|
|
65
|
+
EmptyTotalError
|
|
66
|
+
When the values add up to 0.
|
|
67
|
+
DuplicateLabelError
|
|
68
|
+
When two slices have the same label.
|
|
69
|
+
|
|
70
|
+
Warns
|
|
71
|
+
-----
|
|
72
|
+
ReadabilityWarning
|
|
73
|
+
When there are more than 5 slices.
|
|
74
|
+
|
|
75
|
+
Examples
|
|
76
|
+
--------
|
|
77
|
+
>>> import numdaplot as ndp
|
|
78
|
+
>>> from numdaplot.plots.data.pie_values import read_pie_values
|
|
79
|
+
>>> cities = ndp.Array.from_list(["Paris", "Lyon"])
|
|
80
|
+
>>> sales = ndp.Array.from_list([120.0, 80.0])
|
|
81
|
+
>>> shares = ndp.Table.from_arrays({"city": cities, "sales": sales})
|
|
82
|
+
>>> read_pie_values(shares, ndp.PieChart(labels="city", values="sales")).series[0].values
|
|
83
|
+
array([120., 80.])
|
|
84
|
+
"""
|
|
85
|
+
labels_name = chart.labels
|
|
86
|
+
values_name = chart.values
|
|
87
|
+
frame = read_stored_frame(table)
|
|
88
|
+
known_names = frame.columns.tolist()
|
|
89
|
+
require_known_columns([labels_name, values_name], known_names)
|
|
90
|
+
labels = read_texts(frame[labels_name], CHART_NAME)
|
|
91
|
+
numbers = read_numbers(frame[values_name], CHART_NAME)
|
|
92
|
+
require_present_values(labels, labels_name)
|
|
93
|
+
require_present_values(numbers, values_name)
|
|
94
|
+
require_unique_labels(labels)
|
|
95
|
+
require_shares(numbers, values_name)
|
|
96
|
+
slice_count = len(labels)
|
|
97
|
+
warn_slice_count(slice_count)
|
|
98
|
+
rows = numpy.arange(slice_count)
|
|
99
|
+
positions = Positions(PositionKind.TEXTS, labels, labels_name)
|
|
100
|
+
values_series = Series(values_name, numbers)
|
|
101
|
+
values_column = frame[values_name]
|
|
102
|
+
values_type = find_column_type(values_column)
|
|
103
|
+
pie_values = ChartValues(positions, [values_series], rows, values_name, values_type)
|
|
104
|
+
|
|
105
|
+
return pie_values
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def require_present_values(values: NDArray[Any], column_name: str) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Check that a column drawn by a PieChart has no missing value.
|
|
111
|
+
|
|
112
|
+
.. versionadded:: 0.1.0
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
values
|
|
117
|
+
The labels, None where missing, or the numbers, NaN where missing.
|
|
118
|
+
column_name
|
|
119
|
+
The column read, shown in the error message.
|
|
120
|
+
|
|
121
|
+
Raises
|
|
122
|
+
------
|
|
123
|
+
MissingValueError
|
|
124
|
+
When a value is missing.
|
|
125
|
+
|
|
126
|
+
Examples
|
|
127
|
+
--------
|
|
128
|
+
>>> import numpy
|
|
129
|
+
>>> import numdaplot as ndp
|
|
130
|
+
>>> from numdaplot.plots.data.pie_values import require_present_values
|
|
131
|
+
>>> try:
|
|
132
|
+
... require_present_values(numpy.array([120.0, numpy.nan]), "sales")
|
|
133
|
+
... except ndp.MissingValueError as error:
|
|
134
|
+
... print(error)
|
|
135
|
+
PieChart cannot draw a missing value, found one in 'sales'.
|
|
136
|
+
"""
|
|
137
|
+
missing = pandas.isna(values)
|
|
138
|
+
has_missing = bool(missing.any())
|
|
139
|
+
if has_missing:
|
|
140
|
+
raise MissingValueError(CHART_NAME, column_name)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def require_shares(numbers: NDArray[numpy.float64], column_name: str) -> None:
|
|
144
|
+
"""
|
|
145
|
+
Check that the values of a PieChart can be shared out: none is negative and their total is above 0.
|
|
146
|
+
|
|
147
|
+
.. versionadded:: 0.1.0
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
numbers
|
|
152
|
+
The value of each slice, none missing.
|
|
153
|
+
column_name
|
|
154
|
+
The column of the values, shown in the error message.
|
|
155
|
+
|
|
156
|
+
Raises
|
|
157
|
+
------
|
|
158
|
+
OutOfDomainError
|
|
159
|
+
At the first negative value.
|
|
160
|
+
EmptyTotalError
|
|
161
|
+
When the values add up to 0.
|
|
162
|
+
|
|
163
|
+
Examples
|
|
164
|
+
--------
|
|
165
|
+
>>> import numpy
|
|
166
|
+
>>> import numdaplot as ndp
|
|
167
|
+
>>> from numdaplot.plots.data.pie_values import require_shares
|
|
168
|
+
>>> try:
|
|
169
|
+
... require_shares(numpy.array([120.0, -3.0]), "sales")
|
|
170
|
+
... except ndp.OutOfDomainError as error:
|
|
171
|
+
... print(error)
|
|
172
|
+
PieChart is not defined for -3.0.
|
|
173
|
+
"""
|
|
174
|
+
negative_numbers = numbers[numbers < 0]
|
|
175
|
+
negative_count = len(negative_numbers)
|
|
176
|
+
if negative_count > 0:
|
|
177
|
+
first_negative = float(negative_numbers[0])
|
|
178
|
+
raise OutOfDomainError(CHART_NAME, first_negative)
|
|
179
|
+
|
|
180
|
+
total = numbers.sum()
|
|
181
|
+
if total == 0:
|
|
182
|
+
raise EmptyTotalError(CHART_NAME, column_name)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def warn_slice_count(slice_count: int) -> None:
|
|
186
|
+
"""
|
|
187
|
+
Emit a ReadabilityWarning when a PieChart has more than 5 slices.
|
|
188
|
+
|
|
189
|
+
.. versionadded:: 0.1.0
|
|
190
|
+
|
|
191
|
+
Parameters
|
|
192
|
+
----------
|
|
193
|
+
slice_count
|
|
194
|
+
The number of slices.
|
|
195
|
+
|
|
196
|
+
Warns
|
|
197
|
+
-----
|
|
198
|
+
ReadabilityWarning
|
|
199
|
+
When there are more than 5 slices.
|
|
200
|
+
|
|
201
|
+
Examples
|
|
202
|
+
--------
|
|
203
|
+
>>> import warnings
|
|
204
|
+
>>> from numdaplot.plots.data.pie_values import warn_slice_count
|
|
205
|
+
>>> with warnings.catch_warnings(record=True) as caught_warnings:
|
|
206
|
+
... warnings.simplefilter("always")
|
|
207
|
+
... warn_slice_count(6)
|
|
208
|
+
>>> print(caught_warnings[0].message)
|
|
209
|
+
A PieChart with 6 slices is hard to read. Try ndp.Plot.bar with a BarChart, it may compare them better.
|
|
210
|
+
"""
|
|
211
|
+
if slice_count <= MAXIMUM_READABLE_SLICES:
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
message = READABILITY_MESSAGE.format(slice_count=slice_count)
|
|
215
|
+
warnings.warn(message, ReadabilityWarning, stacklevel=READABILITY_STACK_LEVEL)
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Values coloring and sizing the points of a ScatterChart.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass, replace
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
import numpy
|
|
11
|
+
import pandas
|
|
12
|
+
from numpy.typing import NDArray
|
|
13
|
+
|
|
14
|
+
from numdaplot.data_types.value_family import ValueFamily
|
|
15
|
+
from numdaplot.errors.refused_setting_error import RefusedSettingError
|
|
16
|
+
from numdaplot.plots.charts.color_scale import ColorScale
|
|
17
|
+
from numdaplot.plots.data.chart_values import ChartValues, Series
|
|
18
|
+
from numdaplot.plots.data.column_reading import read_numbers, read_texts, require_column_family
|
|
19
|
+
from numdaplot.tables.columns.column_names import require_known_columns
|
|
20
|
+
from numdaplot.tables.frames.column import Column
|
|
21
|
+
from numdaplot.tables.table import Table
|
|
22
|
+
from numdaplot.tables.table_data import read_stored_frame
|
|
23
|
+
|
|
24
|
+
CHART_NAME = "ScatterChart"
|
|
25
|
+
NUMBER_COLORS_DTYPE = numpy.dtype(numpy.float64)
|
|
26
|
+
SCALE_ON_TEXTS = "scale without a color_by column of numbers"
|
|
27
|
+
COLOR_FAMILIES = frozenset({ValueFamily.NUMBER, ValueFamily.TEXT, ValueFamily.BOOL, ValueFamily.TIME})
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True, eq=False)
|
|
31
|
+
class PointValues:
|
|
32
|
+
"""
|
|
33
|
+
The values coloring and sizing each point of a ScatterChart, one per drawn row.
|
|
34
|
+
|
|
35
|
+
.. versionadded:: 0.1.0
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
color_name
|
|
40
|
+
The ``color_by`` column, or None.
|
|
41
|
+
colors
|
|
42
|
+
Its values: float64 numbers or texts, or None.
|
|
43
|
+
size_name
|
|
44
|
+
The ``size_by`` column, or None.
|
|
45
|
+
sizes
|
|
46
|
+
Its float64 numbers, or None.
|
|
47
|
+
|
|
48
|
+
Examples
|
|
49
|
+
--------
|
|
50
|
+
>>> import numpy
|
|
51
|
+
>>> from numdaplot.plots.data.point_values import PointValues
|
|
52
|
+
>>> PointValues("city", numpy.array(["Paris"], dtype=object), None, None).color_name
|
|
53
|
+
'city'
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
color_name: str | None
|
|
57
|
+
colors: NDArray[Any] | None
|
|
58
|
+
size_name: str | None
|
|
59
|
+
sizes: NDArray[numpy.float64] | None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def read_point_values(
|
|
63
|
+
table: Table, color_name: str | None, size_name: str | None, rows: NDArray[numpy.intp]
|
|
64
|
+
) -> PointValues:
|
|
65
|
+
"""
|
|
66
|
+
Return the values of the ``color_by`` and ``size_by`` columns of a ScatterChart for the drawn rows.
|
|
67
|
+
|
|
68
|
+
.. versionadded:: 0.1.0
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
table
|
|
73
|
+
The Table drawn.
|
|
74
|
+
color_name
|
|
75
|
+
The ``color_by`` column, or None.
|
|
76
|
+
size_name
|
|
77
|
+
The ``size_by`` column, or None.
|
|
78
|
+
rows
|
|
79
|
+
The row numbers drawn.
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
PointValues
|
|
84
|
+
The values of each column given, in the order of the drawn rows.
|
|
85
|
+
|
|
86
|
+
Raises
|
|
87
|
+
------
|
|
88
|
+
ColumnNotFoundError
|
|
89
|
+
When a column does not exist.
|
|
90
|
+
IncompatibleTypesError
|
|
91
|
+
When ``color_by`` holds neither numbers nor texts, or ``size_by`` does not hold numbers.
|
|
92
|
+
|
|
93
|
+
Examples
|
|
94
|
+
--------
|
|
95
|
+
>>> import numpy
|
|
96
|
+
>>> import numdaplot as ndp
|
|
97
|
+
>>> from numdaplot.plots.data.point_values import read_point_values
|
|
98
|
+
>>> surfaces = ndp.Array.from_list([30.0, 45.0])
|
|
99
|
+
>>> cities = ndp.Array.from_list(["Paris", "Lyon"])
|
|
100
|
+
>>> flats = ndp.Table.from_arrays({"surface": surfaces, "city": cities})
|
|
101
|
+
>>> read_point_values(flats, "city", "surface", numpy.arange(2)).sizes
|
|
102
|
+
array([30., 45.])
|
|
103
|
+
"""
|
|
104
|
+
frame = read_stored_frame(table)
|
|
105
|
+
column_names = frame.columns.tolist()
|
|
106
|
+
colors = None
|
|
107
|
+
sizes = None
|
|
108
|
+
if color_name is not None:
|
|
109
|
+
require_known_columns([color_name], column_names)
|
|
110
|
+
all_colors = read_colors(frame[color_name])
|
|
111
|
+
colors = all_colors[rows]
|
|
112
|
+
|
|
113
|
+
if size_name is not None:
|
|
114
|
+
require_known_columns([size_name], column_names)
|
|
115
|
+
all_sizes = read_numbers(frame[size_name], CHART_NAME)
|
|
116
|
+
sizes = all_sizes[rows]
|
|
117
|
+
|
|
118
|
+
point_values = PointValues(color_name, colors, size_name, sizes)
|
|
119
|
+
|
|
120
|
+
return point_values
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def require_scale_on_numbers(scale: ColorScale | None, colors: NDArray[Any] | None) -> None:
|
|
124
|
+
"""
|
|
125
|
+
Check that a color scale colors numbers.
|
|
126
|
+
|
|
127
|
+
.. versionadded:: 0.1.0
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
scale
|
|
132
|
+
The ``scale`` of a ScatterChart, or None.
|
|
133
|
+
colors
|
|
134
|
+
The values of its ``color_by`` column, float64 numbers or texts.
|
|
135
|
+
|
|
136
|
+
Raises
|
|
137
|
+
------
|
|
138
|
+
RefusedSettingError
|
|
139
|
+
When a scale is given for texts or booleans, which take one color per value.
|
|
140
|
+
|
|
141
|
+
Examples
|
|
142
|
+
--------
|
|
143
|
+
>>> import numpy
|
|
144
|
+
>>> import numdaplot as ndp
|
|
145
|
+
>>> from numdaplot.plots.data.point_values import require_scale_on_numbers
|
|
146
|
+
>>> require_scale_on_numbers(ndp.ColorScale.BLUES, numpy.array([1.5]))
|
|
147
|
+
>>> try:
|
|
148
|
+
... require_scale_on_numbers(ndp.ColorScale.BLUES, numpy.array(["Paris"], dtype=object))
|
|
149
|
+
... except ndp.RefusedSettingError as error:
|
|
150
|
+
... print(error)
|
|
151
|
+
ScatterChart does not accept scale without a color_by column of numbers.
|
|
152
|
+
"""
|
|
153
|
+
if scale is None or colors is None:
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
if colors.dtype != NUMBER_COLORS_DTYPE:
|
|
157
|
+
raise RefusedSettingError(SCALE_ON_TEXTS, CHART_NAME)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def read_colors(column: Column) -> NDArray[Any]:
|
|
161
|
+
"""
|
|
162
|
+
Return the values of a ``color_by`` column: float64 numbers or texts.
|
|
163
|
+
|
|
164
|
+
.. versionadded:: 0.1.0
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
column
|
|
169
|
+
A Table column.
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
NDArray
|
|
174
|
+
Numbers with NaN, or texts with None, where a value is missing.
|
|
175
|
+
|
|
176
|
+
Raises
|
|
177
|
+
------
|
|
178
|
+
IncompatibleTypesError
|
|
179
|
+
When the column holds neither numbers, texts, booleans nor times of day.
|
|
180
|
+
|
|
181
|
+
Examples
|
|
182
|
+
--------
|
|
183
|
+
>>> import pandas
|
|
184
|
+
>>> from numdaplot.plots.data.point_values import read_colors
|
|
185
|
+
>>> read_colors(pandas.Series([2.5, None], dtype="float64"))
|
|
186
|
+
array([2.5, nan])
|
|
187
|
+
"""
|
|
188
|
+
family = require_column_family(column, COLOR_FAMILIES, CHART_NAME)
|
|
189
|
+
if family == ValueFamily.NUMBER:
|
|
190
|
+
numbers = read_numbers(column, CHART_NAME)
|
|
191
|
+
return numbers
|
|
192
|
+
|
|
193
|
+
texts = read_texts(column, CHART_NAME)
|
|
194
|
+
|
|
195
|
+
return texts
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def hide_missing_points(chart_values: ChartValues, point_values: PointValues) -> ChartValues:
|
|
199
|
+
"""
|
|
200
|
+
Return the values of a ScatterChart without the points whose color or size value is missing.
|
|
201
|
+
|
|
202
|
+
.. versionadded:: 0.1.0
|
|
203
|
+
|
|
204
|
+
Parameters
|
|
205
|
+
----------
|
|
206
|
+
chart_values
|
|
207
|
+
The positions and the series.
|
|
208
|
+
point_values
|
|
209
|
+
The values coloring and sizing the points.
|
|
210
|
+
|
|
211
|
+
Returns
|
|
212
|
+
-------
|
|
213
|
+
ChartValues
|
|
214
|
+
The same values, NaN in the series where a color or size value is missing.
|
|
215
|
+
|
|
216
|
+
Examples
|
|
217
|
+
--------
|
|
218
|
+
>>> import numpy
|
|
219
|
+
>>> import numdaplot as ndp
|
|
220
|
+
>>> from numdaplot.plots.data.chart_values import ChartValues, Positions, Series
|
|
221
|
+
>>> from numdaplot.plots.data.point_values import PointValues, hide_missing_points
|
|
222
|
+
>>> from numdaplot.plots.data.position_kind import PositionKind
|
|
223
|
+
>>> positions = Positions(PositionKind.NUMBERS, numpy.array([0.0, 1.0]), None)
|
|
224
|
+
>>> price_series = Series("price", numpy.array([1.0, 2.0]))
|
|
225
|
+
>>> chart_values = ChartValues(positions, [price_series], numpy.arange(2), "price", ndp.Type.FLOAT64)
|
|
226
|
+
>>> point_values = PointValues(None, None, "surface", numpy.array([30.0, numpy.nan]))
|
|
227
|
+
>>> hide_missing_points(chart_values, point_values).series[0].values
|
|
228
|
+
array([ 1., nan])
|
|
229
|
+
"""
|
|
230
|
+
row_count = len(chart_values.rows)
|
|
231
|
+
missing = numpy.zeros(row_count, dtype=numpy.bool_)
|
|
232
|
+
|
|
233
|
+
for point_column in (point_values.colors, point_values.sizes):
|
|
234
|
+
if point_column is None:
|
|
235
|
+
continue
|
|
236
|
+
|
|
237
|
+
missing_values = pandas.isna(point_column)
|
|
238
|
+
missing = missing | missing_values
|
|
239
|
+
|
|
240
|
+
shown_series = list[Series]()
|
|
241
|
+
|
|
242
|
+
for series in chart_values.series:
|
|
243
|
+
shown_numbers = numpy.where(missing, numpy.nan, series.values)
|
|
244
|
+
series_copy = Series(series.name, shown_numbers)
|
|
245
|
+
shown_series.append(series_copy)
|
|
246
|
+
|
|
247
|
+
shown_values = replace(chart_values, series=shown_series)
|
|
248
|
+
|
|
249
|
+
return shown_values
|