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