José Miguel Ladino Méndez - Maestría en Ciencias Astronomía - UNAL

LACoNGA Physics - Ciencia de Datos - Tarea-Clase-08-datos

Documento de análisis de los datos .csv y .root

Realizado desde la maquina virtual de Atlas-Open-Data-ubuntu-2020-v4 a través de Oracle VM VirtualBox.

Datos .csv con las temperaturas, las luminosidades, los radios, las magnitudes absolutas, los tipos, los colores y las correspondientes clasificaciónes espectrales de 240 estrellas (base de datos de Kaggle).

In [1]:
import pandas as pd #importando librerías
import numpy as np
import ROOT
Welcome to JupyROOT 6.18/04
In [2]:
%jsroot on
In [3]:
stars= pd.read_csv('../data-used/stars.csv') #leyendo el .csv con pandas
stars
Out[3]:
Temperature(K) Luminosity(L/Lo) Radius(R/Ro) Absolute_magnitude(Mv) Star_type Star_color Spectral_Class
0 3068 0.002400 0.1700 16.12 0 Red M
1 3042 0.000500 0.1542 16.60 0 Red M
2 2600 0.000300 0.1020 18.70 0 Red M
3 2800 0.000200 0.1600 16.65 0 Red M
4 1939 0.000138 0.1030 20.06 0 Red M
... ... ... ... ... ... ... ...
235 38940 374830.000000 1356.0000 -9.93 5 Blue O
236 30839 834042.000000 1194.0000 -10.63 5 Blue O
237 8829 537493.000000 1423.0000 -10.73 5 White A
238 9235 404940.000000 1112.0000 -11.23 5 White A
239 37882 294903.000000 1783.0000 -7.80 5 Blue O

240 rows × 7 columns

Convention:

Brown Dwarf -> Star Type = 0

Red Dwarf -> Star Type = 1

White Dwarf-> Star Type = 2

Main Sequence -> Star Type = 3

Supergiant -> Star Type = 4

Hypergiant -> Star Type = 5

Para poder convertir el archivo .csv correctamente a .root, es necesario modificar el .csv,

In [4]:
stars.replace(',','_', regex=True, inplace=True) #remplazar , por _
stars.replace(' ','_', regex=True, inplace=True) #remplazar espacios por _

#pandas, 

stars = stars.reset_index(drop=True) 
stars = stars.dropna()
stars.to_csv('../codigo/starsmod.csv')

Luego de convertir el .csv a .root en el archivo convert_csv_to_root.ipynb

In [5]:
starsmod = ROOT.TFile.Open("../codigo/starsmod.root") #abriendo data en formato .root

Histograma para las magnitudes absolutas de las estrellas

La magnitud absoluta M es la magnitud convencional que tendría la estrella si su distancia fuese llevada a 10pc (Definición).

In [6]:
tree = starsmod.Get("ntuple") #obteniendo data
tree
tree.GetEntries() #número de filas
Out[6]:
240
In [7]:
canvas = ROOT.TCanvas("Canvas","Magnitud absoluta(Mv)",800,600)
hist = ROOT.TH1F("Magnitud absoluta(Mv)",
                 "Magnitud absoluta de las estrellas; Intervalos de magnitud absoluta (Mv) ; Numero de estrellas ",
                 7,-15,27)
 
for event in tree:
    hist.Fill(tree.Absolute_magnitude)
    
hist.SetFillColor(1)
hist.Draw()
canvas.Draw()
In [8]:
80*100/240
Out[8]:
33.333333333333336

Un 33.3% de las estrellas tienen una magnitud absoluta entre 9 Mv a 15 Mv.

Histograma para las temperaturas de las estrellas

In [9]:
canvas2 = ROOT.TCanvas("Canvas2","Temperatura(K)",800,600)
hist2 = ROOT.TH1F("Temperatura(K)",
                  "Temperatura de las estrellas; Intervalos de Temperatura (K) ; Numero de estrellas ",7,0,40490)

