Estudiante: Angie Nicole Hernández Durán
Investigue sobre el diagrama de Hertzprung-Russell, una herramienta muy potente en astronomia, y describa un poco al respecto para darle contexto al resto de la tarea
Este diagrama es un diagrama del tipo 'scatter' que muestra la relaión entre la magnitud de la luminosidad absoluta de una estrella y sus temperatura. Fue creado en 1910 por Ejnar Hertzsprung y Henry Norris Russell.
El objetivo es generar un diagrama HR lo más parecido al de esta referencia. No lucirá idéntico por que no se usarán exactamente los mismos datos, y las unidades pueden ser ligeramente distinta. La idea sí es dejar su figura lo más parecida a la de referencia en el estilo: colores, escalas en los ejes, tamaño de los marcadores, leyendas, textos en el gráfico, etc.
Los datos para crear la figura están en la carpeta Data
. Cada tabla contiene las informaciones sobre un tipo de estrellas según indican los nombres de archivo. La información viene en 3 columnas: luminosidad en luminosidades
solares, Temperatura en Kelvin y Radio de la estrella en unidades arbitrarias.
La idea es que cada estrella en el gráfico tenga un color representativo de su temperatura (que estrellas frías son rojas y estrellas calientes son azules) y que el tamaño del símbolo sea representativo del tamaño de cada estrella para diferenciar entre enanas, gigantes y estrellas de secuencia principal.
Busque que su código sea semi automático; es indispensable leer los datos desde el propio programa, no copiarlos a mano, y hallar una forma de obtener los tamaños y colores sin declararlos uno a uno
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
Primero importo los datos
dwarfs = pd.read_csv("data/dwarfs.csv")
main_sequence = pd.read_csv("data/ms.csv")
giants = pd.read_csv("data/giants.txt", sep = " ")
super_giants = pd.read_csv("data/supergiants.txt", sep = " ")
Ahora si procedo a armar un gráfico lo más similar posible al dado.
#Primero debo hacer el bastidor donde irá mi figura, de una vez le doy el tamaño
fig = plt.figure(figsize = (15,9))
#Hago un subplot, 111 lo deja ocupando todo el anterior bastidor, esto me facilita poner los ejes en las escalas
#correspondientes y hacer otros ajustes que encontré por el camino
ax1 = fig.add_subplot(111)
#Pongo los ejes en escalas logarítmicas
ax1.set_xscale('log')
ax1.set_yscale('log')
#ax1.set_xticks((2500, 5000, 10000, 20000))
#Estos min y max se definen para dar valores límite al colormap que será usado eventualmente, se vé más similar de
#esta manera
min_, max_ = main_sequence['temp'].min(), main_sequence['temp'].max()
#Comienzo a poner los datos en el mismo subplot
#En el argumento de cada plt.scatter van varias cosas, los ejes X,Y corresponden a las columnas de 'temp','lum'
#en cada dataframe.
#El radio de cada punto corresponde a la columna 'radius', sin embargo este es escalado para dar una
#representación visual más diciente, las super giants, por ejemplo, se establecieron 3 veces más grandes
#que las dwarfs y las de main sequence.
#Todas las que no son dwarfs se representan usando un gradiente de color que es azul a más altas temperaturas,
#y rojo a más bajas, este está en "cmap = RdYlBu". Alpha indica la transparencia del color.
#El borde de las dwarfs debe ser negro porque su interior es blanco, no se vería
plt.scatter(dwarfs['temp'], dwarfs['lum'], s=10 * dwarfs['radius'], marker='o', c='w', edgecolors='k', alpha=0.5)
plt.clim(min_,max_) #Esto es para definir dónde irán los límites del colormap
plt.scatter(main_sequence['temp'], main_sequence['lum'], s=10 * main_sequence['radius'], c=main_sequence['temp'], cmap = 'RdYlBu', edgecolors='k',alpha=0.9)
plt.clim(min_,max_)
plt.scatter(giants['temp'], giants['lum'], s=15 * giants['radius'], c=giants['temp'], cmap = 'RdYlBu', edgecolors='k',alpha=0.9)
plt.clim(min_,max_)
plt.scatter(super_giants['temp'], super_giants['lum'], s=30 * super_giants['radius'], c=super_giants['temp'], cmap = 'RdYlBu', edgecolors='k',alpha=0.9)
plt.clim(min_,max_)
#Invierto eje x
plt.gca().invert_xaxis()
#Pongo nombres a los ejes, en tamaño grande y negrilla
plt.xlabel('Temperature (K)', fontsize='large', fontweight='bold')
plt.ylabel('Luminosity (L)', fontsize='large', fontweight='bold')
#Agrego los nombres de los grupos de estrellas
ax1.text(5000, 20000, 'Red supergiants', style='italic', fontsize='large', fontweight='bold')
ax1.text(11000, 100000, 'Blue giants', style='italic', fontsize='large', fontweight='bold')
ax1.text(4500, 200, 'Red giants', style='italic', fontsize='large', fontweight='bold')
ax1.text(8000, 1, 'Main sequence', style='italic', fontsize='large', fontweight='bold')
ax1.text(8000, 0.001, 'White dwarfs', style='italic', fontsize='large', fontweight='bold')
#Elimino las lineas de la derecha y arriba del recuadro que rodea la figura
right_side = ax1.spines["right"]
right_side.set_visible(False)
top_part = ax1.spines["top"]
top_part.set_visible(False)
#Tengo que alargar un poco el eje Y hacia arriba porque mis Red Supergiants uedaban cortadas por el borde superior
#del gráfico
ax1.set_ylim([None, 10000000])
#Quito los ticks automáticos, si no los quito primero y solo pongo los que quiero, me quedan sobrepuestos con estos
ax1.set_xticks([], minor=True)
#Pongo algunos de los X ticks que aparecen en la figura que estamos imitando
ax1.set_xticks((5000, 10000))
#Para que no salga en eje X en notación científica
ax1.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())