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