for event in tree:
    hist2.Fill(tree.Temperature)
    
hist2.SetFillColor(2)
hist2.Draw()
canvas2.SetLogy()
canvas2.Draw()
In [10]:
120*100/240
Out[10]:
50.0

El 50% de las estrellas tienen una temperatura entre 0 °K y 5000 °K

Histograma para las luminosidades de las estrellas

La luminosidad es la cantidad de potencia (energía por unidad de tiempo) emitida en todas direcciones por un cuerpo celeste definición.

In [11]:
canvas3 = ROOT.TCanvas("Canvas3","Luminosidad(L/Lo)",800,600)
hist3 = ROOT.TH1F("Luminosidad(L/Lo)",
                  "Luminosidad de las estrellas (L/Lo); Intervalos de luminosidad (L/Lo) ; Numero de estrellas ",
                  7,0,900000)

for event in tree:
    hist3.Fill(tree.Luminosity)
    
hist3.SetFillColor(3)
hist3.Draw()
canvas3.SetLogy()
canvas3.Draw()
In [12]:
162*100/240
Out[12]:
67.5

El 67% de las estrellas tienen una luminosidad entre 0 L/Lo y 100000 L/Lo

Histograma para los radios de las estrellas

In [13]:
canvas4 = ROOT.TCanvas("Canvas4","Radio(R/Ro)",800,600)
hist4 = ROOT.TH1F("Radio(R/Ro)",
                  "Radios de las estrellas (R/Ro); Intervalos del cociente de radios (R/Ro);Numero de estrellas",
                  7,0,2249)

for event in tree:
    hist4.Fill(tree.Radius)

hist4.SetFillColor(4)
hist4.Draw()
canvas4.SetLogy()
canvas4.Draw()
In [14]:
200*100/240
Out[14]:
83.33333333333333

El 83.3% de las estrellas tienen un radio entre 0 R/Ro y 321.3 R/Ro

Diagrama Hertzsprung - Russell

In [15]:
import matplotlib.pyplot as plt

def Temperatura(star):
    T=[]
    for j in star:
        T.append(j[0])
    return T

def Luminosidad(star):
    T=[]
    for j in star:
        T.append(j[1])
    return T

def Radios(star):
    T=[]
    for j in star:
        T.append(j[2])
    return T

def Mag(star):
    T=[]
    for j in star:
        T.append(j[3])
    return T
starsa=np.array(stars)
plt.figure(figsize = (15,10))
plt.title('Diagrama Hertzsprung - Russell\n', fontsize = 12, fontweight = 'bold')
plt.xlabel('Temperatura (K)', fontsize=12, fontweight = 'bold')
plt.ylabel('Luminosidad ($L_{Sol}$)', fontsize = 12, fontweight = 'bold')
plt.xlim(40000, 0)
plt.ylim(0.00001,100000000)
plt.yscale('log')

plt.text(35000, 9000000, 'Gigantes\n  azules', fontsize = 14, fontweight = 'bold')
plt.text(7200, 9000000, 'Supergigantes\n       rojas', fontsize = 14, fontweight = 'bold')
plt.text(7200, 500, 'Gigantes\n    rojas', fontsize = 14, fontweight = 'bold')
plt.text(14000, 8, 'Secuencia\n principal', fontsize = 14, fontweight = 'bold')
plt.text(9500, 0.005, 'Enanas\nblancas', fontsize = 14, fontweight = 'bold')

plt.scatter(Temperatura(starsa), Luminosidad(starsa), Radios(starsa)*25, Temperatura(starsa), edgecolors = 'k', cmap = 'RdYlBu')
#plt.colorbar() # para ver barra de colores de convensión en función de la temperatura
plt.show()

Porcentajes para los tipos de estrellas y clases espectrales

