2D Histogram

HR Diagram Star Distribution

Hertzsprung-Russell diagram showing stellar temperature vs luminosity distribution for stellar classification.

Output
HR Diagram Star Distribution
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap

# Stellar population
np.random.seed(42)

n_main = 4000
temp_main = np.random.uniform(3000, 30000, n_main)
lum_main = (temp_main / 5778) ** 4 * np.random.lognormal(0, 0.3, n_main)

n_giants = 800
temp_giants = np.random.uniform(3000, 5500, n_giants)
lum_giants = np.random.uniform(50, 1000, n_giants)

n_dwarfs = 600
temp_dwarfs = np.random.uniform(8000, 40000, n_dwarfs)
lum_dwarfs = np.random.uniform(0.0001, 0.05, n_dwarfs)

temp = np.concatenate([temp_main, temp_giants, temp_dwarfs])
lum = np.concatenate([lum_main, lum_giants, lum_dwarfs])

# Space dark theme
plt.style.use('dark_background')
fig, ax = plt.subplots(figsize=(10, 8))
fig.patch.set_facecolor('#02020a')
ax.set_facecolor('#02020a')

# Custom colormap - stellar
colors = ['#02020a', '#0a0a20', '#1a1a40', '#2a2a60', '#3a4a80', 
          '#4a6aa0', '#5a8ac0', '#7abae0', '#9aeaff', '#c0f8ff', '#ffffff']
cmap = LinearSegmentedColormap.from_list('stellar', colors, N=256)

# 2D histogram
h = ax.hist2d(temp, np.log10(lum + 0.0001), bins=60, cmap=cmap, cmin=1)

# Spectral classes
spectral = {'O': 35000, 'B': 20000, 'A': 8500, 'F': 6500, 'G': 5500, 'K': 4500, 'M': 3200}
for label, t in spectral.items():
    ax.axvline(x=t, color='#3a4a80', linestyle=':', alpha=0.3, linewidth=0.8)
    ax.text(t, 4.8, label, color='#7abae0', fontsize=10, ha='center', alpha=0.9)

# Region labels
ax.text(4000, 2.5, 'Red Giants', fontsize=11, color='#ffa500', alpha=0.9, fontweight='500')
ax.text(15000, 0.5, 'Main Sequence', fontsize=11, color='#9aeaff', alpha=0.9, rotation=-45)
ax.text(25000, -2.5, 'White Dwarfs', fontsize=11, color='#ffffff', alpha=0.9)

# Styled colorbar
cbar = plt.colorbar(h[3], ax=ax, pad=0.02, shrink=0.85)
cbar.ax.set_facecolor('#02020a')
cbar.set_label('Star Count', fontsize=11, color='#a0d0e8', labelpad=10)
cbar.ax.yaxis.set_tick_params(color='#a0d0e8')
cbar.outline.set_edgecolor('#2a3a50')
plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='#a0d0e8', fontsize=9)

ax.set_xlabel('Temperature (K)', fontsize=13, color='#a0d0e8', fontweight='600', labelpad=10)
ax.set_ylabel('log10(L / L_sun)', fontsize=13, color='#a0d0e8', fontweight='600', labelpad=10)
ax.set_title('Hertzsprung-Russell Diagram', fontsize=16, color='white', fontweight='bold', pad=20)

ax.tick_params(colors='#80b0c8', labelsize=10, length=0)
for spine in ax.spines.values():
    spine.set_visible(False)

ax.invert_xaxis()
plt.tight_layout()
plt.show()
Library

Matplotlib

Category

Statistical

Did this help you?

Support PyLucid to keep it free & growing

Support