Siria Sadeddin
One of the most useful and powerful plots in astrophysics is the Hertzsprung-Russell diagram. It originated in 1911 when the Danish astronomer, Ejnar Hertzsprung, plotted the absolute magnitude of stars against their colour. Independently in 1913 the American astronomer Henry Norris Russell used spectral class against absolute magnitude. Their resultant plots showed that the relationship between temperature and luminosity of a star was not random but instead appeared to fall into distinct groups.[1] We will reproduce this diagram using the data provided in this course, this data consist in "txt" and "csv" files that contain information for each of the star classes:
Each of these files have the following information:
[1] https://www.atnf.csiro.au/outreach/education/senior/astrophysics/stellarevolution_hrintro.html
Our strategy will be reading this files and join them, so we will have a unique dataframe of data for the stars. We will use pandas python library for this task.
#import pandas and numpy
import pandas as pd
import numpy as np
# define data directory
dir="./data"
# read files
dwarfs=pd.read_csv(dir+"/dwarfs.csv")
giants=pd.read_csv(dir+"/giants.txt", sep=" ")
ms=pd.read_csv(dir+"/ms.csv")
supergiants=pd.read_csv(dir+"/supergiants.txt", sep=" ")
# create new column "type" for identifying the star class in dataframe
dwarfs['type']='dwarfs'
giants['type']='giants'
ms['type']='ms'
supergiants['type']='supergiants'
# join datasets
df=pd.concat([dwarfs,giants,ms,supergiants],ignore_index=True)
#create new star class "blue giant" for the hottest supergiant available in data
df.loc[(df.temp==np.max(df[(df.type=='supergiants')].temp)) & (df.type=='supergiants'),'type']='blue giant'
#take the log base 10 of the luminosity, radius and temperature. This will help on distinguish between data points, since some of them are
# orders of magnitude appart
df['log_lum']=np.log10(df.lum)
df['log_radius']=np.log10(df.radius)
df['log_temp']=np.log10(df.temp)
# sort values by temperature and reset row index numbers
df=df.sort_values('temp')
df = df.reset_index(drop=True)
df.head()
We will use seaborn and matplotlib python libraries to make a visualization of the diagram. Seaborn helps on setting the point sizes and color easily. For the cluster names labeling (star clases), we will take the mean of the temperature and log10(luminosity), this gives the cluster centroid positions for each star class.
#libaries import
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
#cluster means
means=df.groupby('type').mean()
means
# plot canvas
fig = plt.figure(figsize=(10,10))
plt.xlim(14000, 3000)
plt.title("Hertzsprung-Russell Diagram", fontsize=20)
plt.xlabel('temp K',fontsize=20)
plt.ylabel('log_lum',fontsize=20)
sns.set_style("dark")
# plot data points
sns.scatterplot(data=df,
x='temp',
y='log_lum',
hue=df.temp,
size=df.radius,
sizes=(100, 1000),
palette="Spectral",
legend=False)
#plot cluster labels for each star class
plt.text(means.loc['dwarfs','temp'], means.loc['dwarfs','log_lum'], 'DWARFS', style='normal',color='red', fontsize=16,horizontalalignment='center',fontweight='bold')
plt.text(means.loc['giants','temp'], means.loc['giants','log_lum'], 'GIANTS', style='normal',color='red', fontsize=16,horizontalalignment='right',verticalalignment='bottom',fontweight='bold')
plt.text(means.loc['ms','temp'], means.loc['ms','log_lum'], 'MAIN SEQUENCE', style='normal',color='orange', fontsize=16,horizontalalignment='right',verticalalignment='top',rotation=-25,fontweight='bold')
plt.text(means.loc['supergiants','temp'], means.loc['supergiants','log_lum'], 'SUPERGIANTS', style='normal',color='red', fontsize=16,horizontalalignment='center',verticalalignment='top',fontweight='bold')
plt.text(means.loc['blue giant','temp'], means.loc['blue giant','log_lum'], 'BLUE GIANTS', style='normal',color='blue', fontsize=16,horizontalalignment='center',verticalalignment='top',fontweight='bold')
#show plot
plt.show()
# plot canvas
fig = plt.figure(figsize=(10,10))
#plt.xlim(14000, 3000)
plt.title("Radius vs luminosity", fontsize=20)
plt.xlabel('log_radius',fontsize=20)
plt.ylabel('log_lum',fontsize=20)
sns.set_style("dark")
# plot data points
sns.scatterplot(data=df,
x='log_radius',
y='log_lum',
legend=False,
hue=df.log_temp,
size=df.log_radius,
palette="Spectral",
sizes=(1, 1000)
)
#plot cluster labels for each star class
plt.text(means.loc['dwarfs','log_radius'], means.loc['dwarfs','log_lum'], 'DWARFS', style='normal',color='red', fontsize=16,horizontalalignment='center',fontweight='bold')
plt.text(means.loc['giants','log_radius'], means.loc['giants','log_lum'], 'GIANTS', style='normal',color='red', fontsize=16,horizontalalignment='right',verticalalignment='bottom',fontweight='bold')
plt.text(means.loc['ms','log_radius'], means.loc['ms','log_lum'], 'MAIN SEQUENCE', style='normal',color='orange', fontsize=16,horizontalalignment='right',verticalalignment='top',rotation=-25,fontweight='bold')
plt.text(means.loc['supergiants','log_radius'], means.loc['supergiants','log_lum'], 'SUPERGIANTS', style='normal',color='red', fontsize=16,horizontalalignment='center',verticalalignment='top',fontweight='bold')
plt.text(means.loc['blue giant','log_radius'], means.loc['blue giant','log_lum'], 'BLUE GIANTS', style='normal',color='blue', fontsize=16,horizontalalignment='center',verticalalignment='top',fontweight='bold')
#show plot
plt.show()
The plot shows the well known form of the Hertzsprung-Russell diagram, on the center, we can observe the main sequence, which contains the regular stars. The main sequence has a linear like behavior (lum-temp plot), we can also see some outlier clusters that contains the rare stars as dwarfs, giants, supergiants and blue giants. The dwarfs for example, have low luminosity for their temperature, giants, supergiants and blue giants have high luminosity for their related temperature. The plot point sizes are related to the star radius and the point colors with their temperature (blue hotter and red colder). We have also made a luminosity-radius plot, wich shows that the radius of the star does not explain the oulier behavior of those stars, instead of that, we see again the clusters for the dwarfs, giants, supergiants and blue giants
We will use the previous plot to make an animated plot. The matplotlib.animation sublibrary will be used for this task.
# import library
from matplotlib.animation import FuncAnimation
# define animation iteration function
# set canvas configuration
fig, ax = plt.subplots(figsize=(10,10))
ax.set(xlim=(14000, 3000),ylim=(-5, 7))
plt.title("Hertzsprung-Russell Diagram", fontsize=20)
plt.xlabel('temp K',fontsize=20)
plt.ylabel('log_lum',fontsize=20)
sns.set_style("dark")
def animate(i):
#data slice
dfi=df.loc[0:i,:]
#make plot
sns.scatterplot(data=dfi,x='temp',y='log_lum',hue=df.temp,size=df.radius,sizes=(100, 1000),palette="Spectral",legend=False)
#print cluster labels
if any(dfi.type=="dwarfs"):
plt.text(means.loc['dwarfs','temp'], means.loc['dwarfs','log_lum'], 'DWARFS', style='normal',color='red', fontsize=16,horizontalalignment='center',fontweight='bold')
if any(dfi.type=="giants"):
plt.text(means.loc['giants','temp'], means.loc['giants','log_lum'], 'GIANTS', style='normal',color='red', fontsize=16,horizontalalignment='right',verticalalignment='bottom',fontweight='bold')
if any(dfi.type=="ms"):
plt.text(means.loc['ms','temp'], means.loc['ms','log_lum'], 'MAIN SEQUENCE', style='normal',color='orange', fontsize=16,horizontalalignment='right',verticalalignment='top',rotation=-25,fontweight='bold')
if any(dfi.type=="supergiants"):
plt.text(means.loc['supergiants','temp'], means.loc['supergiants','log_lum'], 'SUPERGIANTS', style='normal',color='red', fontsize=16,horizontalalignment='center',verticalalignment='top',fontweight='bold')
if any(dfi.type=="blue giant"):
plt.text(means.loc['blue giant','temp'], means.loc['blue giant','log_lum'], 'BLUE GIANTS', style='normal',color='blue', fontsize=16,horizontalalignment='center',verticalalignment='top',fontweight='bold')
#make animation
anim = FuncAnimation(fig, animate, interval=100, frames=len(df)-1)
#save animation
anim.save('Hertzsprung-Russell-Diagram.gif')
We have shown the characteristics of the Hertzsprung-Russell Diagram and used the available data to reproduce it satifactorily, we have made data manipulation with pandas library, data plotting and animation with matplotlib library. The Hertzsprung-Russell Diagram shows the behavior of star's luminosity related to their temperature, which is, normaly almost linear. In contrast, we find groups of stars which show an outlier behavior, and as out luminosity-radius plot showed, can not be explained by the star size.