CODE FOR A FICTION

Syntax of Imagination.
  • Baner imager of Code for a fiction

    Welcome to CODE OF A FICTION

    Syntax of Imagination” melds the precision of coding with the vastness of creative thought, crafting a digital narrative where every command is a creation.

Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Saturday, March 23, 2024

Creating North Indian Style Vedic Astrology Charts with Python and SVGWRITE

North India Chart Generation


In this blog post, I will share with you how to create North Indian-style Vedic astrology charts using Python. The tools I will be using will be the svgwrite library, a powerful resource that enables us to craft SVG (Scalable Vector Graphics) files programmatically. Let’s start.

Imports

The Python libraries used in our code are: 
  • svgwrite: This library provides an interface for creating SVG files.
  • math: This library provides mathematical functions. 
  • random: This library is used to generate random numbers. 

Code

The code begins by importing the necessary libraries:

import svgwrite
from svgwrite import cm, mm
import math
import random
Next, this creates a new SVG document using svgwrite.Drawing. The size of the drawing is set to 100% of the viewport, and the SVG profile is set to ‘full’, which allows for the most features: 


dwg = svgwrite.Drawing('astrology_chart.svg', size=("100%", "100%"), profile='full') 

This would set the width and height of the SVG to ‘100%’, which means the SVG will take up 100% of the width and height of its container. The viewBox attribute is used to specify the aspect ratio and coordinate system of the SVG. In this case, we set it to ‘0 0 800 600’, which means the width and height of the SVG’s coordinate system are 100 units.

# Set the size of the SVG to a percentage of the viewport
dwg.attribs['width'] = '100%'
dwg.attribs['height'] = '100%'
dwg.attribs['viewBox'] = '0 0 800 600'
This would define a linear gradient and add it to the defs section of the SVG. This gradient will be used to fill the polygons that represent the houses in the chart:

gradient = svgwrite.gradients.LinearGradient(start=(0, 0), end=(0, 1), id="grad")
gradient.add_stop_color(0, 'white')
gradient.add_stop_color(1, '#f0f3bf')
dwg.defs.add(gradient)
The houses in the chart are represented as polygons. The points for each polygon are defined, and then the polygon is created and added to the SVG drawing:

points_h1 = [(100,225), (200,300), (300,225), (200,150)]
h1 = svgwrite.shapes.Polygon(points_h1, fill="url(#grad)")
dwg.add(h1)
This process is repeated for each of the 12 houses. The centers of the polygons (houses) are defined in the centers list:

centers = [
    (190, 75),  # 1st house
    (100, 30),   # 2nd house
    (30, 75),   # 3rd house
    (90, 150),  # 4th house
    (30, 225),     # 5th house
    (90, 278),  # 6th house
    (190, 225),  # 7th house
    (290, 278),  # 8th house
    (360, 225),    # 9th house
    (290, 150),  # 10th house
    (360, 75),  # 11th house
    (290, 30),   # 12th house
]
Each tuple in the list represents the (x, y) coordinates of the center of a house. The coordinates are defined in the SVG’s coordinate system. The placeholders for the planets are generated in a circular arrangement around the center of each house. This is done in the following part of the code: Next, we randomly assign each planet to a house. The planets are represented as text elements, which are placed in a circular arrangement within each house:

for i, center in enumerate(centers):
    house_planets = houses[i]
    for j, planet in enumerate(house_planets):
        angle = 2 * math.pi * j / len(house_planets)
        x = center[0] + radius * math.cos(angle)
        y = center[1] + radius * math.sin(angle)
        color = colors[planets.index(planet)]
        dwg.add(dwg.text(planet[:2], insert=(x, y), font_size='11px', fill=color))
In this part of the code, I first iterated over the list of centers, which are the center points of each house. For each house, i would get the list of planets assigned to that house. Then i iterated over this list of planets. For each planet, i calculated an angle based on the index of the planet in the list and the total number of planets in the house. This angle is used to calculate the x and y coordinates of the planet’s position within the house. The position is calculated such that the planets are arranged in a circular pattern around the center of the house. Finally, the SVG document is saved:

