Zeta Oph's Study

matplotlib을 이용한 우주 거대 구조 지도 그리기 본문

프로그래밍

matplotlib을 이용한 우주 거대 구조 지도 그리기

Zeta Oph 2023. 3. 22. 01:48

이 글에서는 matplotlib을 이용하여 우주 거대 구조 지도를 그리는 과정을 설명하겠습니다.


matplotlib 이란?

matplotlib은 그래프를 손쉽게 그릴 수 있도록 도와주는 파이썬 라이브러리입니다.

matplotlib의 함수들을 이용하면 그래프, 산점도 등을 그리고, 이들의 축, 레이블 등을 손쉽게 꾸밀 수 있습니다.


SDSS(Sloan Digital Sky Survey) 란?

SDSS는 전 하늘의 약 35%를 차지하는 영역의 천체들에 대해 측광, 스펙트럼 수집을 진행한, 대규모 적색편이 탐사 프로젝트입니다. SDSS의 관측 자료는 현재 모두 무료로 공개되어 있으며, 수많은 멀리 있는 외부은하들의 등급, 적색편이값 등을 담고 있습니다.


간단한 이론적 배경

우주론에서, 허블-르메트르 법칙은 아래와 같이 주어집니다.

$$v=H_0 d$$

$$(v : 후퇴 속도, H_0 : 허블 상수, d : 천체까지의 거리)$$

 

또한, 빠른 속도로 멀어지는 천체에 대해서는 도플러 효과가 나타나는데, 우주 팽창의 규모에서는 굉장히 빠른 속도로 은하들이 후퇴하기 때문에, 상대론적 도플러 효과를 적용해주어야 합니다. 그 식은 아래와 같습니다.

$$1+z=\frac{\sqrt{1+v/c}}{\sqrt{1-v/c}}$$

$$(z : 적색편이)$$

 

이제 상대론적 도플러 효과 식과 허블-르메트르 법칙을 결합하면, 천체까지의 거리 $d$와 적색편이 $z$ 사이 관계를 나타내는 식을 찾을 수 있습니다.

$$d=\frac{(1+z)^2-1}{(1+z)^2+1}\frac{c}{H_0}$$

 

저는 여기서 SDSS의 데이터를 이용하여, 각 은하의 z값을 대입하여 은하까지의 거리 d를 알아낸 후 그 은하의 적경 값에 따라 극좌표계에 점을 찍어주면 우주에서 은하들이 어떻게 분포하는지 알 수 있는, 즉 우주 거대 구조 지도를 그리기로 하였습니다.


코드 작성

우선 저는 코드를 어떻게 작성할 지 대략적인 순서도를 그려보았습니다.

이때 convertra 함수는, csv 파일에 시:분:초 형식으로 입력되어 있는 적경 값을 라디안 값으로 바꾸어주는 함수입니다.

convertra 함수의 순서도는 아래와 같습니다.

순서도를 바탕으로 작성한 코드는 아래와 같습니다.

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

H0 = 67.8
C = 299792.458

df = pd.read_csv("C:/Users/dlgkr/Desktop/자료/LSS/LSS Sloan Data.csv") //파일 경로

df = pd.DataFrame(df, columns=['ra','z'])
ra0 = df['ra'].values.tolist()
z0 = df['z'].values.tolist()

def convertra(ra0):
    ra0 = ra0[1:-1]
    h, m, s = ra0.split(':', 2)
    h = float(h)
    m = float(m)
    s = float(s)
    ra1 = (h + m/60 + s/3600)*15*np.pi/180
    return ra1

ra = list(map(convertra, ra0))

ra = np.array(ra)
z = np.array(z0)

d = (((1+z)**2 - 1)/((1+z)**2 + 1))*C/H0

fig = plt.figure(figsize=(15, 7))