In [16]:
stars['Star_type'].value_counts()
Out[16]:
5    40
4    40
3    40
2    40
1    40
0    40
Name: Star_type, dtype: int64
In [17]:
stars['Spectral_Class'].value_counts()
Out[17]:
M    111
B     46
O     40
A     19
F     17
K      6
G      1
Name: Spectral_Class, dtype: int64
In [18]:
tipos=["M","B","O","A","F","K","G"]
tipos2=["Brown Dwarf","Red Dwarf", "White Dwarf", "Main Sequence Star", "Supergiant","Hypergiant"  ]
plt.figure(figsize = (15,10))
plt.subplot(121)
plt.title('Tipos de estrellas ', fontsize = 12, fontweight = 'bold')
plt.pie(stars['Star_type'].value_counts(), labels=tipos2, autopct="%0.1f %%")
plt.axis("equal")
plt.subplot(122)
plt.title('Clases espectrales ', fontsize = 12, fontweight = 'bold')
plt.pie(stars['Spectral_Class'].value_counts(), labels=tipos, autopct="%0.1f %%")
plt.axis("equal")
plt.show()

Correlaciones entre algunas variables y tipos de estrellas

In [19]:
import seaborn as sns
plt.figure(figsize = (6,7))
plt.title('Mapa de calor de correlación\n ', fontsize = 12, fontweight = 'bold')

sns.heatmap(stars.corr(), annot=True)
plt.show()
In [20]:
stars['Star_type']
Out[20]:
0      0
1      0
2      0
3      0
4      0
      ..
235    5
236    5
237    5
238    5
239    5
Name: Star_type, Length: 240, dtype: int64
In [21]:
O = stars[stars["Spectral_Class"] == 'O']
B = stars[stars["Spectral_Class"] == 'B']
A = stars[stars["Spectral_Class"] == 'A']
F = stars[stars["Spectral_Class"] == 'F']
G = stars[stars["Spectral_Class"] == 'G']
K = stars[stars["Spectral_Class"] == 'K']
M = stars[stars["Spectral_Class"] == 'M']
plt.figure(figsize = (15,10))
plt.subplot(211)
plt.title('Tipo de estrella VS Magnitud absoluta (Mv) y Temperatura(K)\n para cada clase espectral\n ', fontsize = 12, fontweight = 'bold')
plt.xlabel('Magnitud absoluta (Mv)', fontsize=12, fontweight = 'bold')
plt.ylabel('Tipo de estrella', fontsize = 12, fontweight = 'bold')
ax7=plt.scatter( M['Absolute_magnitude(Mv)'],M['Star_type'], label="M")
ax2=plt.scatter( B['Absolute_magnitude(Mv)'],B['Star_type'], label="B")
ax1=plt.scatter( O['Absolute_magnitude(Mv)'],O['Star_type'], label="O")
ax3=plt.scatter( A['Absolute_magnitude(Mv)'],A['Star_type'], label="A")
ax4=plt.scatter( F['Absolute_magnitude(Mv)'],F['Star_type'], label="F")
ax6=plt.scatter( K['Absolute_magnitude(Mv)'],K['Star_type'], label="K")
ax5=plt.scatter( G['Absolute_magnitude(Mv)'],G['Star_type'], label="G")


