This interactive figure lets you investigate how the temperature and radius of a star affect the amount of energy it puts out every second, which is the star's luminosity.
Luminosity has metric units of Watts (e.g. a 100 Watt light bulb is converting electrical energy into light and heat at a rate of 100 Watts). However, since stars are very luminous (at least compared to most things on a "human" scale, in astronomy typically use units of solar luminosity, $L_\odot$, where the Sun's luminosity is $1 L_\odot = 3.83\times10^{26}$ Watts!
The figure below shows a model star. Use the sliders to change the radius and the temperature of the star. Using our Sun as a baseline, the sliders take the radius in Solar Radii and the temperature in Solar Temperatures. The luminosity is reported in the lower right in both Watts and Solar Luminosities and the temperature is translated to units of Kelvin (for a baseline, room temperature is approximately 295 K).
Use this interactive to explore the following questions:
# Author: Andrew Louwagie Gordon
# Date Created: 22May2018
# Last Modified: 22Jun2018 (tweaked by Juan Cabanela)
# Import Block
# Import the necessary packages
from IPython.display import display
import numpy as np
import ipywidgets as widgets
import bqplot as bq
import pythreejs as p3j
import tempNcolor as tc
import number_formatting as nf
import starlib as star
# Function Definitions Block
def Star_Temp(T):
'''
This function calculates the temperature of the star in Kelvin.
'''
global T_Sun
temp = T * T_Sun
temp = round(temp, -2) # Round the temperature to the nearest 100 K
return int(temp)
def L_Ratio(t, r):
'''
This function calculates the ratio of luminosities for the star based on temperature and radius.
'''
lum = (r ** 2.0) * (t ** 4.0) # Luminosity calculation in L/L_sun
return nf.SigFig(lum, 2)
def UpdateWidgets(change=None):
'''
This function continuously updates the widgets that display information.
'''
# Get the luminosity ratio for this star and display it
get_l_ratio = L_Ratio(Temp.value, Rad.value)
L_Ratio_report.value = str(get_l_ratio)
# Compute the luminosity in Watts and display it.
Luminosity = float(get_l_ratio) * L_Sun
latex = nf.exp2LaTeX(Luminosity,3)
Luminosity_report.value = '{}'.format(latex[2])
# Set the temperature of this star and display it
t_star = Star_Temp(Temp.value)
t_star_report.value = str(t_star)
def UpdateStar(change=None):
'''
This function continuously updates the color and radius (really scale) of the star.
'''
global init_r, star_sphere
# Get temperature in K and assign associated hexcolor
t_star = Star_Temp(Temp.value)
hex_color = tc.rgb2hex(tc.temp2rgb(t_star))
# Set the color of the star image
star.StarMeshColor(star_sphere, hex_color[0])
# Set the scale of the star image
scale_dim = Rad.value/init_r
star_sphere.scale = (scale_dim, scale_dim, scale_dim)
# Define constants
L_Sun = star.L_Sun # Solar luminosity in Watts
T_Sun = star.Te_Sun # Solar temperature in Kelvin
t_star = T_Sun # Define variable to be updated later
Luminosity = 1 # Define variable to be updated later
get_l_ratio = 1 # Define variable to be updated later
# Make a list from the number2LaTeX converter being used
latex = nf.exp2LaTeX(Luminosity)
# Define initial conditions to be Sun-like
init_temp = 1
init_rad = 1
# Widgets Definitions Block
# Radius slider in units of R/R_Sun
Rad = widgets.FloatSlider(
min=0.2,
value=1.0,
max=15,
step=0.1,
disabled=False,
continuous_update=True,
orientation='horizontal',
readout=True,
readout_format='.1f',
layout=widgets.Layout(border='none', width='200px')
)
# Temperature slider in units of T/T_Sun
Temp = widgets.FloatSlider(
min=0.5,
value=1.0,
max=7.0,
step=0.1,
disabled=False,
continuous_update=True,
orientation='horizontal',
readout=True,
readout_format='.1f',
layout=widgets.Layout(border='none', width='200px')
)
# Widget to report updated temperature in Kelvin
t_star_report = widgets.Text(
value = str(int(t_star)),
readout_format='.0f',
placeholder = 'Type something',
disabled = True
)
# Widget to report updated luminosity in L/L_sun
L_Ratio_report = widgets.Text(
value = str(get_l_ratio),
placeholder = 'Type something',
disabled = True
)
# Widget to report updated luminosity in Watts
Luminosity_report = widgets.HTML(
value = '{}'.format(latex[2]),
placeholder = 'Type something',
disabled = True
)
# Reset to initial values
Temp.value = init_temp
Rad.value = init_rad
# Set viewer size
view_width = 300
view_height = 300
# Get the initial temperature for the star
t_star = Star_Temp(Temp.value)
t_star_report.value = str(t_star)
# Compute the luminosity in Watts and display it.
latex = nf.exp2LaTeX(float(get_l_ratio) * L_Sun,3)
Luminosity_report.value = '{}'.format(latex[2])
# Set scale factor for radius (approximately 10 pixels per solar radius)
scale_factor = 1
# Set initial parameters based on stellar parameters
r1 = scale_factor*Rad.value
# Save initial radius to scale all other radii to this
init_r = r1
# set the scale
scale1 = (r1/init_r, r1/init_r, r1/init_r)
# Create a stellar image sphere (including a copy that represents the Sun, since it will use initial values)
star_sphere = star.StarMesh(t_star, r1, scale1, [0, 0, 0])
sun_sphere = star.StarMesh(t_star, r1, scale1, [0, 18, 0])
# Makes the scene environment, not sure how the background works yet
scene2 = p3j.Scene(children=[star_sphere, sun_sphere], background='black')
# Creates the camera so you can see stuff. Place the cemera just above the x-axis and orient camera so up
# is along y-axis.
starcam = p3j.PerspectiveCamera(position=[45, 0, 0], up=[0, 0, 1])
# Makes a controller to use for the
controller = p3j.OrbitControls(controlling=starcam, enableRotate=False, enableZoom=False)
# creates the object that gets displayed to the screen
renderer2 = p3j.Renderer(camera=starcam,
scene=scene2,
controls=[controller],
width=view_width, height=view_height)
# Use the UpdateStar function to continuously update the star in the plot
Temp.observe(UpdateStar, names=['value'])
Rad.observe(UpdateStar, names=['value'])
# Use the UpdateWidgets function to continuously update the calculated values in the display widgets on the bottom
Temp.observe(UpdateWidgets, names=['value'])
Rad.observe(UpdateWidgets, names=['value'])
# Define the layout for the final widget to make it presentable
box_layout = widgets.Layout(align_items='center', justify_content = 'flex-end', border='none', width='800px')
# Arrange and display all the widgets in a presentable manner
top_box = widgets.VBox([widgets.HTML ("<h2>Model Star</h2>"), renderer2,
widgets.HTML ("<p>Model Star in center, Sun shown to right for comparison.</p>")],
layout = box_layout)
Rad_label = widgets.HTML('Radius (R<sub>☉</sub>):',
layout=widgets.Layout(align = 'right', width='150px'))
rad_slide = widgets.HBox([Rad_label, Rad],
layout=widgets.Layout(border='none', width='350px'))
Temp_Label = widgets.HTML('Temperature (T<sub>☉</sub>):',
layout=widgets.Layout(align = 'right', width='150px'))
temp_slide = widgets.HBox([Temp_Label, Temp],
layout=widgets.Layout(border='none', width='350px'))
temp_disp = widgets.HBox([widgets.Label('Temperature (K):'), t_star_report],
layout=widgets.Layout(border='none'))
temp_disp.children[0].layout.width = '150px'
temp_disp.children[1].layout.width = '100px'
lratio_disp = widgets.HBox([widgets.HTML('Luminosity (L<sub>☉</sub>):'), L_Ratio_report],
layout=widgets.Layout(border='none'))
lratio_disp.children[0].layout.width = '150px'
lratio_disp.children[1].layout.width = '100px'
lum_disp = widgets.HBox([widgets.Label('Luminosity (W):'), Luminosity_report],
layout=widgets.Layout(border='none'))
lum_disp.children[0].layout.width = '150px'
lum_disp.children[1].layout.width = '100px'
bottom_left = widgets.VBox([temp_slide, rad_slide])
bottom_right = widgets.VBox([temp_disp, lratio_disp, lum_disp])
bottom = widgets.HBox([bottom_left, bottom_right])
the_box = widgets.VBox([top_box, bottom], layout = box_layout)
display(the_box)