Neyse, sorunu matplotlib modülü yerine tkinter modülünü kullanarak çözdüm.
Kodlar:
#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
import swisseph as swe
import tkinter as tk
from math import cos, sin, radians
from PIL import ImageTk
root = tk.Tk()
root.title("Astro-Python")
root.resizable(width=False, height=False)
canvas = tk.Canvas(master=root, bg="white", width=800, height=600)
canvas.pack(fill="both", expand=True)
def oval_object(x, y, r):
canvas.create_oval(
x - r,
y - r,
x + r,
y + r,
fill="white",
width=2
)
def line_object(x1, y1, x2, y2, width=2):
canvas.create_line(x1, y1, x2, y2, width=width)
def text_object(x, y, text, width=0):
canvas.create_text(x, y, text=text, width=width)
def image_object(x, y, image):
canvas.create_image(x, y, image=image)
class Chart:
SIGNS = ["Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
"Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"]
FILES = [f"images/{i}.png" for i in SIGNS]
IMAGE_FILES = {i[:-4]: ImageTk.PhotoImage(file=i) for i in FILES}
MIDPOINT_OF_HOUSES = []
def __init__(self, year, month, day, hour, minute, longitude, latitude):
self.year = year
self.month = month
self.day = day
self.hour = hour
self.minute = minute
self.longitude = longitude
self.latitude = latitude
oval_object(x=400, y=300, r=200)
oval_object(x=400, y=300, r=150)
oval_object(x=400, y=300, r=50)
self.draw_houses()
self.draw_signs()
self.draw_house_numbers()
self.draw_sign_symbols()
@staticmethod
def dd_to_dms(dd):
degree = int(dd)
minute = int((dd - degree) * 60)
second = float((dd - degree - minute / 60) * 3600)
return f"{degree}\u00b0 {minute}' {second}\""
@staticmethod
def dms_to_dd(dms):
degree = int(dms.split(" ")[0])
minute = float(dms.split(" ")[1]) / 60
second = float(dms.split(" ")[2]) / 3600
return degree + minute + second
def utc_time(self):
longitude = int(self.longitude)
hour = float(self.hour)
if longitude == 0:
return hour
elif longitude in range(1, 16):
return hour - 1
elif longitude in range(-16, -1):
return hour + 1
elif longitude in range(16, 31):
return hour - 2
elif longitude in range(-31, -16):
return hour + 2
elif longitude in range(31, 46):
return hour - 3
elif longitude in range(-46, -31):
return hour + 3
elif longitude in range(46, 61):
return hour - 4
elif longitude in range(-61, -46):
return hour + 4
elif longitude in range(61, 76):
return hour - 5
elif longitude in range(-76, -61):
return hour + 5
elif longitude in range(76, 91):
return hour - 6
elif longitude in range(-91, -76):
return hour + 6
elif longitude in range(91, 106):
return hour - 7
elif longitude in range(-106, -91):
return hour + 7
elif longitude in range(106, 121):
return hour - 8
elif longitude in range(-121, -106):
return hour + 8
elif longitude in range(121, 136):
return hour - 9
elif longitude in range(-136, -121):
return hour + 9
elif longitude in range(136, 151):
return hour - 10
elif longitude in range(-151, -136):
return hour + 10
elif longitude in range(151, 166):
return hour - 11
elif longitude in range(-166, -151):
return hour + 11
elif longitude in range(166, 181):
return hour - 12
elif longitude in range(-181, -166):
return hour + 12
def julday(self):
jd = swe.julday(
self.year, self.month, self.day, self.utc_time() + self.minute / 60)
deltat = swe.deltat(jd)
return round(jd + deltat, 6)
@staticmethod
def convert_angle(angle):
if 0 < angle < 30:
return angle, "Aries"
elif 30 < angle < 60:
return angle - 30, "Taurus"
elif 60 < angle < 90:
return angle - 60, "Gemini"
elif 90 < angle < 120:
return angle - 90, "Cancer"
elif 120 < angle < 150:
return angle - 120, "Leo"
elif 150 < angle < 180:
return angle - 150, "Virgo"
elif 180 < angle < 210:
return angle - 180, "Libra"
elif 210 < angle < 240:
return angle - 210, "Scorpio"
elif 240 < angle < 270:
return angle - 240, "Sagittarius"
elif 270 < angle < 300:
return angle - 270, "Capricorn"
elif 300 < angle < 330:
return angle - 300, "Aquarius"
elif 330 < angle < 360:
return angle - 330, "Pisces"
def planet_pos(self, planet):
calc = self.convert_angle(swe.calc_ut(self.julday(), planet)[0])
return self.dd_to_dms(calc[0]), calc[1]
def house_cusps(self):
houses = []
asc = 0
angle = []
for i, j in enumerate(swe.houses(self.julday(), self.latitude, self.longitude)[0]):
if i == 0:
asc += j
angle.append(j)
houses.append((
f"House {i + 1}:",
f"{self.dd_to_dms(self.convert_angle(j)[0])}",
f"{self.convert_angle(j)[1]}"))
return houses, asc, angle
def house_pos(self):
return self.house_cusps()[2]
def sign_pos(self):
asc = self.house_cusps()[1]
degree = self.house_cusps()[0][0][1].replace("'", "").replace('"', "").replace("\u00b0", "")
end = 30 - self.dms_to_dd(degree) + asc
start = end - 30
signs = []
for i, j in enumerate(self.house_cusps()[0]):
signs.append(j[2])
for i in self.SIGNS:
if i not in signs:
index_1 = self.SIGNS.index(i) + 1
sign = self.SIGNS[index_1]
index_2 = signs.index(sign)
signs.insert(index_2, i)
for i in signs:
count = signs.count(i)
if count > 1:
signs.pop(signs.index(i, 1))
_signs_ = []
for i, j in enumerate(signs):
_start = start + (i * 30)
_end = end + (i * 30)
if _start > 360:
_start -= 360
if _end > 360:
_end -= 360
_signs_.append(_start)
return _signs_, signs
@staticmethod
def line_components(angle, r):
x1, y1 = 400, 300
x2 = x1 + (r * cos(radians(angle)))
y2 = y1 - (r * sin(radians(angle)))
return x1, y1, x2, y2
def x_y(self, angle, r1, r2):
x1, y1, x2, y2 = self.line_components(angle=angle, r=r1)
_x1, _y1, _x2, _y2 = self.line_components(angle=angle, r=r2)
return x2, y2, _x2, _y2
def draw_houses(self):
for i, j in enumerate(self.house_pos()):
_degree = j - (self.house_pos()[0] - 180)
if _degree < 0:
_degree += 360
elif _degree > 360:
_degree -= 360
self.MIDPOINT_OF_HOUSES.append(_degree)
x1, y1, x2, y2 = self.x_y(angle=_degree, r1=50, r2=150)
if i == 0 or i == 3 or i == 6 or i == 9:
line_object(x1, y1, x2, y2, width=4)
else:
line_object(x1, y1, x2, y2, width=2)
def draw_signs(self):
sign_pos = self.sign_pos()[0]
for i in sign_pos:
_degree = i - (self.house_pos()[0] - sign_pos[1])
if _degree > 360:
_degree -= 360
x1, y1, x2, y2 = self.x_y(angle=_degree, r1=150, r2=200)
line_object(x1, y1, x2, y2, width=2)
def draw_house_numbers(self):
for i, j in enumerate(self.MIDPOINT_OF_HOUSES):
if i == 11:
midpoint = (self.MIDPOINT_OF_HOUSES[i] + self.MIDPOINT_OF_HOUSES[0]) / 2
else:
if self.MIDPOINT_OF_HOUSES[i] == 360:
midpoint = self.MIDPOINT_OF_HOUSES[i + 1] / 2
else:
if self.MIDPOINT_OF_HOUSES[i + 1] == 0:
midpoint = (self.MIDPOINT_OF_HOUSES[i] + self.MIDPOINT_OF_HOUSES[i + 1] + 360) / 2
else:
midpoint = (self.MIDPOINT_OF_HOUSES[i] + self.MIDPOINT_OF_HOUSES[i + 1]) / 2
x1, y1, x2, y2 = self.x_y(angle=midpoint, r1=50, r2=150)
x = (x1 + x2) / 2
y = (y1 + y2) / 2
text_object(x=x, y=y, text=f"{i + 1}")
def draw_sign_symbols(self):
asc = self.house_cusps()[1]
for i, j in enumerate(self.SIGNS):
end = 30 - (asc % 30) + 180
start = end - 30
start += (30 * i)
end += (30 * i)
if start > 360:
start -= 360
if end > 360:
end -= 360
if start > 330:
midpoint = (start + end + 360) / 2
else:
midpoint = (start + end) / 2
if midpoint > 360:
midpoint -= 360
x1, y1, x2, y2 = self.x_y(angle=midpoint, r1=150, r2=200)
x = (x1 + x2) / 2
y = (y1 + y2) / 2
image_object(
x=x,
y=y,
image=self.IMAGE_FILES[f"images/{self.sign_pos()[1][i]}"]
)
chart = Chart(1985, 12, 30, 5, 5, 8.32, 47.31)
root.mainloop()
Edit: Burçların ve gezegenlerin grafik dosyaları yerine unicode karakterleri de kullanılabilir.