plt.legend(loc = 'upper right')
plt.subplot(212)
#plt.title('Luminosidad (L/Lo) vs Mag\n', fontsize = 20, fontweight = 'bold')
plt.xlabel('Temperatura(K)', fontsize=12, fontweight = 'bold')
plt.ylabel('Tipo de estrella', fontsize = 12, fontweight = 'bold')
plt.scatter( M['Temperature(K)'],M['Star_type'], label="M")
plt.scatter( B['Temperature(K)'],B['Star_type'], label="B")
plt.scatter( O['Temperature(K)'],O['Star_type'], label="O")
plt.scatter( A['Temperature(K)'],A['Star_type'], label="A")
plt.scatter( F['Temperature(K)'],F['Star_type'], label="F")
plt.scatter( K['Temperature(K)'],K['Star_type'], label="K")
plt.scatter( G['Temperature(K)'],G['Star_type'], label="G")
plt.legend(loc = 'lower right')
plt.show()
In [22]:
plt.figure(figsize = (15,10))
plt.subplot(121)
plt.title('Radio(R/Ro) VS Magnitud absoluta(Mv)\n para cada clase espectral\n ', fontsize = 12, fontweight = 'bold')
plt.xlabel('Magnitud absoluta (Mv)', fontsize=12, fontweight = 'bold')
plt.ylabel('Radio(R/Ro)', fontsize = 12, fontweight = 'bold')
plt.yscale('log')
plt.scatter( M['Absolute_magnitude(Mv)'],M['Radius(R/Ro)'], label="M")
plt.scatter( B['Absolute_magnitude(Mv)'],B['Radius(R/Ro)'], label="B")
plt.scatter( O['Absolute_magnitude(Mv)'],O['Radius(R/Ro)'], label="O")
plt.scatter( A['Absolute_magnitude(Mv)'],A['Radius(R/Ro)'], label="A")
plt.scatter( F['Absolute_magnitude(Mv)'],F['Radius(R/Ro)'], label="F")
plt.scatter( K['Absolute_magnitude(Mv)'],K['Radius(R/Ro)'], label="K")
plt.scatter( G['Absolute_magnitude(Mv)'],G['Radius(R/Ro)'], label="G")
plt.legend(loc = 'upper right')
plt.subplot(122)
plt.title('Luminosidad(L/Lo) VS Magnitud absoluta(Mv)\n para cada clase espectral\n', fontsize = 12, fontweight = 'bold')
plt.xlabel('Magnitud absoluta (Mv)', fontsize=12, fontweight = 'bold')
plt.ylabel('Luminosidad ($L_{Sol}$)', fontsize = 12, fontweight = 'bold')
plt.yscale('log')
plt.scatter( M['Absolute_magnitude(Mv)'],M['Luminosity(L/Lo)'], label="M")
plt.scatter( B['Absolute_magnitude(Mv)'],B['Luminosity(L/Lo)'], label="B")
plt.scatter( O['Absolute_magnitude(Mv)'],O['Luminosity(L/Lo)'], label="O")
plt.scatter( A['Absolute_magnitude(Mv)'],A['Luminosity(L/Lo)'], label="A")
plt.scatter( F['Absolute_magnitude(Mv)'],F['Luminosity(L/Lo)'], label="F")
plt.scatter( K['Absolute_magnitude(Mv)'],K['Luminosity(L/Lo)'], label="K")
plt.scatter( G['Absolute_magnitude(Mv)'],G['Luminosity(L/Lo)'], label="G")
plt.legend(loc = 'upper right')
plt.show()

Algunas conclusiones:

Luego de instalar la maquina virtual de Atlas-Open-Data-ubuntu-2020-v4 y usarla a través de Oracle VM VirtualBox, fue posible estudiar estadísticamente a las estrellas y sus correspondientes radios, magnitudes absolutas, temperaturas y luminosidades usando pandas y ROOT.

Se logró evidenciar que hay igual cantidad de estrellas de cada tipo en la base de datos, mientras que la mayoría de las estrellas pertenecen a la clase espectral M. También fue posible deducir que la mayoría de estas estrellas tienen una luminosidad entre 0 L/Lo y 100000 L/Lo, un radio entre 0 R/Ro y 321.3 R/Ro. Y adicionalmente se concluye que la mitad de las estrellas tienen una temperatura entre 0 K y 5000 K.

Se logró gráficar y evidenciar las respuestas de tendencia del Diagrama Hertzsprung - Russell para diferentes tipos de estrella de distintas clases espectrales.

La base de datos en formato .root es bastante útil para un análisis estadístico rápido y sencillo, además de que con su output interactivo se logra reconocer cada región en detalle de los plots.

Manipular los datos en formato .csv también tiene sus beneficios, cómo el análisis de correlación de variables el cuál sugiere de manera rápida qué combinaciones de tendencias estudiar.

In [ ]: