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,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Place of a Plot in the grid of a Figure.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.errors.invalid_count_error import InvalidCountError
|
|
10
|
+
from numdaplot.errors.invalid_position_error import InvalidPositionError
|
|
11
|
+
from numdaplot.settings.field_types import require_field_types
|
|
12
|
+
|
|
13
|
+
MINIMUM_SPAN = 1
|
|
14
|
+
FIRST_POSITION = 0
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class Cell:
|
|
19
|
+
"""
|
|
20
|
+
Place of a Plot in the grid of a ``Figure``: its first cell, and how many cells it spans.
|
|
21
|
+
|
|
22
|
+
Rows and columns are numbered from 0, row 0 at the top and column 0 on the left.
|
|
23
|
+
|
|
24
|
+
.. versionadded:: 0.1.0
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
row
|
|
29
|
+
The row of the top cell, from 0.
|
|
30
|
+
column
|
|
31
|
+
The column of the left cell, from 0.
|
|
32
|
+
row_span
|
|
33
|
+
The number of rows covered, 1 by default.
|
|
34
|
+
column_span
|
|
35
|
+
The number of columns covered, 1 by default.
|
|
36
|
+
|
|
37
|
+
Raises
|
|
38
|
+
------
|
|
39
|
+
InvalidTypeError
|
|
40
|
+
When a setting is not of the type its annotation names.
|
|
41
|
+
InvalidPositionError
|
|
42
|
+
When ``row`` or ``column`` is lower than 0.
|
|
43
|
+
InvalidCountError
|
|
44
|
+
When ``row_span`` or ``column_span`` is lower than 1.
|
|
45
|
+
|
|
46
|
+
Examples
|
|
47
|
+
--------
|
|
48
|
+
>>> import numdaplot as ndp
|
|
49
|
+
>>> months = ndp.Array.from_list([1, 2, 3, 4, 5, 6])
|
|
50
|
+
>>> sales = ndp.Array.from_list([120.0, 150.0, 90.0, 170.0, 160.0, 185.0])
|
|
51
|
+
>>> costs = ndp.Array.from_list([80.0, 95.0, 70.0, 110.0, 100.0, 120.0])
|
|
52
|
+
>>> shop = ndp.Table.from_arrays({"month": months, "sales": sales, "cost": costs})
|
|
53
|
+
>>> trend = ndp.Plot.line(shop, ndp.LineChart(x="month", y=["sales", "cost"]))
|
|
54
|
+
>>> sales_spread = ndp.Plot.box(shop, ndp.BoxChart(columns=["sales"]))
|
|
55
|
+
>>> cost_spread = ndp.Plot.box(shop, ndp.BoxChart(columns=["cost"]))
|
|
56
|
+
>>> figure = ndp.Figure(ndp.Layout(rows=2, columns=2))
|
|
57
|
+
>>> figure = figure.place(trend, ndp.Cell(row=0, column=0, column_span=2))
|
|
58
|
+
>>> figure = figure.place(sales_spread, ndp.Cell(row=1, column=0))
|
|
59
|
+
>>> figure = figure.place(cost_spread, ndp.Cell(row=1, column=1))
|
|
60
|
+
>>> figure.show()
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
row: int
|
|
64
|
+
column: int
|
|
65
|
+
row_span: int = MINIMUM_SPAN
|
|
66
|
+
column_span: int = MINIMUM_SPAN
|
|
67
|
+
|
|
68
|
+
def __post_init__(self) -> None:
|
|
69
|
+
"""
|
|
70
|
+
Check the first cell and the number of rows and of columns covered.
|
|
71
|
+
|
|
72
|
+
.. versionadded:: 0.1.0
|
|
73
|
+
|
|
74
|
+
Raises
|
|
75
|
+
------
|
|
76
|
+
InvalidTypeError
|
|
77
|
+
When a setting is not of the type its annotation names.
|
|
78
|
+
InvalidPositionError
|
|
79
|
+
When ``row`` or ``column`` is lower than 0.
|
|
80
|
+
InvalidCountError
|
|
81
|
+
When ``row_span`` or ``column_span`` is lower than 1.
|
|
82
|
+
"""
|
|
83
|
+
require_field_types(self)
|
|
84
|
+
|
|
85
|
+
if self.row < FIRST_POSITION:
|
|
86
|
+
raise InvalidPositionError(self.row)
|
|
87
|
+
|
|
88
|
+
if self.column < FIRST_POSITION:
|
|
89
|
+
raise InvalidPositionError(self.column)
|
|
90
|
+
|
|
91
|
+
if self.row_span < MINIMUM_SPAN:
|
|
92
|
+
raise InvalidCountError(self.row_span, MINIMUM_SPAN)
|
|
93
|
+
|
|
94
|
+
if self.column_span < MINIMUM_SPAN:
|
|
95
|
+
raise InvalidCountError(self.column_span, MINIMUM_SPAN)
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Several Plots placed on a grid of cells.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Self
|
|
8
|
+
|
|
9
|
+
from matplotlib.figure import Figure as MatplotlibFigure
|
|
10
|
+
from matplotlib.figure import FigureBase
|
|
11
|
+
|
|
12
|
+
from numdaplot.plots.drawing.plot_drawing import FigureDrawing, build_figure
|
|
13
|
+
from numdaplot.plots.figure.cell import Cell
|
|
14
|
+
from numdaplot.plots.figure.figure_drawing import choose_figure_size, draw_figure
|
|
15
|
+
from numdaplot.plots.figure.figure_style import FigureStyle
|
|
16
|
+
from numdaplot.plots.figure.layout import Layout
|
|
17
|
+
from numdaplot.plots.figure.placement import Placement, require_cell_inside, require_free_cells
|
|
18
|
+
from numdaplot.plots.output.image_saving import write_image
|
|
19
|
+
from numdaplot.plots.output.plot_display import show_drawing
|
|
20
|
+
from numdaplot.plots.output.shown_object import ShownObject
|
|
21
|
+
from numdaplot.plots.plot import Plot
|
|
22
|
+
from numdaplot.plots.style.image_options import ImageOptions
|
|
23
|
+
from numdaplot.settings.argument_types import checked_arguments
|
|
24
|
+
from numdaplot.tables.conflict import Conflict
|
|
25
|
+
from numdaplot.tables.files.file_paths import FilePath
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Figure:
|
|
29
|
+
"""
|
|
30
|
+
Several Plots placed on a grid of cells, shown and saved as one image.
|
|
31
|
+
|
|
32
|
+
A Figure is immutable: ``place`` returns a new Figure. Each Plot keeps its own axes and its own PlotStyle,
|
|
33
|
+
except its size: the Figure gives it the size of its cells. A cell without Plot stays blank.
|
|
34
|
+
|
|
35
|
+
.. versionadded:: 0.1.0
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
layout
|
|
40
|
+
The grid of cells.
|
|
41
|
+
style
|
|
42
|
+
The title and the size of the Figure, the default ``FigureStyle`` when omitted.
|
|
43
|
+
|
|
44
|
+
Examples
|
|
45
|
+
--------
|
|
46
|
+
>>> import numdaplot as ndp
|
|
47
|
+
>>> months = ndp.Array.from_list(["Jan", "Feb", "Mar", "Apr"])
|
|
48
|
+
>>> sales = ndp.Array.from_list([120.0, 150.0, 90.0, 170.0])
|
|
49
|
+
>>> visits = ndp.Array.from_list([900.0, 1100.0, 800.0, 1300.0])
|
|
50
|
+
>>> shop = ndp.Table.from_arrays({"month": months, "sales": sales, "visits": visits})
|
|
51
|
+
>>> sales_plot = ndp.Plot.bar(shop, ndp.BarChart(x="month", y=["sales"]))
|
|
52
|
+
>>> visits_plot = ndp.Plot.line(shop, ndp.LineChart(x="month", y=["visits"]))
|
|
53
|
+
>>> figure = ndp.Figure(ndp.Layout(rows=1, columns=2), ndp.FigureStyle(title="Shop"))
|
|
54
|
+
>>> figure = figure.place(sales_plot, ndp.Cell(row=0, column=0))
|
|
55
|
+
>>> figure = figure.place(visits_plot, ndp.Cell(row=0, column=1))
|
|
56
|
+
>>> figure.show()
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
@checked_arguments
|
|
60
|
+
def __init__(self, layout: Layout, style: FigureStyle | None = None) -> None:
|
|
61
|
+
"""
|
|
62
|
+
Keep the grid and the style of an empty Figure.
|
|
63
|
+
|
|
64
|
+
.. versionadded:: 0.1.0
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
layout
|
|
69
|
+
The grid of cells.
|
|
70
|
+
style
|
|
71
|
+
The title and the size of the Figure, the default ``FigureStyle`` when omitted.
|
|
72
|
+
|
|
73
|
+
Raises
|
|
74
|
+
------
|
|
75
|
+
InvalidTypeError
|
|
76
|
+
When an argument is not of the type its annotation names.
|
|
77
|
+
"""
|
|
78
|
+
if style is None:
|
|
79
|
+
style = FigureStyle()
|
|
80
|
+
|
|
81
|
+
self._layout = layout
|
|
82
|
+
self._style = style
|
|
83
|
+
self._placements = list[Placement]()
|
|
84
|
+
|
|
85
|
+
@checked_arguments
|
|
86
|
+
def place(self, plot: Plot, cell: Cell) -> Self:
|
|
87
|
+
"""
|
|
88
|
+
Return a new Figure with a Plot placed on a cell, and on the cells it spans.
|
|
89
|
+
|
|
90
|
+
.. versionadded:: 0.1.0
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
plot
|
|
95
|
+
The Plot placed, which keeps its PlotStyle but takes the size of its cells.
|
|
96
|
+
cell
|
|
97
|
+
Its first cell, from row 0 and column 0, and the number of cells it spans.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
Self
|
|
102
|
+
A new Figure; this one is left unchanged.
|
|
103
|
+
|
|
104
|
+
Raises
|
|
105
|
+
------
|
|
106
|
+
InvalidTypeError
|
|
107
|
+
When an argument is not of the type its annotation names.
|
|
108
|
+
CellOutOfRangeError
|
|
109
|
+
When a cell covered is outside the Layout.
|
|
110
|
+
OccupiedCellError
|
|
111
|
+
When a cell covered already holds a Plot.
|
|
112
|
+
|
|
113
|
+
Examples
|
|
114
|
+
--------
|
|
115
|
+
>>> import numdaplot as ndp
|
|
116
|
+
>>> prices = ndp.Array.from_list([12.0, 15.5, 14.0, 17.0])
|
|
117
|
+
>>> plot = ndp.Plot.line(prices, style=ndp.PlotStyle(title="Prices"))
|
|
118
|
+
>>> figure = ndp.Figure(ndp.Layout(rows=1, columns=2))
|
|
119
|
+
>>> placed_figure = figure.place(plot, ndp.Cell(row=0, column=1))
|
|
120
|
+
>>> placed_figure.show()
|
|
121
|
+
"""
|
|
122
|
+
require_cell_inside(cell, self._layout)
|
|
123
|
+
require_free_cells(cell, self._placements)
|
|
124
|
+
placement = Placement(plot, cell)
|
|
125
|
+
figure_class = type(self)
|
|
126
|
+
placed_figure = figure_class(self._layout, self._style)
|
|
127
|
+
placed_figure._placements = [*self._placements, placement]
|
|
128
|
+
|
|
129
|
+
return placed_figure
|
|
130
|
+
|
|
131
|
+
def to_matplotlib(self) -> MatplotlibFigure:
|
|
132
|
+
"""
|
|
133
|
+
Return a new matplotlib figure of the Figure, to change it with matplotlib.
|
|
134
|
+
|
|
135
|
+
Each Plot is drawn on a matplotlib subfigure. Changing the figure never changes the Figure.
|
|
136
|
+
|
|
137
|
+
.. versionadded:: 0.1.0
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
matplotlib.figure.Figure
|
|
142
|
+
The figure, with one subfigure per Plot.
|
|
143
|
+
|
|
144
|
+
Examples
|
|
145
|
+
--------
|
|
146
|
+
>>> import numdaplot as ndp
|
|
147
|
+
>>> plot = ndp.Plot.line(ndp.Array.from_list([12.0, 15.5]))
|
|
148
|
+
>>> figure = ndp.Figure(ndp.Layout(rows=2, columns=2)).place(plot, ndp.Cell(row=1, column=1))
|
|
149
|
+
>>> matplotlib_figure = figure.to_matplotlib()
|
|
150
|
+
>>> len(matplotlib_figure.subfigs), matplotlib_figure.get_size_inches().tolist()
|
|
151
|
+
(1, [9.6, 7.2])
|
|
152
|
+
"""
|
|
153
|
+
drawing = self._describe_drawing()
|
|
154
|
+
matplotlib_figure = build_figure(drawing)
|
|
155
|
+
|
|
156
|
+
return matplotlib_figure
|
|
157
|
+
|
|
158
|
+
@checked_arguments
|
|
159
|
+
def save(self, path: FilePath, options: ImageOptions | None = None, on_conflict: Conflict = Conflict.ERROR) -> None:
|
|
160
|
+
"""
|
|
161
|
+
Save the Figure as an image, in the format named by the extension of the path.
|
|
162
|
+
|
|
163
|
+
``.png`` gives an image made of pixels, ``.svg`` and ``.pdf`` images made of lines and texts that stay
|
|
164
|
+
sharp at any zoom.
|
|
165
|
+
|
|
166
|
+
.. versionadded:: 0.1.0
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
path
|
|
171
|
+
The path of the image, a ``FilePath`` such as ``"chart.png"`` or ``Path("images/chart.svg")``, ending with
|
|
172
|
+
``.png``, ``.svg`` or ``.pdf``.
|
|
173
|
+
options
|
|
174
|
+
The resolution of a PNG image, 100 dots per inch when omitted. SVG and PDF images take none.
|
|
175
|
+
on_conflict
|
|
176
|
+
``ERROR`` by default, refusing to overwrite an existing file, or ``REPLACE`` to overwrite it.
|
|
177
|
+
|
|
178
|
+
Raises
|
|
179
|
+
------
|
|
180
|
+
InvalidTypeError
|
|
181
|
+
When an argument is not of the type its annotation names.
|
|
182
|
+
UnsupportedImageFormatError
|
|
183
|
+
When the path does not end with ``.png``, ``.svg`` or ``.pdf``.
|
|
184
|
+
RefusedSettingError
|
|
185
|
+
When options are given for an SVG or PDF image.
|
|
186
|
+
FileExistsError
|
|
187
|
+
When a file exists at the path and ``on_conflict`` is ``ERROR``.
|
|
188
|
+
FileAccessError
|
|
189
|
+
When the file system refuses the file: missing folder, missing permission and so on.
|
|
190
|
+
|
|
191
|
+
Examples
|
|
192
|
+
--------
|
|
193
|
+
>>> import tempfile
|
|
194
|
+
>>> from pathlib import Path
|
|
195
|
+
>>> import numdaplot as ndp
|
|
196
|
+
>>> path = Path(tempfile.mkdtemp()) / "shop.pdf"
|
|
197
|
+
>>> plot = ndp.Plot.line(ndp.Array.from_list([12.0, 15.5]))
|
|
198
|
+
>>> figure = ndp.Figure(ndp.Layout(rows=1, columns=2)).place(plot, ndp.Cell(row=0, column=0))
|
|
199
|
+
>>> figure.save(path)
|
|
200
|
+
>>> path.read_bytes()[:4]
|
|
201
|
+
b'%PDF'
|
|
202
|
+
"""
|
|
203
|
+
drawing = self._describe_drawing()
|
|
204
|
+
write_image(drawing, path, options, on_conflict)
|
|
205
|
+
|
|
206
|
+
def show(self) -> None:
|
|
207
|
+
"""
|
|
208
|
+
Show the Figure: as an image in a Jupyter notebook, in a matplotlib window anywhere else.
|
|
209
|
+
|
|
210
|
+
In a script, the window stays open until it is closed. When no window can be opened, because Python has no
|
|
211
|
+
``tkinter`` or runs on a server, nothing is shown and a ``DisplayWarning`` suggests saving the Figure instead.
|
|
212
|
+
|
|
213
|
+
.. versionadded:: 0.1.0
|
|
214
|
+
|
|
215
|
+
Examples
|
|
216
|
+
--------
|
|
217
|
+
>>> import numdaplot as ndp
|
|
218
|
+
>>> prices = ndp.Array.from_list([12.0, 15.5, 14.0, 17.0])
|
|
219
|
+
>>> line_plot = ndp.Plot.line(prices, style=ndp.PlotStyle(title="Line"))
|
|
220
|
+
>>> bar_plot = ndp.Plot.bar(prices, style=ndp.PlotStyle(title="Bars"))
|
|
221
|
+
>>> figure = ndp.Figure(ndp.Layout(rows=1, columns=2), ndp.FigureStyle(title="Prices"))
|
|
222
|
+
>>> figure = figure.place(line_plot, ndp.Cell(row=0, column=0))
|
|
223
|
+
>>> figure = figure.place(bar_plot, ndp.Cell(row=0, column=1))
|
|
224
|
+
>>> figure.show()
|
|
225
|
+
"""
|
|
226
|
+
drawing = self._describe_drawing()
|
|
227
|
+
show_drawing(drawing, ShownObject.FIGURE)
|
|
228
|
+
|
|
229
|
+
def _draw_on(self, target: FigureBase) -> None:
|
|
230
|
+
"""
|
|
231
|
+
Draw the Figure on an empty matplotlib figure.
|
|
232
|
+
|
|
233
|
+
.. versionadded:: 0.1.0
|
|
234
|
+
|
|
235
|
+
Parameters
|
|
236
|
+
----------
|
|
237
|
+
target
|
|
238
|
+
The figure drawn on.
|
|
239
|
+
"""
|
|
240
|
+
draw_figure(target, self._layout, self._placements, self._style.title)
|
|
241
|
+
|
|
242
|
+
def _describe_drawing(self) -> FigureDrawing:
|
|
243
|
+
"""
|
|
244
|
+
Return what the Figure draws, and its size.
|
|
245
|
+
|
|
246
|
+
.. versionadded:: 0.1.0
|
|
247
|
+
|
|
248
|
+
Returns
|
|
249
|
+
-------
|
|
250
|
+
FigureDrawing
|
|
251
|
+
The drawing of the Figure.
|
|
252
|
+
"""
|
|
253
|
+
size_inches = choose_figure_size(self._layout, self._style.size)
|
|
254
|
+
drawing = FigureDrawing(self._draw_on, size_inches)
|
|
255
|
+
|
|
256
|
+
return drawing
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Drawing of a Figure: its title and the Plots in their cells.
|
|
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 matplotlib.figure import FigureBase
|
|
11
|
+
|
|
12
|
+
from numdaplot.plots.drawing.plot_theme import BACKGROUND_COLOR
|
|
13
|
+
from numdaplot.plots.drawing.size_inches import convert_size_to_inches
|
|
14
|
+
from numdaplot.plots.figure.layout import Layout
|
|
15
|
+
from numdaplot.plots.figure.placement import Placement
|
|
16
|
+
from numdaplot.plots.style.size import Size
|
|
17
|
+
|
|
18
|
+
CELL_WIDTH = 4.8
|
|
19
|
+
CELL_HEIGHT = 3.6
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def draw_figure(target: FigureBase, layout: Layout, placements: list[Placement], title: str | None) -> None:
|
|
23
|
+
"""
|
|
24
|
+
Draw the title of a Figure and each of its Plots on the cells it covers, the empty cells staying blank.
|
|
25
|
+
|
|
26
|
+
.. versionadded:: 0.1.0
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
target
|
|
31
|
+
An empty matplotlib figure.
|
|
32
|
+
layout
|
|
33
|
+
The grid of the Figure.
|
|
34
|
+
placements
|
|
35
|
+
The Plots and their cells.
|
|
36
|
+
title
|
|
37
|
+
The title above the grid, or None.
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> import numdaplot as ndp
|
|
42
|
+
>>> from matplotlib.figure import Figure
|
|
43
|
+
>>> from numdaplot.plots.figure.figure_drawing import draw_figure
|
|
44
|
+
>>> from numdaplot.plots.figure.placement import Placement
|
|
45
|
+
>>> plot = ndp.Plot.line(ndp.Array.from_list([12.0, 15.5]))
|
|
46
|
+
>>> figure = Figure()
|
|
47
|
+
>>> draw_figure(figure, ndp.Layout(rows=1, columns=2), [Placement(plot, ndp.Cell(row=0, column=1))], "Sales")
|
|
48
|
+
>>> len(figure.subfigs), figure.get_suptitle()
|
|
49
|
+
(1, 'Sales')
|
|
50
|
+
"""
|
|
51
|
+
target.set_facecolor(BACKGROUND_COLOR)
|
|
52
|
+
if title is not None:
|
|
53
|
+
target.suptitle(title)
|
|
54
|
+
|
|
55
|
+
cell_grid = target.add_gridspec(layout.rows, layout.columns)
|
|
56
|
+
|
|
57
|
+
for placement in placements:
|
|
58
|
+
cell = placement.cell
|
|
59
|
+
row_end = cell.row + cell.row_span
|
|
60
|
+
column_end = cell.column + cell.column_span
|
|
61
|
+
cell_area = cell_grid[cell.row : row_end, cell.column : column_end]
|
|
62
|
+
subfigure = target.add_subfigure(cell_area)
|
|
63
|
+
# A Figure draws its Plots with the drawing they use for themselves, which is not public.
|
|
64
|
+
placement.plot._draw_on(subfigure) # pyright: ignore[reportPrivateUsage]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def choose_figure_size(layout: Layout, size: Size | None) -> tuple[float, float]:
|
|
68
|
+
"""
|
|
69
|
+
Return the width and the height of a Figure in inches.
|
|
70
|
+
|
|
71
|
+
.. versionadded:: 0.1.0
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
layout
|
|
76
|
+
The grid of the Figure.
|
|
77
|
+
size
|
|
78
|
+
The size chosen, or None for 4.8 by 3.6 inches per cell.
|
|
79
|
+
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
tuple[float, float]
|
|
83
|
+
The width and the height.
|
|
84
|
+
|
|
85
|
+
Examples
|
|
86
|
+
--------
|
|
87
|
+
>>> import numdaplot as ndp
|
|
88
|
+
>>> from numdaplot.plots.figure.figure_drawing import choose_figure_size
|
|
89
|
+
>>> choose_figure_size(ndp.Layout(rows=2, columns=3), None)
|
|
90
|
+
(14.399999999999999, 7.2)
|
|
91
|
+
"""
|
|
92
|
+
if size is not None:
|
|
93
|
+
chosen_size = convert_size_to_inches(size)
|
|
94
|
+
return chosen_size
|
|
95
|
+
|
|
96
|
+
width = CELL_WIDTH * layout.columns
|
|
97
|
+
height = CELL_HEIGHT * layout.rows
|
|
98
|
+
|
|
99
|
+
return width, height
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Look of a whole Figure.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.plots.style.size import Size
|
|
10
|
+
from numdaplot.settings.field_types import require_field_types
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class FigureStyle:
|
|
15
|
+
"""
|
|
16
|
+
Look of a whole Figure: its title and its size, used by ``Figure``.
|
|
17
|
+
|
|
18
|
+
The look of each Plot belongs to its ``PlotStyle``.
|
|
19
|
+
|
|
20
|
+
.. versionadded:: 0.1.0
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
title
|
|
25
|
+
The title above the grid, no title when omitted.
|
|
26
|
+
size
|
|
27
|
+
The width and the height of the whole Figure, 4.8 by 3.6 inches per cell when omitted.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
Raises
|
|
31
|
+
------
|
|
32
|
+
InvalidTypeError
|
|
33
|
+
When a setting is not of the type its annotation names.
|
|
34
|
+
|
|
35
|
+
Examples
|
|
36
|
+
--------
|
|
37
|
+
>>> import numdaplot as ndp
|
|
38
|
+
>>> prices = ndp.Array.from_list([12.0, 15.5, 14.0, 17.0])
|
|
39
|
+
>>> plot = ndp.Plot.line(prices)
|
|
40
|
+
>>> style = ndp.FigureStyle(title="Prices", size=ndp.Size(width=8, height=3))
|
|
41
|
+
>>> figure = ndp.Figure(ndp.Layout(rows=1, columns=1), style)
|
|
42
|
+
>>> figure = figure.place(plot, ndp.Cell(row=0, column=0))
|
|
43
|
+
>>> figure.show()
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
title: str | None = None
|
|
47
|
+
size: Size | None = None
|
|
48
|
+
|
|
49
|
+
def __post_init__(self) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Check the type of every setting.
|
|
52
|
+
|
|
53
|
+
.. versionadded:: 0.1.0
|
|
54
|
+
|
|
55
|
+
Raises
|
|
56
|
+
------
|
|
57
|
+
InvalidTypeError
|
|
58
|
+
When a setting is not of the type its annotation names.
|
|
59
|
+
"""
|
|
60
|
+
require_field_types(self)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Grid of cells of a Figure.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.errors.invalid_count_error import InvalidCountError
|
|
10
|
+
from numdaplot.settings.field_types import require_field_types
|
|
11
|
+
|
|
12
|
+
MINIMUM_LINE_COUNT = 1
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class Layout:
|
|
17
|
+
"""
|
|
18
|
+
Grid of cells of a ``Figure``, each cell holding a Plot or left blank.
|
|
19
|
+
|
|
20
|
+
.. versionadded:: 0.1.0
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
rows
|
|
25
|
+
The number of rows of cells, at least 1.
|
|
26
|
+
columns
|
|
27
|
+
The number of columns of cells, at least 1.
|
|
28
|
+
|
|
29
|
+
Raises
|
|
30
|
+
------
|
|
31
|
+
InvalidTypeError
|
|
32
|
+
When a setting is not of the type its annotation names.
|
|
33
|
+
InvalidCountError
|
|
34
|
+
When ``rows`` or ``columns`` is lower than 1.
|
|
35
|
+
|
|
36
|
+
Examples
|
|
37
|
+
--------
|
|
38
|
+
>>> import numdaplot as ndp
|
|
39
|
+
>>> prices = ndp.Array.from_list([12.0, 15.5, 14.0, 17.0])
|
|
40
|
+
>>> line_plot = ndp.Plot.line(prices)
|
|
41
|
+
>>> bar_plot = ndp.Plot.bar(prices)
|
|
42
|
+
>>> layout = ndp.Layout(rows=2, columns=1)
|
|
43
|
+
>>> figure = ndp.Figure(layout)
|
|
44
|
+
>>> figure = figure.place(line_plot, ndp.Cell(row=0, column=0))
|
|
45
|
+
>>> figure = figure.place(bar_plot, ndp.Cell(row=1, column=0))
|
|
46
|
+
>>> figure.show()
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
rows: int
|
|
50
|
+
columns: int
|
|
51
|
+
|
|
52
|
+
def __post_init__(self) -> None:
|
|
53
|
+
"""
|
|
54
|
+
Check the number of rows and of columns.
|
|
55
|
+
|
|
56
|
+
.. versionadded:: 0.1.0
|
|
57
|
+
|
|
58
|
+
Raises
|
|
59
|
+
------
|
|
60
|
+
InvalidTypeError
|
|
61
|
+
When a setting is not of the type its annotation names.
|
|
62
|
+
InvalidCountError
|
|
63
|
+
When ``rows`` or ``columns`` is lower than 1.
|
|
64
|
+
"""
|
|
65
|
+
require_field_types(self)
|
|
66
|
+
|
|
67
|
+
if self.rows < MINIMUM_LINE_COUNT:
|
|
68
|
+
raise InvalidCountError(self.rows, MINIMUM_LINE_COUNT)
|
|
69
|
+
|
|
70
|
+
if self.columns < MINIMUM_LINE_COUNT:
|
|
71
|
+
raise InvalidCountError(self.columns, MINIMUM_LINE_COUNT)
|