dwg.save()
After running the Python script, an SVG file named ‘astrology_chart.svg’ will be generated. This file contains a graphical representation of the North Indian style Vedic astrology chart. The chart consists of 12 houses, each represented by a polygon. Each house contains one or more planets, represented by text elements. The planets are arranged in predefined placeholder within each house. The size and position of the elements in the chart are calculated dynamically, so the chart can be easily customized by modifying the code. Open the SVG file in a web browser or image viewer to see the generated chart. The chart should look similar to the image provided below.


You can find the complete code for generating the North Indian style Vedic astrology chart on my GitHub GIST. Feel free to clone, and explore the code in more detail. If you have any questions or suggestions, don’t hesitate to post. Happy coding!

Additional Details 

The colors of the planets are defined in the colors list. Each color corresponds to a planet in the planets list. The colors are then used to fill the text elements that represent the planets. The houses are randomly generated for testing purposes. In a real-world application, i would replace this with the actual house data. 

Possible Improvements 

While this code serves its purpose, there are several ways it could be improved: 
  • Modularization: The code could be broken down into functions to improve readability and reusability.
  • Error Handling: The code currently does not handle any errors or exceptions. Adding error handling would make the code more robust. 
  • Customization: The code could be modified to allow for more customization, such as different color schemes or chart styles. 
Share:

Friday, March 22, 2024

Getting Started with Swiss Ephemeris in Python for Astrological Calculations

Swisseph

The Swiss Ephemeris (swisseph) library is a powerful tool for high-precision astronomical and astrological calculations. Here are some reasons why you might want to use it:

  1. High Precision: Swiss Ephemeris is based on the DE431 ephemeris from NASA’s Jet Propulsion Laboratory (JPL), which is one of the most accurate ephemerides available. This makes it suitable for applications that require high precision, such as astrology, astronomy, and celestial navigation.
  2. Wide Time Range: Swiss Ephemeris covers a wide time range, from 13201 BCE to 17191 CE. This makes it useful for historical research, as well as for predicting future celestial events.
  3. Comprehensive Features: Swiss Ephemeris provides a wide range of features, including the calculation of planetary positions, houses, aspects, transits, solar and lunar returns, and more. It also provides functions for calculating sunrise and sunset times, as well as other astronomical phenomena.
  4. Ease of Use: Swiss Ephemeris provides a simple and intuitive API, making it easy to use in your applications. It also provides bindings for several programming languages, including Python, which makes it accessible to a wide range of developers.
  5. Open Source: Swiss Ephemeris is open source, which means you can use it for free in your applications, and you can also contribute to its development if you wish.Installation 

Swisseph can be installed in Python using pip, which is a package manager for Python. You can install it by running the following command in your terminal:

pip install pyswisseph
Make sure that you have pip installed and that Python is in your system’s path. 

Basic Usage 

Once you have installed swisseph, you can import it in your Python script as follows:

import swisseph as swe
Before making any calculations, it’s important to set the Ayanamsha. For Vedic astrology, N.C. Lahiri is commonly used:

swe.set_sid_mode(swe.SIDM_LAHIRI)
You can calculate the position of a planet using the calc_ut function. For example, to calculate the position of the Sun:

jd = swe.julday(2024, 3, 21)
xx, ret = swe.calc_ut(jd, swe.SUN)
The calc_ut function returns two values: xx and ret. xx is a list that contains the longitude, latitude, distance, and speed of the planet. ret is a flag that indicates whether the calculation was successful. 

Advanced Usage 

Swisseph can also calculate the Ascendant (Lagna), Rasi (Zodiac sign), planetary positions, houses of each planet, sunrise and sunset times, Tithi (Lunar day), and Vara (Day of the week) for a specified date, time, and location. This can serve as the foundation for a more complex astrological software. Here’s an example script that demonstrates these calculations:

import swisseph as swe
import json
from datetime import datetime

# Set the path to the Swiss Ephemeris data files
swe.set_ephe_path('ephe')

# Set the Ayanamsha to N.C. Lahiri
swe.set_sid_mode(swe.SIDM_LAHIRI)

# Get user input
name = input("Enter name: ")
dob = input("Enter date of birth (YYYY-MM-DD): ")
tob = input("Enter time of birth (HH:MM:SS): ")
place_of_birth = input("Enter place of birth: ")
latitude = float(input("Enter latitude: "))
longitude = float(input("Enter longitude: "))

