Printing a Chart¶
This tutorial combines the concepts from Zodiacal Position (swe.calc_ut(), swe.split_deg()) and Angles and Houses (swe.houses()). You can feel free to skip all the commented-out print() statements; they’re mostly here for verification, especially if you’re using the Python interpreter in interactive mode.
Define constants and calculate Julian day¶
We’re going to calculate the zodiacal positions of the 10 planets, ascendant and midheaven of the initial release of the Swiss Ephemeris C library underlying pyswisseph, which has the following birth information:
1997 September 30
4:00 p.m. CEST (UTC+2) -> 14:00 UTC
Zollikon, Switzerland -> 47.33 N, 8.58 E
import swisseph as swe
from datetime import datetime, timezone
lat = 47.33
lng = 8.58
hsys = b"W"
date = datetime(1997, 9, 30, 14, 0, 0, tzinfo=timezone.utc)
jd_ut, jd_tt = swe.utc_to_jd(
date.year, date.month, date.day, date.hour, date.minute, date.second
)
# print(f"Julian day: {jd_tt}")
# Output:
# Julian day: 2450722.0833377214
b'W': This is the byte character for whole sign houses, but anything works here since cusps are irrelevant to this tutorial.swe.utc_to_jd(): Explained in Quickstart thatjd_ttis more accurate thanjd_utgiven byswe.julday.
Calculate ascendant and midheaven longitudes¶
cusps, ascmc = swe.houses(jd_tt, lat, lng, hsys)
angles = [ascmc[0], ascmc[1]]
# print(f"Ascendant: {angles[0]}")
# print(f"Midheaven: {angles[1]}")
# Output:
# Ascendant: 290.4375225094583
# Midheaven: 230.37565140999195
swe.houses(): We only need the tuple at index1,ascmc, and only its first two elements, so we unpack them into a new list calledanglesfor later concatenation.
Calculate planetary longitudes¶
PLANET_IDS = {
"Sun": swe.SUN,
"Moon": swe.MOON,
"Mercury": swe.MERCURY,
"Venus": swe.VENUS,
"Mars": swe.MARS,
"Jupiter": swe.JUPITER,
"Saturn": swe.SATURN,
"Uranus": swe.URANUS,
"Neptune": swe.NEPTUNE,
"Pluto": swe.PLUTO,
}
planets = []
for name, id_val in PLANET_IDS.items():
coords, flag, _ = swe.calc_ut(jd_tt, id_val) # returns coordinates, flags, and error messages
longitude = coords[0]
planets.append(longitude)
# for name, planet in zip(PLANET_IDS.keys(), planets):
# print(f"{name}: {planet}")
# Output:
# Sun: 187.44207682576493
# Moon: 175.3108433704147
# Mercury: 177.03456720228542
# Venus: 231.25169861097027
# Mars: 241.1545702632383
# Jupiter: 312.18899266331294
# Saturn: 17.660024903370054
# Uranus: 304.81633539199663
# Neptune: 297.20035476146546
# Pluto: 243.46074212504317
PLANET_IDS: This dictionary explicitly uses constants, but you can easily loop over a range as described in Bodies.swe.calc_ut():coords[0]gives ecliptic longitude.
Convert longitudes to DMS¶
objects = planets + angles
zodiacal = []
for point in objects:
dms_split = swe.split_deg(point, swe.SPLIT_DEG_ZODIACAL)
zodiacal.append(dms_split)
# print(zodiacal)
# Output:
# [(7, 26, 31, 0.47657275374280417, 6), (25, 18, 39, 0.03613349287529388, 5), (27, 2, 4, 0.44192822749755756, 5), (21, 15, 6, 0.11499949295648548, 7), (1, 9, 16, 0.45294765787414093, 8), (12, 11, 20, 0.373587926601477, 10), (17, 39, 36, 0.08965213219526191, 0), (4, 48, 58, 0.8074111878721197, 10), (27, 12, 1, 0.2771412 7566374014, 9), (3, 27, 38, 0.6716501554064536, 8), (20, 26, 15, 0.08103404984462159, 9), (20, 22, 32, 0.34507597100455456, 7)]
SIGNS = (
"Ari",
"Tau",
"Gem",
"Can",
"Leo",
"Vir",
"Lib",
"Sco",
"Sag",
"Cap",
"Aqu",
"Pis",
)
swe.split_deg(): Described in Zodiacal Position. This tuple is(degrees, minutes, seconds, fraction_of_seconds, sign index)wheresign_indexis an integer from0to11.SIGNS: This tuple makessign_indexlegible in printing.
Format and print output¶
OBJECT_NAMES = list(PLANET_IDS.keys()) + ["AC", "MC"]
print(f"--- Chart Positions (System: {hsys.decode()}) ---")
for name, dms_split in zip(OBJECT_NAMES, zodiacal):
deg, minute, sec, f_of_s, sign_index = dms_split
sign = SIGNS[int(sign_index)]
position_string = f"{name:<8} {deg:2.0f} {sign} {minute:02} {sec:02.0f}"
print(position_string)
OBJECT_NAMES: Concatenates the dictionary keys fromPLANET_IDSwith ourangleslist.dms_split: This is where we getsign_indexat index 4.
Expected output¶
If you ran the complete script (tutorial.py), the final output should look like this:
--- Chart Positions (System: W) ---
Sun 7 Lib 26 31
Moon 25 Vir 18 39
Mercury 27 Vir 02 04
Venus 21 Sco 15 06
Mars 1 Sag 09 16
Jupiter 12 Aqu 11 20
Saturn 17 Ari 39 36
Uranus 4 Aqu 48 58
Neptune 27 Cap 12 01
Pluto 3 Sag 27 38
AC 20 Cap 26 15
MC 20 Sco 22 32
Tutorial app¶
You can input your own birth information in the if __name__ = "__main__" block of tutorial_app.py:
if __name__ == "__main__":
# User inputs here!
BIRTH_DATA = {
"date": datetime(1997, 7, 19, 12, 0, 0, tzinfo=timezone.utc),
"lat": 35.6897,
"lng": 139.69,
"hsys": b"W",
}