ax = fig.add_subplot(121, projection='polar')
plt.grid(False)
plt.xlabel('RA [hour]')
ax.set_xticks(np.arange(0,2.0*np.pi,np.pi/12.0), labels=['0h', '', '', '3h', '', '', '6h', '', '', '9h', '', '', '12h', '', '', '15h', '', '', '18h', '', '', '21h', '', ''])
plt.ylabel('Distance [Mpc]', labelpad=27)
ax.set_ylim(0,450)
ax.set_yticks(np.arange(0,450,150), labels=['', '', ''])
ax.set_facecolor('k')
ax.set_title("Large Scale Structure of Universe - Sloan Great Wall (450Mpc)", va='bottom')
colors = d/450
plt.scatter(ra, d, s=0.003, alpha=0.6, c=colors, cmap='YlOrBr')

ax = fig.add_subplot(122, projection='polar')
plt.grid(False)
plt.xlabel('RA [hour]')
ax.set_xticks(np.arange(0,2.0*np.pi,np.pi/12.0), labels=['0h', '', '', '3h', '', '', '6h', '', '', '9h', '', '', '12h', '', '', '15h', '', '', '18h', '', '', '21h', '', ''])
plt.ylabel('Distance [Mpc]', labelpad=27)
ax.set_ylim(0,600)
ax.set_yticks(np.arange(0,600,200), labels=['','',''])
ax.set_facecolor('k')
ax.set_title("Large Scale Structure of Universe - Sloan Great Wall (600Mpc)", va='bottom')
colors = d/450
plt.scatter(ra, d, s=0.003, alpha=0.6, c=colors, cmap='YlOrBr')

plt.show()

이제 코드 내용을 간단하게나마 설명해보겠습니다.

 

SDSS의 데이터를 담은 csv파일에는 은하의 적경(ra), 적색편이(z) 값이 포함되어 있습니다. 이 csv파일을 입력받아 ra열과 z열만 뽑아와 주고 이를 ra0와 z0라는 변수에 저장합니다.

극좌표 산점도를 그릴 때 각도로 이용하기 위해, ra0의 각 값들을 convertra 함수에 대입하여 적경 값을 라디안 단위로 바꾸어줍니다. 그리고 나서 ra0와 z0의 자료형을 list에서 numpy array로 바꾸어줍니다. 이때 변수 이름도 함께 ra와 z로 바꾸어주었습니다. 위에서 구한 식을 이용하여 거리 d 값들을 담은 array를 계산해줍니다.

거리가 450Mpc인 은하들까지 나타낸 지도와 거리가 600Mpc인 은하까지 나타낸 지도 2개를 그리기 위해, 2개의 극좌표 산점도를 plot해줍니다. 각 축의 이름, 눈금, 범위, 제목 등을 설정해준 후, plt.scatter 함수를 이용하여 각도를 ra, 반지름을 d로 하여 산점도를 찍어주면 완성입니다.

 

위 코드의 실행 결과는 아래와 같습니다.

우주 거대 구조

지도를 보시면, 우주에는 은하들이 균일하게 분포하지 않고 그물망처럼 분포하여 특정 지역에 몰려 있는 것을 알 수 있습니다. 이러한 구조를 우주 거대 구조라고 합니다. 또한 왼쪽 지도 왼쪽 구역에, 중심부에서 많이 떨어져있지 않은 지점에서 은하들이 벽처럼 뭉쳐있는 구조를 보실 수 있을 겁니다. 이 구조를 슬론 장성이라고 합니다. 슬론 장성은 SDSS 프로젝트를 통해서 처음 발견되었으며, 그 크기는 약 13.8억 광년이라고 합니다.

 

 

지금까지 SDSS 데이터와 matplotlib을 이용하여 우주 거대 구조 지도를 그려보았습니다. 

(사용한 SDSS 데이터 : https://drive.google.com/file/d/1CBe-HA0CB0oZNy-3fEjyaw1T3SD7bp6G/view?usp=sharing)

 

LSS Sloan Data.zip

 

drive.google.com