# Parse the date and time of birth
year, month, day = map(int, dob.split('-'))
hour, minute, second = map(int, tob.split(':'))

# Calculate Julian Day
jd = swe.julday(year, month, day, hour + minute/60 + second/3600)

# Calculate the Ascendant using Equal house system
asc = swe.houses(jd, latitude, longitude, b'E')[0][0]

# Calculate the Rasi (Zodiac sign)
rasi = int((asc % 360) / 30)

# Calculate planetary positions and houses
planets = ['Sun', 'Moon', 'Mercury', 'Venus', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto']
planet_positions = {}
planet_houses = {}
for i, planet in enumerate(planets):
    xx, ret = swe.calc_ut(jd, i, swe.FLG_SPEED)  # Include velocities in the output
    planet_positions[planet] = xx[0]  # Longitude of the planet
    planet_houses[planet] = swe.house_pos(asc, latitude, 'E', xx[0], xx[1])  # House of the planet

# Calculate sunrise and sunset
next_sunrise = swe.rise_trans(jd, swe.SUN, geopos=(longitude, latitude, 0), rsmi=swe.CALC_RISE)[1][0]
next_sunset = swe.rise_trans(jd, swe.SUN, geopos=(longitude, latitude, 0), rsmi=swe.CALC_SET)[1][0]

# Convert sunrise and sunset times to date-time format
next_sunrise = datetime.fromtimestamp(swe.revjul(next_sunrise)).strftime('%Y-%m-%d %H:%M:%S')
next_sunset = datetime.fromtimestamp(swe.revjul(next_sunset)).strftime('%Y-%m-%d %H:%M:%S')

# Calculate Tithi (Lunar day)
moon_long = swe.calc_ut(jd, swe.MOON)[0][0]
sun_long = swe.calc_ut(jd, swe.SUN)[0][0]
tithi = int((moon_long - sun_long) % 360 / 12) + 1

# Calculate Vara (Day of the week)
vara = int((jd + 1) % 7)
vara_names = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']

# Create a dictionary to store the results
data = {
    "name": name,
    "date_of_birth": dob,
    "time_of_birth": tob,
    "place_of_birth": place_of_birth,
    "latitude": latitude,
    "longitude": longitude,
    "ascendant": asc,
    "rasi": rasi,
    "planet_positions": planet_positions,
    "planet_houses": planet_houses,
    "next_sunrise": next_sunrise,
    "next_sunset": next_sunset,
    "tithi": tithi,
    "vara": vara_names[vara]
}

# Convert the dictionary to a JSON string
json_data = json.dumps(data, indent=4)

# Print the JSON string
print(json_data)
This script demonstrates how to use swisseph to perform a variety of astrological calculations. It serves as a good starting point for developing more complex astrological software. 

NOTE 

The swe.set_ephe_path('ephe') function is used to set the path to the directory containing the Swiss Ephemeris data files. These data files are necessary for the Swiss Ephemeris library to perform astronomical calculations. 
The argument 'ephe' is the path to the directory containing the data files. This can be an absolute path or a relative path. In this case, 'ephe' is a relative path, which means that the ephe directory is located in the same directory as the Python script. Here’s an example of how to use this function:

import swisseph as swe

# Set the path to the Swiss Ephemeris data files
swe.set_ephe_path('ephe')

# Now you can use other functions from the Swiss Ephemeris library
jd = swe.julday(2024, 3, 21)
xx, ret = swe.calc_ut(jd, swe.SUN)

print(f"The position of the Sun on March 21, 2024 is {xx[0]} degrees.")
In this example, the swe.set_ephe_path('ephe') function is called before any other Swiss Ephemeris functions. This ensures that the Swiss Ephemeris library knows where to find the data files it needs to perform calculations. 

Please note that you need to have the Swiss Ephemeris data files in the ephe directory for this to work. If the data files are not found, the Swiss Ephemeris library will not be able to perform calculations and will raise an error. You can download the Swiss Ephemeris data files from the Astrodienst website or GITHUB. Please note that this is a very basic calculation and may not be accurate for all purposes. For more accurate calculations, consider using a library specifically designed for Vedic astrology.
Share:

Comments

Belive in yourself

Code for a fiction