kerykeion 5.0.0b1__py3-none-any.whl → 5.0.0b4__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.

Potentially problematic release.


This version of kerykeion might be problematic. Click here for more details.

Files changed (30) hide show
  1. kerykeion/__init__.py +3 -2
  2. kerykeion/aspects/aspects_factory.py +60 -21
  3. kerykeion/aspects/aspects_utils.py +1 -1
  4. kerykeion/backword.py +111 -18
  5. kerykeion/chart_data_factory.py +72 -7
  6. kerykeion/charts/chart_drawer.py +601 -206
  7. kerykeion/charts/charts_utils.py +440 -255
  8. kerykeion/charts/templates/aspect_grid_only.xml +269 -312
  9. kerykeion/charts/templates/chart.xml +302 -328
  10. kerykeion/charts/templates/wheel_only.xml +271 -312
  11. kerykeion/charts/themes/black-and-white.css +148 -0
  12. kerykeion/relationship_score_factory.py +12 -2
  13. kerykeion/schemas/chart_template_model.py +27 -0
  14. kerykeion/schemas/kr_literals.py +1 -1
  15. kerykeion/settings/__init__.py +16 -2
  16. kerykeion/settings/chart_defaults.py +444 -0
  17. kerykeion/settings/config_constants.py +0 -5
  18. kerykeion/settings/kerykeion_settings.py +31 -74
  19. kerykeion/settings/translation_strings.py +1479 -0
  20. kerykeion/settings/translations.py +74 -0
  21. kerykeion/transits_time_range_factory.py +10 -1
  22. {kerykeion-5.0.0b1.dist-info → kerykeion-5.0.0b4.dist-info}/METADATA +304 -204
  23. {kerykeion-5.0.0b1.dist-info → kerykeion-5.0.0b4.dist-info}/RECORD +25 -26
  24. kerykeion/settings/kr.config.json +0 -1474
  25. kerykeion/settings/legacy/__init__.py +0 -0
  26. kerykeion/settings/legacy/legacy_celestial_points_settings.py +0 -299
  27. kerykeion/settings/legacy/legacy_chart_aspects_settings.py +0 -71
  28. kerykeion/settings/legacy/legacy_color_settings.py +0 -42
  29. {kerykeion-5.0.0b1.dist-info → kerykeion-5.0.0b4.dist-info}/WHEEL +0 -0
  30. {kerykeion-5.0.0b1.dist-info → kerykeion-5.0.0b4.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kerykeion
3
- Version: 5.0.0b1
3
+ Version: 5.0.0b4
4
4
  Summary: A Python library for astrological calculations, including natal charts, houses, planetary aspects, and SVG chart generation.
5
5
  Project-URL: Homepage, https://www.kerykeion.net/
6
6
  Project-URL: Repository, https://github.com/g-battaglia/kerykeion
@@ -47,7 +47,9 @@ Description-Content-Type: text/markdown
47
47
  <div align="center">
48
48
  <img src="https://static.pepy.tech/badge/kerykeion/month" alt="PyPI Downloads">
49
49
  <img src="https://static.pepy.tech/badge/kerykeion/week" alt="PyPI Downloads">
50
- <img src="https://img.shields.io/github/contributors/g-battaglia/kerykeion?color=blue&logo=github" alt="contributors">
50
+ <img src="https://static.pepy.tech/personalized-badge/kerykeion?period=total&units=INTERNATIONAL_SYSTEM&left_color=GREY&right_color=BLUE&left_text=downloads/total" alt="PyPI Downloads">
51
+ </div>
52
+ <div align="center">
51
53
  <img src="https://img.shields.io/pypi/v/kerykeion?label=pypi%20package" alt="Package version">
52
54
  <img src="https://img.shields.io/pypi/pyversions/kerykeion.svg" alt="Supported Python versions">
53
55
  </div>
@@ -58,14 +60,13 @@ Kerykeion is a Python library for astrology. It computes planetary and house pos
58
60
 
59
61
  The main goal of this project is to offer a clean, data-driven approach to astrology, making it accessible and programmable.
60
62
 
61
- Kerykeion also integrates seamlessly with LLM and AI applications.
63
+ Kerykeion also integrates seamlessly with LLM and AI applications.
62
64
 
63
65
  Here is an example of a birthchart:
64
66
 
65
67
  ![John Lenon Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Dark%20Theme%20-%20Natal%20Chart.svg)
66
68
 
67
- **Web API**
68
- ---
69
+ ## **Web API**
69
70
 
70
71
  If you want to use Kerykeion in a web application, you can try the dedicated web API:
71
72
 
@@ -73,8 +74,7 @@ If you want to use Kerykeion in a web application, you can try the dedicated web
73
74
 
74
75
  It is [open source](https://github.com/g-battaglia/Astrologer-API) and directly supports this project.
75
76
 
76
- **Donate**
77
- --
77
+ ## **Donate**
78
78
 
79
79
  Maintaining this project requires substantial time and effort. The Astrologer API alone cannot cover the costs of full-time development. If you find Kerykeion valuable and would like to support further development, please consider donating:
80
80
 
@@ -87,62 +87,63 @@ This branch (`next`) is **not the stable version** of Kerykeion. It is the **dev
87
87
  If you're looking for the latest stable version, please check out the [`master`](https://github.com/g-battaglia/kerykeion/tree/master) branch instead.
88
88
 
89
89
  ## Table of Contents
90
- - [**Web API**](#web-api)
91
- - [**Donate**](#donate)
92
- - [⚠️ Development Branch Notice](#️-development-branch-notice)
93
- - [Table of Contents](#table-of-contents)
94
- - [Installation](#installation)
95
- - [Basic Usage](#basic-usage)
96
- - [Generate a SVG Chart](#generate-a-svg-chart)
97
- - [Birth Chart](#birth-chart)
98
- - [External Birth Chart](#external-birth-chart)
99
- - [Synastry Chart](#synastry-chart)
100
- - [Transit Chart](#transit-chart)
101
- - [Composite Chart](#composite-chart)
102
- - [Wheel Only Charts](#wheel-only-charts)
103
- - [Birth Chart](#birth-chart-1)
104
- - [Wheel Only Birth Chart (External)](#wheel-only-birth-chart-external)
105
- - [Synastry Chart](#synastry-chart-1)
106
- - [Change the Output Directory](#change-the-output-directory)
107
- - [Change Language](#change-language)
108
- - [Minified SVG](#minified-svg)
109
- - [SVG without CSS Variables](#svg-without-css-variables)
110
- - [Grid Only SVG](#grid-only-svg)
111
- - [Report Generator](#report-generator)
112
- - [Quick Examples](#quick-examples)
113
- - [Section Access](#section-access)
114
- - [Example: Retrieving Aspects](#example-retrieving-aspects)
115
- - [Ayanamsa (Sidereal Modes)](#ayanamsa-sidereal-modes)
116
- - [House Systems](#house-systems)
117
- - [Perspective Type](#perspective-type)
118
- - [Themes](#themes)
119
- - [Alternative Initialization](#alternative-initialization)
120
- - [Lunar Nodes (Rahu \& Ketu)](#lunar-nodes-rahu--ketu)
121
- - [JSON Support](#json-support)
122
- - [Auto Generated Documentation](#auto-generated-documentation)
123
- - [Development](#development)
124
- - [Kerykeion v5.0 – What's New](#kerykeion-v50--whats-new)
125
- - [🎯 Key Highlights](#-key-highlights)
126
- - [Factory-Centered Architecture](#factory-centered-architecture)
127
- - [Pydantic 2 Models \& Type Safety](#pydantic-2-models--type-safety)
128
- - [Enhanced Features](#enhanced-features)
129
- - [🚨 Breaking Changes](#-breaking-changes)
130
- - [1. Removed Legacy Classes](#1-removed-legacy-classes)
131
- - [2. Import Changes](#2-import-changes)
132
- - [3. Lunar Nodes Naming](#3-lunar-nodes-naming)
133
- - [4. Chart Generation Changes](#4-chart-generation-changes)
134
- - [5. Aspects API Changes](#5-aspects-api-changes)
135
- - [🔄 Migration Guide](#-migration-guide)
136
- - [Using the Backward Compatibility Layer](#using-the-backward-compatibility-layer)
137
- - [Step-by-Step Migration](#step-by-step-migration)
138
- - [Automated Migration Script](#automated-migration-script)
139
- - [📦 Other Notable Changes](#-other-notable-changes)
140
- - [🎨 New Themes](#-new-themes)
141
- - [📚 Resources](#-resources)
142
- - [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
143
- - [License](#license)
144
- - [Contributing](#contributing)
145
- - [Citations](#citations)
90
+
91
+ - [**Web API**](#web-api)
92
+ - [**Donate**](#donate)
93
+ - [⚠️ Development Branch Notice](#️-development-branch-notice)
94
+ - [Table of Contents](#table-of-contents)
95
+ - [Installation](#installation)
96
+ - [Basic Usage](#basic-usage)
97
+ - [Generate a SVG Chart](#generate-a-svg-chart)
98
+ - [Birth Chart](#birth-chart)
99
+ - [External Birth Chart](#external-birth-chart)
100
+ - [Synastry Chart](#synastry-chart)
101
+ - [Transit Chart](#transit-chart)
102
+ - [Composite Chart](#composite-chart)
103
+ - [Wheel Only Charts](#wheel-only-charts)
104
+ - [Birth Chart](#birth-chart-1)
105
+ - [Wheel Only Birth Chart (External)](#wheel-only-birth-chart-external)
106
+ - [Synastry Chart](#synastry-chart-1)
107
+ - [Change the Output Directory](#change-the-output-directory)
108
+ - [Change Language](#change-language)
109
+ - [Minified SVG](#minified-svg)
110
+ - [SVG without CSS Variables](#svg-without-css-variables)
111
+ - [Grid Only SVG](#grid-only-svg)
112
+ - [Report Generator](#report-generator)
113
+ - [Quick Examples](#quick-examples)
114
+ - [Section Access](#section-access)
115
+ - [Example: Retrieving Aspects](#example-retrieving-aspects)
116
+ - [Ayanamsa (Sidereal Modes)](#ayanamsa-sidereal-modes)
117
+ - [House Systems](#house-systems)
118
+ - [Perspective Type](#perspective-type)
119
+ - [Themes](#themes)
120
+ - [Alternative Initialization](#alternative-initialization)
121
+ - [Lunar Nodes (Rahu \& Ketu)](#lunar-nodes-rahu--ketu)
122
+ - [JSON Support](#json-support)
123
+ - [Auto Generated Documentation](#auto-generated-documentation)
124
+ - [Development](#development)
125
+ - [Kerykeion v5.0 – What's New](#kerykeion-v50--whats-new)
126
+ - [🎯 Key Highlights](#-key-highlights)
127
+ - [Factory-Centered Architecture](#factory-centered-architecture)
128
+ - [Pydantic 2 Models \& Type Safety](#pydantic-2-models--type-safety)
129
+ - [Enhanced Features](#enhanced-features)
130
+ - [🚨 Breaking Changes](#-breaking-changes)
131
+ - [1. Removed Legacy Classes](#1-removed-legacy-classes)
132
+ - [2. Import Changes](#2-import-changes)
133
+ - [3. Lunar Nodes Naming](#3-lunar-nodes-naming)
134
+ - [4. Chart Generation Changes](#4-chart-generation-changes)
135
+ - [5. Aspects API Changes](#5-aspects-api-changes)
136
+ - [🔄 Migration Guide](#-migration-guide)
137
+ - [Using the Backward Compatibility Layer](#using-the-backward-compatibility-layer)
138
+ - [Step-by-Step Migration](#step-by-step-migration)
139
+ - [Automated Migration Script](#automated-migration-script)
140
+ - [📦 Other Notable Changes](#-other-notable-changes)
141
+ - [🎨 New Themes](#-new-themes)
142
+ - [📚 Resources](#-resources)
143
+ - [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
144
+ - [License](#license)
145
+ - [Contributing](#contributing)
146
+ - [Citations](#citations)
146
147
 
147
148
  ## Installation
148
149
 
@@ -184,7 +185,7 @@ john = AstrologicalSubjectFactory.from_birth_data(
184
185
  lng=-2.9833, # Longitude for Liverpool
185
186
  lat=53.4000, # Latitude for Liverpool
186
187
  tz_str="Europe/London", # Timezone for Liverpool
187
- city="Liverpool",
188
+ city="Liverpool",
188
189
  )
189
190
  ```
190
191
 
@@ -192,7 +193,7 @@ john = AstrologicalSubjectFactory.from_birth_data(
192
193
 
193
194
  To generate a chart, use the `ChartDataFactory` to pre-compute chart data, then `ChartDrawer` to create the visualization. This two-step process ensures clean separation between astrological calculations and chart rendering.
194
195
 
195
- **Tip:**
196
+ **Tip:**
196
197
  The optimized way to open the generated SVG files is with a web browser (e.g., Chrome, Firefox).
197
198
  To improve compatibility across different applications, you can use the `remove_css_variables` parameter when generating the SVG. This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
198
199
 
@@ -234,6 +235,7 @@ chart_data = ChartDataFactory.create_external_natal_chart_data(birth_chart)
234
235
  birth_chart_svg = ChartDrawer(chart_data=chart_data)
235
236
  birth_chart_svg.save_svg()
236
237
  ```
238
+
237
239
  ![John Lennon External Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20ExternalNatal%20Chart.svg)
238
240
 
239
241
  ### Synastry Chart
@@ -257,7 +259,6 @@ synastry_chart.save_svg()
257
259
 
258
260
  ![John Lennon and Paul McCartney Synastry](https://www.kerykeion.net/img/examples/synastry-chart.svg)
259
261
 
260
-
261
262
  ### Transit Chart
262
263
 
263
264
  ```python
@@ -307,9 +308,10 @@ composite_chart.save_svg()
307
308
 
308
309
  ## Wheel Only Charts
309
310
 
310
- For *all* the charts, you can generate a wheel-only chart by using the method `makeWheelOnlySVG()`:
311
+ For _all_ the charts, you can generate a wheel-only chart by using the method `makeWheelOnlySVG()`:
311
312
 
312
313
  ### Birth Chart
314
+
313
315
  ```python
314
316
  from kerykeion import AstrologicalSubjectFactory
315
317
  from kerykeion.chart_data_factory import ChartDataFactory
@@ -325,6 +327,7 @@ chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
325
327
  birth_chart_svg = ChartDrawer(chart_data=chart_data)
326
328
  birth_chart_svg.save_wheel_only_svg_file()
327
329
  ```
330
+
328
331
  ![John Lennon Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Wheel%20Only%20-%20Natal%20Chart%20-%20Wheel%20Only.svg)
329
332
 
330
333
  ### Wheel Only Birth Chart (External)
@@ -351,6 +354,7 @@ birth_chart_svg.save_wheel_only_svg_file(
351
354
  ![John Lennon Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Wheel%20External%20Only%20-%20ExternalNatal%20Chart%20-%20Wheel%20Only.svg)
352
355
 
353
356
  ### Synastry Chart
357
+
354
358
  ```python
355
359
  from kerykeion import AstrologicalSubjectFactory
356
360
  from kerykeion.chart_data_factory import ChartDataFactory
@@ -393,7 +397,7 @@ synastry_chart.save_svg(output_path=".")
393
397
 
394
398
  ### Change Language
395
399
 
396
- You can switch chart language by passing `chart_language` to the `ChartDrawer` class:
400
+ You can switch chart language by passing `chart_language` to the `ChartDrawer` class:
397
401
 
398
402
  ```python
399
403
  from kerykeion import AstrologicalSubjectFactory
@@ -412,23 +416,43 @@ birth_chart_svg = ChartDrawer(
412
416
  chart_language="IT" # Change to Italian
413
417
  )
414
418
  birth_chart_svg.save_svg()
419
+
420
+ You can also provide custom labels (or introduce a brand-new language) by passing
421
+ a dictionary to `language_pack`. Only the keys you supply are merged on top of the
422
+ built-in strings:
423
+
424
+ ```python
425
+ custom_labels = {
426
+ "PT": {
427
+ "info": "Informações",
428
+ "celestial_points": {"Sun": "Sol", "Moon": "Lua"},
429
+ }
430
+ }
431
+
432
+ birth_chart_svg = ChartDrawer(
433
+ chart_data=chart_data,
434
+ chart_language="PT",
435
+ language_pack=custom_labels["PT"],
436
+ )
437
+ ```
415
438
  ```
416
439
 
417
440
  More details [here](https://www.kerykeion.net/docs/chart-language).
418
441
 
419
442
  The available languages are:
420
- - EN (English)
421
- - FR (French)
422
- - PT (Portuguese)
423
- - ES (Spanish)
424
- - TR (Turkish)
425
- - RU (Russian)
426
- - IT (Italian)
427
- - CN (Chinese)
428
- - DE (German)
429
443
 
444
+ - EN (English)
445
+ - FR (French)
446
+ - PT (Portuguese)
447
+ - ES (Spanish)
448
+ - TR (Turkish)
449
+ - RU (Russian)
450
+ - IT (Italian)
451
+ - CN (Chinese)
452
+ - DE (German)
430
453
 
431
454
  ### Minified SVG
455
+
432
456
  To generate a minified SVG, set `minify_svg=True` in the `makeSVG()` method:
433
457
 
434
458
  ```python
@@ -450,6 +474,7 @@ birth_chart_svg.save_svg(
450
474
  ```
451
475
 
452
476
  ### SVG without CSS Variables
477
+
453
478
  To generate an SVG without CSS variables, set `remove_css_variables=True` in the `makeSVG()` method:
454
479
 
455
480
  ```python
@@ -469,8 +494,8 @@ birth_chart_svg.save_svg(
469
494
  remove_css_variables=True
470
495
  )
471
496
  ```
472
- This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
473
497
 
498
+ This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
474
499
 
475
500
  ### Grid Only SVG
476
501
 
@@ -492,6 +517,7 @@ chart_data = ChartDataFactory.create_synastry_chart_data(birth_chart, second)
492
517
  aspect_grid_chart = ChartDrawer(chart_data=chart_data, theme="dark")
493
518
  aspect_grid_chart.save_aspect_grid_only_svg_file()
494
519
  ```
520
+
495
521
  ![John Lennon Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Aspect%20Grid%20Only%20-%20Natal%20Chart%20-%20Aspect%20Grid%20Only.svg)
496
522
 
497
523
  ## Report Generator
@@ -522,14 +548,15 @@ ReportGenerator(synastry_data).print_report(max_aspects=12)
522
548
  ```
523
549
 
524
550
  Each report contains:
525
- - A chart-aware title summarising the subject(s) and chart type
526
- - Birth/event metadata and configuration settings
527
- - Celestial points with sign, position, **daily motion**, **declination**, retrograde flag, and house
528
- - House cusp tables for every subject involved
529
- - Lunar phase details when available
530
- - Element/quality distributions and active configuration summaries (for chart data)
531
- - Aspect listings tailored for single or dual charts, with symbols for type and movement
532
- - Dual-chart extras such as house comparisons and relationship scores (when provided by the data)
551
+
552
+ - A chart-aware title summarising the subject(s) and chart type
553
+ - Birth/event metadata and configuration settings
554
+ - Celestial points with sign, position, **daily motion**, **declination**, retrograde flag, and house
555
+ - House cusp tables for every subject involved
556
+ - Lunar phase details when available
557
+ - Element/quality distributions and active configuration summaries (for chart data)
558
+ - Aspect listings tailored for single or dual charts, with symbols for type and movement
559
+ - Dual-chart extras such as house comparisons and relationship scores (when provided by the data)
533
560
 
534
561
  ### Section Access
535
562
 
@@ -590,6 +617,43 @@ custom_aspects = DEFAULT_ACTIVE_ASPECTS.copy()
590
617
  # and filters aspects based on relevance and orb thresholds
591
618
  ```
592
619
 
620
+ ## Element & Quality Distribution Strategies
621
+
622
+ `ChartDataFactory` now offers two strategies for calculating element and modality totals. The default `"weighted"` mode leans on a curated map that emphasises core factors (for example `sun`, `moon`, and `ascendant` weight 2.0, angles such as `medium_coeli` 1.5, personal planets 1.5, social planets 1.0, outers 0.5, and minor bodies 0.3–0.8). Provide `distribution_method="pure_count"` when you want every active point to contribute equally.
623
+
624
+ You can refine the weighting without rebuilding the dictionary: pass lowercase point names to `custom_distribution_weights` and use `"__default__"` to override the fallback value applied to entries that are not listed explicitly.
625
+
626
+ ```python
627
+ from kerykeion import AstrologicalSubjectFactory, ChartDataFactory
628
+
629
+ subject = AstrologicalSubjectFactory.from_birth_data(
630
+ "Sample", 1986, 4, 12, 8, 45, "Bologna", "IT"
631
+ )
632
+
633
+ # Equal weighting: every active point counts once
634
+ pure_data = ChartDataFactory.create_natal_chart_data(
635
+ subject,
636
+ distribution_method="pure_count",
637
+ )
638
+
639
+ # Custom emphasis: boost the Sun, soften everything else
640
+ weighted_data = ChartDataFactory.create_natal_chart_data(
641
+ subject,
642
+ distribution_method="weighted",
643
+ custom_distribution_weights={
644
+ "sun": 3.0,
645
+ "__default__": 0.75,
646
+ },
647
+ )
648
+
649
+ print(pure_data.element_distribution.fire)
650
+ print(weighted_data.element_distribution.fire)
651
+ ```
652
+
653
+ All convenience helpers (`create_synastry_chart_data`, `create_transit_chart_data`, returns, and composites) forward the same keyword-only parameters, so you can keep a consistent weighting scheme across every chart type.
654
+
655
+ For an extended walkthrough (including category breakdowns of the default map), see `site-docs/element_quality_distribution.md`.
656
+
593
657
  ## Ayanamsa (Sidereal Modes)
594
658
 
595
659
  By default, the zodiac type is **Tropical**. To use **Sidereal**, specify the sidereal mode:
@@ -645,13 +709,17 @@ Full list of supported perspective types [here](https://www.kerykeion.net/pydocs
645
709
 
646
710
  Kerykeion provides several chart themes:
647
711
 
648
- - **Classic** (default)
649
- - **Dark**
650
- - **Dark High Contrast**
651
- - **Light**
652
-
712
+ - **Classic** (default)
713
+ - **Dark**
714
+ - **Dark High Contrast**
715
+ - **Light**
716
+ - **Strawberry**
717
+ - **Black & White** (optimized for monochrome printing)
718
+
653
719
  Each theme offers a distinct visual style, allowing you to choose the one that best suits your preferences or presentation needs. If you prefer more control over the appearance, you can opt not to set any theme, making it easier to customize the chart by overriding the default CSS variables. For more detailed instructions on how to apply themes, check the [documentation](https://www.kerykeion.net/docs/theming)
654
720
 
721
+ The Black & White theme renders glyphs, rings, and aspects in solid black on light backgrounds, designed for crisp B/W prints (PDF or paper) without sacrificing legibility.
722
+
655
723
  Here's an example of how to set the theme:
656
724
 
657
725
  ```python
@@ -666,7 +734,7 @@ dark_theme_subject = AstrologicalSubjectFactory.from_birth_data("John Lennon - D
666
734
  chart_data = ChartDataFactory.create_natal_chart_data(dark_theme_subject)
667
735
 
668
736
  # Step 3: Create visualization with dark high contrast theme
669
- dark_theme_natal_chart = ChartDrawer(chart_data=chart_data, theme="dark_high_contrast")
737
+ dark_theme_natal_chart = ChartDrawer(chart_data=chart_data, theme="dark-high-contrast")
670
738
  dark_theme_natal_chart.save_svg()
671
739
  ```
672
740
 
@@ -696,10 +764,10 @@ subject = AstrologicalSubject.get_from_iso_utc_time(
696
764
 
697
765
  Kerykeion supports both **True** and **Mean** Lunar Nodes:
698
766
 
699
- - **True North Lunar Node**: `"true_node"` (name kept without "north" for backward compatibility).
700
- - **True South Lunar Node**: `"true_south_node"`.
701
- - **Mean North Lunar Node**: `"mean_node"` (name kept without "north" for backward compatibility).
702
- - **Mean South Lunar Node**: `"mean_south_node"`.
767
+ - **True North Lunar Node**: `"true_node"` (name kept without "north" for backward compatibility).
768
+ - **True South Lunar Node**: `"true_south_node"`.
769
+ - **Mean North Lunar Node**: `"mean_node"` (name kept without "north" for backward compatibility).
770
+ - **Mean South Lunar Node**: `"mean_south_node"`.
703
771
 
704
772
  In instances of the classes used to generate aspects and SVG charts, only the mean nodes are active. To activate the true nodes, you need to pass the `active_points` parameter to the `ChartDataFactory` methods.
705
773
 
@@ -717,23 +785,23 @@ subject = AstrologicalSubjectFactory.from_birth_data("John Lennon", 1940, 10, 9,
717
785
  chart_data = ChartDataFactory.create_natal_chart_data(
718
786
  subject,
719
787
  active_points=[
720
- "Sun",
721
- "Moon",
722
- "Mercury",
723
- "Venus",
724
- "Mars",
725
- "Jupiter",
788
+ "Sun",
789
+ "Moon",
790
+ "Mercury",
791
+ "Venus",
792
+ "Mars",
793
+ "Jupiter",
726
794
  "Saturn",
727
- "Uranus",
728
- "Neptune",
729
- "Pluto",
730
- "Mean_Node",
731
- "Mean_South_Node",
732
- "True_Node", # Activates True North Node
795
+ "Uranus",
796
+ "Neptune",
797
+ "Pluto",
798
+ "Mean_Node",
799
+ "Mean_South_Node",
800
+ "True_Node", # Activates True North Node
733
801
  "True_South_Node", # Activates True South Node
734
802
  "Ascendant",
735
- "Medium_Coeli",
736
- "Descendant",
803
+ "Medium_Coeli",
804
+ "Descendant",
737
805
  "Imum_Coeli"
738
806
  ]
739
807
  )
@@ -770,17 +838,19 @@ Kerykeion v5 is a **complete redesign** that modernizes the library with a data-
770
838
  ### 🎯 Key Highlights
771
839
 
772
840
  #### Factory-Centered Architecture
841
+
773
842
  The old class-based approach has been replaced with a modern factory pattern:
774
843
 
775
- - **`AstrologicalSubjectFactory`**: Replaces the old `AstrologicalSubject` class
776
- - **`ChartDataFactory`**: Pre-computes enriched chart data (elements, qualities, aspects)
777
- - **`ChartDrawer`**: Pure SVG rendering separated from calculations
778
- - **`AspectsFactory`**: Unified aspects calculation for natal and synastry charts
779
- - **`PlanetaryReturnFactory`**: Solar and Lunar returns computation
780
- - **`HouseComparisonFactory`**: House overlay analysis for synastry
781
- - **`RelationshipScoreFactory`**: Compatibility scoring between charts
844
+ - **`AstrologicalSubjectFactory`**: Replaces the old `AstrologicalSubject` class
845
+ - **`ChartDataFactory`**: Pre-computes enriched chart data (elements, qualities, aspects)
846
+ - **`ChartDrawer`**: Pure SVG rendering separated from calculations
847
+ - **`AspectsFactory`**: Unified aspects calculation for natal and synastry charts
848
+ - **`PlanetaryReturnFactory`**: Solar and Lunar returns computation
849
+ - **`HouseComparisonFactory`**: House overlay analysis for synastry
850
+ - **`RelationshipScoreFactory`**: Compatibility scoring between charts
782
851
 
783
852
  **Old v4 API:**
853
+
784
854
  ```python
785
855
  from kerykeion import AstrologicalSubject, KerykeionChartSVG
786
856
 
@@ -791,6 +861,7 @@ chart.makeSVG()
791
861
  ```
792
862
 
793
863
  **New v5 API:**
864
+
794
865
  ```python
795
866
  from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
796
867
 
@@ -802,70 +873,81 @@ drawer.save_svg()
802
873
  ```
803
874
 
804
875
  #### Pydantic 2 Models & Type Safety
876
+
805
877
  All data structures are now strongly typed Pydantic models:
806
878
 
807
- - **`AstrologicalSubjectModel`**: Subject data with full validation
808
- - **`ChartDataModel`**: Enriched chart data with elements, qualities, aspects
809
- - **`SingleChartAspectsModel` / `DualChartAspectsModel`**: Typed aspect collections
810
- - **`PlanetReturnModel`**: Planetary return data
811
- - **`ElementDistributionModel`**: Element statistics (fire, earth, air, water)
812
- - **`QualityDistributionModel`**: Quality statistics (cardinal, fixed, mutable)
879
+ - **`AstrologicalSubjectModel`**: Subject data with full validation
880
+ - **`ChartDataModel`**: Enriched chart data with elements, qualities, aspects
881
+ - **`SingleChartAspectsModel` / `DualChartAspectsModel`**: Typed aspect collections
882
+ - **`PlanetReturnModel`**: Planetary return data
883
+ - **`ElementDistributionModel`**: Element statistics (fire, earth, air, water)
884
+ - **`QualityDistributionModel`**: Quality statistics (cardinal, fixed, mutable)
813
885
 
814
886
  All models support:
815
- - JSON serialization/deserialization
816
- - Dictionary export
817
- - Subscript access
818
- - Full IDE autocomplete and type checking
887
+
888
+ - JSON serialization/deserialization
889
+ - Dictionary export
890
+ - Subscript access
891
+ - Full IDE autocomplete and type checking
819
892
 
820
893
  #### Enhanced Features
821
- - **Speed & Declination**: All celestial points now include daily motion speed and declination
822
- - **Element & Quality Analysis**: Automatic calculation of element/quality distributions
823
- - **Relationship Scoring**: Built-in compatibility analysis for synastry
824
- - **House Comparison**: Detailed house overlay analysis
825
- - **Transit Time Ranges**: Advanced transit tracking over time periods
826
- - **Report Module**: Comprehensive text reports with ASCII tables
894
+
895
+ - **Speed & Declination**: All celestial points now include daily motion speed and declination
896
+ - **Element & Quality Analysis**: Automatic calculation of element/quality distributions
897
+ - **Relationship Scoring**: Built-in compatibility analysis for synastry
898
+ - **House Comparison**: Detailed house overlay analysis
899
+ - **Transit Time Ranges**: Advanced transit tracking over time periods
900
+ - **Report Module**: Comprehensive text reports with ASCII tables
901
+ - **Axis Orb Control**: Chart axes now share the same orb as planets by default; pass the keyword-only `axis_orb_limit` to return to a traditional, tighter axis filtering when you need it.
902
+ - **Element Weight Strategies**: Element and quality stats now default to a curated weighted balance; pass `distribution_method` or `custom_distribution_weights` when you need equal counts or bespoke weightings (including a `__default__` fallback) across any chart factory helper.
827
903
 
828
904
  ### 🚨 Breaking Changes
829
905
 
830
906
  #### 1. Removed Legacy Classes
907
+
831
908
  The following classes have been **completely removed** and must be replaced:
832
909
 
833
- | Removed (v4) | Replacement (v5) |
834
- |--------------|------------------|
835
- | `AstrologicalSubject` | `AstrologicalSubjectFactory.from_birth_data()` |
836
- | `KerykeionChartSVG` | `ChartDrawer` + `ChartDataFactory` |
837
- | `NatalAspects` | `AspectsFactory.single_chart_aspects()` |
838
- | `SynastryAspects` | `AspectsFactory.dual_chart_aspects()` |
839
- | `relationship_score()` | `RelationshipScoreFactory` |
910
+ | Removed (v4) | Replacement (v5) |
911
+ | ---------------------- | ---------------------------------------------- |
912
+ | `AstrologicalSubject` | `AstrologicalSubjectFactory.from_birth_data()` |
913
+ | `KerykeionChartSVG` | `ChartDrawer` + `ChartDataFactory` |
914
+ | `NatalAspects` | `AspectsFactory.single_chart_aspects()` |
915
+ | `SynastryAspects` | `AspectsFactory.dual_chart_aspects()` |
916
+ | `relationship_score()` | `RelationshipScoreFactory` |
840
917
 
841
918
  **Note**: The `kerykeion.backword` module provides temporary wrappers for `AstrologicalSubject` and `KerykeionChartSVG` with deprecation warnings. These will be **removed in v6.0**.
842
919
 
843
920
  #### 2. Import Changes
921
+
844
922
  Module structure has been completely reorganized:
845
923
 
846
924
  **Old imports (v4):**
925
+
847
926
  ```python
848
927
  from kerykeion import AstrologicalSubject, KerykeionChartSVG
849
928
  from kerykeion.kr_types import KerykeionException
850
929
  ```
851
930
 
852
931
  **New imports (v5):**
932
+
853
933
  ```python
854
934
  from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
855
935
  from kerykeion.schemas.kerykeion_exception import KerykeionException
856
936
  ```
857
937
 
858
938
  #### 3. Lunar Nodes Naming
939
+
859
940
  All lunar node fields have been renamed for clarity:
860
941
 
861
- | Old Name (v4) | New Name (v5) |
862
- |---------------|---------------|
863
- | `Mean_Node` | `Mean_North_Lunar_Node` |
864
- | `True_Node` | `True_North_Lunar_Node` |
942
+ | Old Name (v4) | New Name (v5) |
943
+ | ----------------- | ----------------------- |
944
+ | `Mean_Node` | `Mean_North_Lunar_Node` |
945
+ | `True_Node` | `True_North_Lunar_Node` |
865
946
  | `Mean_South_Node` | `Mean_South_Lunar_Node` |
866
947
  | `True_South_Node` | `True_South_Lunar_Node` |
867
948
 
868
949
  **Migration example:**
950
+
869
951
  ```python
870
952
  # v4
871
953
  print(subject.mean_node)
@@ -874,16 +956,23 @@ print(subject.mean_node)
874
956
  print(subject.mean_north_lunar_node)
875
957
  ```
876
958
 
877
- #### 4. Chart Generation Changes
959
+ #### 4. Axis Orb Filtering
960
+
961
+ Modern default orbs now treat chart axes (ASC, MC, DSC, IC) exactly like planets. If you prefer a traditional, constrained approach, every public aspect factory exposes the keyword-only `axis_orb_limit` parameter so you can set a dedicated threshold when needed.
962
+
963
+ #### 5. Chart Generation Changes
964
+
878
965
  The two-step process (data + rendering) is now required:
879
966
 
880
967
  **Old v4:**
968
+
881
969
  ```python
882
970
  chart = KerykeionChartSVG(subject)
883
971
  chart.makeSVG()
884
972
  ```
885
973
 
886
974
  **New v5:**
975
+
887
976
  ```python
888
977
  chart_data = ChartDataFactory.create_natal_chart_data(subject)
889
978
  drawer = ChartDrawer(chart_data=chart_data)
@@ -891,9 +980,11 @@ drawer.save_svg()
891
980
  ```
892
981
 
893
982
  #### 5. Aspects API Changes
983
+
894
984
  Aspects are now calculated through the factory:
895
985
 
896
986
  **Old v4:**
987
+
897
988
  ```python
898
989
  from kerykeion import NatalAspects, SynastryAspects
899
990
 
@@ -902,6 +993,7 @@ synastry_aspects = SynastryAspects(subject1, subject2)
902
993
  ```
903
994
 
904
995
  **New v5:**
996
+
905
997
  ```python
906
998
  from kerykeion import AspectsFactory
907
999
 
@@ -930,54 +1022,59 @@ print(subject.true_node) # Maps to true_north_lunar_node
930
1022
  #### Step-by-Step Migration
931
1023
 
932
1024
  1. **Update imports**
933
- ```python
934
- # Old
935
- from kerykeion import AstrologicalSubject, KerykeionChartSVG
936
-
937
- # New
938
- from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
939
- ```
1025
+
1026
+ ```python
1027
+ # Old
1028
+ from kerykeion import AstrologicalSubject, KerykeionChartSVG
1029
+
1030
+ # New
1031
+ from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
1032
+ ```
940
1033
 
941
1034
  2. **Update subject creation**
942
- ```python
943
- # Old
944
- subject = AstrologicalSubject("John", 1990, 1, 1, 12, 0, "London", "GB")
945
-
946
- # New
947
- subject = AstrologicalSubjectFactory.from_birth_data("John", 1990, 1, 1, 12, 0, "London", "GB")
948
- ```
1035
+
1036
+ ```python
1037
+ # Old
1038
+ subject = AstrologicalSubject("John", 1990, 1, 1, 12, 0, "London", "GB")
1039
+
1040
+ # New
1041
+ subject = AstrologicalSubjectFactory.from_birth_data("John", 1990, 1, 1, 12, 0, "London", "GB")
1042
+ ```
949
1043
 
950
1044
  3. **Update chart generation**
951
- ```python
952
- # Old
953
- chart = KerykeionChartSVG(subject)
954
- chart.makeSVG()
955
-
956
- # New
957
- chart_data = ChartDataFactory.create_natal_chart_data(subject)
958
- drawer = ChartDrawer(chart_data=chart_data)
959
- drawer.save_svg()
960
- ```
1045
+
1046
+ ```python
1047
+ # Old
1048
+ chart = KerykeionChartSVG(subject)
1049
+ chart.makeSVG()
1050
+
1051
+ # New
1052
+ chart_data = ChartDataFactory.create_natal_chart_data(subject)
1053
+ drawer = ChartDrawer(chart_data=chart_data)
1054
+ drawer.save_svg()
1055
+ ```
961
1056
 
962
1057
  4. **Update field access** (lunar nodes)
963
- ```python
964
- # Old
965
- print(subject.mean_node.position)
966
-
967
- # New
968
- print(subject.mean_north_lunar_node.position)
969
- ```
1058
+
1059
+ ```python
1060
+ # Old
1061
+ print(subject.mean_node.position)
1062
+
1063
+ # New
1064
+ print(subject.mean_north_lunar_node.position)
1065
+ ```
970
1066
 
971
1067
  5. **Update aspects**
972
- ```python
973
- # Old
974
- from kerykeion import NatalAspects
975
- aspects = NatalAspects(subject)
976
-
977
- # New
978
- from kerykeion import AspectsFactory
979
- aspects = AspectsFactory.single_chart_aspects(subject)
980
- ```
1068
+
1069
+ ```python
1070
+ # Old
1071
+ from kerykeion import NatalAspects
1072
+ aspects = NatalAspects(subject)
1073
+
1074
+ # New
1075
+ from kerykeion import AspectsFactory
1076
+ aspects = AspectsFactory.single_chart_aspects(subject)
1077
+ ```
981
1078
 
982
1079
  #### Automated Migration Script
983
1080
 
@@ -1001,33 +1098,36 @@ find . -name "*.py" -type f -exec sed -i.bak \
1001
1098
 
1002
1099
  ### 📦 Other Notable Changes
1003
1100
 
1004
- - **Packaging**: Migrated from Poetry to PEP 621 + Hatchling with `uv.lock`
1005
- - **Settings**: Centralized in `kerykeion.schemas` and `kerykeion.settings`
1006
- - **Configuration**: Legacy presets available in `settings/legacy/`
1007
- - **Type System**: All literals consolidated in `kr_literals.py`
1008
- - **Performance**: Caching improvements with `functools.lru_cache`
1009
- - **Testing**: 376 tests with 87% coverage, regenerated fixtures for v5
1101
+ - **Packaging**: Migrated from Poetry to PEP 621 + Hatchling with `uv.lock`
1102
+ - **Settings**: Centralized in `kerykeion.schemas` and `kerykeion.settings`
1103
+ - **Configuration**: Default chart presets consolidated in `kerykeion/settings/chart_defaults.py`
1104
+ - **Type System**: All literals consolidated in `kr_literals.py`
1105
+ - **Performance**: Caching improvements with `functools.lru_cache`
1106
+ - **Testing**: 376 tests with 87% coverage, regenerated fixtures for v5
1010
1107
 
1011
1108
  ### 🎨 New Themes
1012
1109
 
1013
1110
  Additional chart themes added:
1014
- - `classic` (default)
1015
- - `dark`
1016
- - `dark_high_contrast`
1017
- - `light`
1018
- - `strawberry`
1111
+
1112
+ - `classic` (default)
1113
+ - `dark`
1114
+ - `dark-high-contrast`
1115
+ - `light`
1116
+ - `strawberry`
1117
+ - `black-and-white`
1019
1118
 
1020
1119
  ### 📚 Resources
1021
1120
 
1022
- - **Full Release Notes**: [v5.0.0.md](release_notes/v5.0.0b1.md)
1023
- - **Documentation**: [kerykeion.readthedocs.io](https://kerykeion.readthedocs.io)
1024
- - **API Reference**: [kerykeion.net/pydocs](https://www.kerykeion.net/pydocs/kerykeion.html)
1025
- - **Examples**: See the `examples/` folder for runnable code
1026
- - **Support**: [GitHub Discussions](https://github.com/g-battaglia/kerykeion/discussions)
1121
+ - **Full Release Notes**: [v5.0.0.md](release_notes/v5.0.0b1.md)
1122
+ - **Documentation**: [kerykeion.readthedocs.io](https://kerykeion.readthedocs.io)
1123
+ - **API Reference**: [kerykeion.net/pydocs](https://www.kerykeion.net/pydocs/kerykeion.html)
1124
+ - **Examples**: See the `examples/` folder for runnable code
1125
+ - **Support**: [GitHub Discussions](https://github.com/g-battaglia/kerykeion/discussions)
1027
1126
 
1028
1127
  **Migration Timeline:**
1029
- - **v5.0**: Current - Backward compatibility layer available
1030
- - **v6.0**: Future - Compatibility layer will be removed
1128
+
1129
+ - **v5.0**: Current - Backward compatibility layer available
1130
+ - **v6.0**: Future - Compatibility layer will be removed
1031
1131
 
1032
1132
  ## Integrating Kerykeion into Your Project
1033
1133
 
@@ -1039,7 +1139,7 @@ This project is covered under the AGPL-3.0 License. For detailed information, pl
1039
1139
 
1040
1140
  As a rule of thumb, if you use this library in a project, you should open-source that project under a compatible license. Alternatively, if you wish to keep your source closed, consider using the [AstrologerAPI](https://rapidapi.com/gbattaglia/api/astrologer/), which is AGPL-3.0 compliant and also helps support the project.
1041
1141
 
1042
- Since the AstrologerAPI is an external third-party service, using it does *not* require your code to be open-source.
1142
+ Since the AstrologerAPI is an external third-party service, using it does _not_ require your code to be open-source.
1043
1143
 
1044
1144
  ## Contributing
1045
1145