2026-10-22 17:20:44 +05:30
"""
app.py
2026-10-27 10:23:02 +05:30
HIFFI Artist Intelligence - Multi-Platform Executive Dashboard
2026-10-31 14:43:43 +05:30
Dual-Engine Architecture:
1. HIFFI Hip-Hop 500: Multi-platform evidence tiers, YouTube/Spotify/IG telemetry, BVI, CPI engine.
2. Global Master Catalog (17k): Empirical registry verification (CSPC, RIAA, Last.fm) with ordinal tier ranking.
2026-10-22 17:20:44 +05:30
"""
2026-10-27 10:23:02 +05:30
from pathlib import Path
2026-11-04 16:49:39 +05:30
import sqlite3
2026-10-22 17:20:44 +05:30
import pandas as pd
import plotly.express as px
2026-10-28 17:07:19 +05:30
import plotly.graph_objects as go
2026-10-22 17:20:44 +05:30
import streamlit as st
2026-10-31 14:43:43 +05:30
try :
from core.cpi_engine import CommercialPowerEngine
except ImportError :
CommercialPowerEngine = None
try :
from exporters.excel_workbook import generate_executive_sales_workbook
except ImportError :
generate_executive_sales_workbook = None
2026-10-30 11:10:54 +05:30
2026-11-04 16:49:39 +05:30
try :
from core.ranking_engine import HIFFIRankingEngine
except ImportError :
HIFFIRankingEngine = None
2026-10-22 17:20:44 +05:30
st . set_page_config (
2026-10-27 10:23:02 +05:30
page_title = "HIFFI | Multi-Platform Intelligence" ,
2026-10-22 17:20:44 +05:30
page_icon = "⚡" ,
layout = "wide" ,
initial_sidebar_state = "expanded" ,
)
2026-11-04 16:49:39 +05:30
PATH_DB = Path ( "data/hiffi_catalog.db" )
2026-10-31 14:43:43 +05:30
PATH_500 = Path ( "data/hiffi_multiplatform_500.csv" )
PATH_17K = Path ( "data/master_artists_intelligence_17k_final.csv" )
FALLBACK_PATH = Path ( "enriched_artists.csv" )
2026-10-22 17:20:44 +05:30
2026-10-30 11:10:54 +05:30
# Global CSS Styling
2026-10-22 17:20:44 +05:30
st . markdown (
"""
<style>
.block-container {
padding-top: 1.8rem;
padding-bottom: 2.5rem;
padding-left: 2.5rem;
padding-right: 2.5rem;
max-width: 100% !important;
}
.kpi-box {
background: #111827;
border: 1px solid #1f2937;
border-radius: 12px;
padding: 16px 20px;
margin-bottom: 12px;
}
.kpi-title {
2026-11-04 16:49:39 +05:30
font-size: 0.72rem;
2026-10-22 17:20:44 +05:30
font-weight: 700;
color: #9ca3af;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.kpi-value {
2026-11-04 16:49:39 +05:30
font-size: 1.85rem;
2026-10-22 17:20:44 +05:30
font-weight: 800;
color: #f9fafb;
margin: 4px 0;
}
.kpi-subtitle {
2026-11-04 16:49:39 +05:30
font-size: 0.72rem;
2026-10-22 17:20:44 +05:30
color: #6b7280;
}
2026-10-30 11:10:54 +05:30
.coverage-card {
background: #0f172a;
border: 1px solid #1e293b;
border-radius: 8px;
padding: 12px 18px;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.sim-kpi-card {
background: #0f172a;
border: 1px solid #334155;
border-radius: 8px;
padding: 10px 14px;
margin-bottom: 10px;
}
.sim-kpi-title {
font-size: 0.68rem;
font-weight: 700;
color: #94a3b8;
text-transform: uppercase;
}
.sim-kpi-val {
font-size: 1.25rem;
font-weight: 800;
margin-top: 2px;
}
2026-10-22 17:20:44 +05:30
.podium-tile {
background: #111827;
border-radius: 12px;
padding: 18px 20px;
border: 1px solid #1f2937;
height: 100%;
}
.podium-gold { border-top: 4px solid #f59e0b; }
.podium-silver { border-top: 4px solid #94a3b8; }
.podium-bronze { border-top: 4px solid #f97316; }
.badge {
display: inline-block;
padding: 3px 8px;
border-radius: 6px;
font-size: 0.70rem;
font-weight: 700;
text-transform: uppercase;
}
2026-10-27 10:23:02 +05:30
.badge-tier3 { background: rgba(16, 185, 129, 0.2); color: #10b981; }
.badge-tier2 { background: rgba(56, 189, 248, 0.2); color: #38bdf8; }
.badge-tier1 { background: rgba(245, 158, 11, 0.2); color: #f59e0b; }
.badge-dormant { background: rgba(239, 68, 68, 0.2); color: #ef4444; }
2026-10-22 17:20:44 +05:30
.custom-divider {
height: 1px;
background: #1f2937;
margin: 24px 0;
}
</style>
""" ,
unsafe_allow_html = True ,
)
@st.cache_data ( ttl = 60 )
2026-10-31 14:43:43 +05:30
def load_hiffi_500 ():
2026-11-04 16:49:39 +05:30
df = pd . DataFrame ()
if PATH_DB . exists ():
try :
conn = sqlite3 . connect ( PATH_DB )
query = """
WITH latest_telemetry AS (
SELECT t.*, ROW_NUMBER() OVER (
PARTITION BY t.artist_id
ORDER BY t.last_synced_at DESC, t.telemetry_id DESC
) as rn
FROM telemetry_metrics t
),
latest_rankings AS (
SELECT r.*, ROW_NUMBER() OVER (
PARTITION BY r.artist_id
ORDER BY r.ranking_id DESC
) as rn
FROM rankings r
),
latest_commercial AS (
SELECT c.*, ROW_NUMBER() OVER (
PARTITION BY c.artist_id
ORDER BY c.commercial_id DESC
) as rn
FROM commercial_sales c
)
SELECT
a.artist_id,
a.artist_name as name,
a.image_verified_flag,
r.catalog_rank as hiffi_xp_published_rank,
r.tier_rank,
r.catalog_intelligence_tier,
t.subscribers_count as subscriber_count,
t.total_views as lifetime_views,
t.spotify_monthly_listeners,
t.instagram_followers,
t.daily_view_velocity,
t.growth_velocity_7d as momentum_7d,
t.growth_velocity_30d as momentum_30d,
t.spotify_daily_change,
t.momentum_score,
c.pure_album_sales,
c.physical_singles_sales,
c.digital_singles_sales,
c.streaming_eas,
c.total_eas_cspc,
c.sales_data_status
FROM artists a
LEFT JOIN latest_telemetry t ON a.artist_id = t.artist_id AND t.rn = 1
LEFT JOIN latest_rankings r ON a.artist_id = r.artist_id AND r.rn = 1
LEFT JOIN latest_commercial c ON a.artist_id = c.artist_id AND c.rn = 1
WHERE a.image_verified_flag = 1
"""
df = pd . read_sql_query ( query , conn )
conn . close ()
except Exception :
df = pd . DataFrame ()
if df . empty :
target = PATH_500 if PATH_500 . exists () else FALLBACK_PATH
if target . exists ():
df = pd . read_csv ( target )
if df . empty :
2026-10-22 17:20:44 +05:30
return pd . DataFrame ()
2026-10-27 10:23:02 +05:30
2026-10-31 14:43:43 +05:30
if "name" not in df . columns and "artist_name" in df . columns :
df [ "name" ] = df [ "artist_name" ]
2026-11-04 16:49:39 +05:30
if "subscriber_count" not in df . columns and "subscribers_count" in df . columns :
df [ "subscriber_count" ] = df [ "subscribers_count" ]
if "lifetime_views" not in df . columns and "total_views" in df . columns :
df [ "lifetime_views" ] = df [ "total_views" ]
2026-10-27 10:23:02 +05:30
if "hiffi_xp_published_rank" not in df . columns :
2026-11-04 16:49:39 +05:30
df [ "hiffi_xp_published_rank" ] = df . get ( "catalog_rank" , df . get ( "hiffi_xp_rank" , df . get ( "hiffi_rank" , df . index + 1 )))
has_yt = df . get ( "subscriber_count" , pd . Series ( index = df . index )) . fillna ( 0 ) . gt ( 0 ) . astype ( int )
has_sp = df . get ( "spotify_monthly_listeners" , pd . Series ( index = df . index )) . fillna ( 0 ) . gt ( 0 ) . astype ( int )
has_ig = df . get ( "instagram_followers" , pd . Series ( index = df . index )) . fillna ( 0 ) . gt ( 0 ) . astype ( int )
df [ "platform_evidence_tier" ] = has_yt + has_sp + has_ig
2026-10-27 10:23:02 +05:30
2026-10-22 17:20:44 +05:30
numeric_cols = [
2026-10-31 14:43:43 +05:30
"hiffi_xp_published_rank" , "hiffi_xp_rank" , "hiffi_xp_score" , "production_hiffi_rank" ,
"production_hiffi_score" , "platform_evidence_tier" , "breakout_velocity_index" ,
"subscriber_count" , "daily_view_velocity" , "momentum_30d" , "spotify_monthly_listeners" ,
"spotify_daily_change" , "instagram_followers" , "confidence_score" , "breakout_rank" ,
"chartmasters_sales_rank" , "cohort_sales_rank" , "pure_album_sales" ,
"physical_singles_sales" , "digital_singles_sales" , "streaming_eas" , "total_eas_cspc" ,
"riaa_certified_album_units" , "riaa_certified_singles_units"
2026-10-22 17:20:44 +05:30
]
for col in numeric_cols :
if col in df . columns :
df [ col ] = pd . to_numeric ( df [ col ], errors = "coerce" )
2026-10-23 10:52:54 +05:30
2026-11-04 16:49:39 +05:30
# Dynamic BVI computation
if HIFFIRankingEngine is not None and ( "breakout_velocity_index" not in df . columns or df [ "breakout_velocity_index" ] . isna () . all ()):
try :
eng_rank = HIFFIRankingEngine ()
temp_df = df . copy ()
if "status_flag" not in temp_df . columns :
temp_df [ "status_flag" ] = "COMPLETE"
df [ "breakout_velocity_index" ] = eng_rank . calculate_breakout_velocity ( temp_df )
except Exception :
df [ "breakout_velocity_index" ] = 0.0
if "breakout_velocity_index" not in df . columns :
df [ "breakout_velocity_index" ] = 0.0
# Calculate HIFFI-XP composite if not present
if "hiffi_xp_score" not in df . columns or df [ "hiffi_xp_score" ] . isna () . all ():
if HIFFIRankingEngine is not None :
try :
eng_rank = HIFFIRankingEngine ()
temp_df = df . copy ()
if "status_flag" not in temp_df . columns :
temp_df [ "status_flag" ] = "COMPLETE"
temp_df = eng_rank . score_and_rank ( temp_df )
temp_df = eng_rank . calculate_hiffi_xp ( temp_df )
df [ "hiffi_xp_score" ] = temp_df [ "hiffi_xp_score" ]
df [ "effective_weights" ] = temp_df . get ( "effective_weights" , "yt:50.0%,sp_monthly:25.0%,sp_velocity:5.0%,ig:20.0%" )
if "production_hiffi_score" not in df . columns :
df [ "production_hiffi_score" ] = temp_df . get ( "production_hiffi_score" , 0.0 )
except Exception :
df [ "hiffi_xp_score" ] = 50.0
else :
df [ "hiffi_xp_score" ] = 50.0
if "effective_weights" not in df . columns :
df [ "effective_weights" ] = "yt:50.0%,sp_monthly:25.0%,sp_velocity:5.0%,ig:20.0%"
if "anomaly_flags" not in df . columns :
df [ "anomaly_flags" ] = "CLEAN"
2026-10-31 14:43:43 +05:30
if CommercialPowerEngine is not None :
try :
2026-11-04 16:49:39 +05:30
cpi_eng = CommercialPowerEngine ()
df [ "commercial_power_index" ] = cpi_eng . calculate_cpi ( df )
2026-10-31 14:43:43 +05:30
except Exception :
df [ "commercial_power_index" ] = None
2026-10-30 11:10:54 +05:30
2026-10-23 10:52:54 +05:30
if "subgenre" not in df . columns :
def infer_subgenre ( r ):
subs = r . get ( "subscriber_count" , 0 ) or 0
bvi = r . get ( "breakout_velocity_index" , 0 ) or 0
if bvi >= 70 :
return "Breakout / Emerging"
elif subs >= 15000000 :
return "Legends"
else :
return "Trap & Street"
df [ "subgenre" ] = df . apply ( infer_subgenre , axis = 1 )
2026-10-22 17:20:44 +05:30
return df
2026-10-31 14:43:43 +05:30
@st.cache_data ( ttl = 60 )
def load_master_17k ():
if not PATH_17K . exists ():
return pd . DataFrame ()
df = pd . read_csv ( PATH_17K )
if "name" not in df . columns and "artist_name" in df . columns :
df [ "name" ] = df [ "artist_name" ]
return df
df_500 = load_hiffi_500 ()
df_17k = load_master_17k ()
engine = CommercialPowerEngine () if CommercialPowerEngine is not None else None
2026-10-30 11:10:54 +05:30
def get_provenance_badge ( status : str ) -> str :
s = str ( status ) . strip ()
2026-10-31 14:43:43 +05:30
if "CSPC" in s or s == "VERIFIED_CSPC" :
2026-10-30 11:10:54 +05:30
return "✅ VERIFIED (CSPC)"
2026-10-31 14:43:43 +05:30
elif "RIAA" in s or "COMMERCIAL_CORE" in s :
2026-10-30 11:10:54 +05:30
return "🏅 VERIFIED (RIAA)"
2026-10-31 14:43:43 +05:30
elif "LASTFM" in s :
return "📻 VERIFIED (Last.fm)"
elif "ESTIMATED_SEA" in s :
2026-10-30 11:10:54 +05:30
return "📊 ESTIMATED (SEA)"
2026-10-31 14:43:43 +05:30
return "⏳ UNAUDITED / PENDING"
2026-10-30 11:10:54 +05:30
2026-10-22 17:20:44 +05:30
# ----------------- Sidebar Controls -----------------
with st . sidebar :
2026-10-31 14:43:43 +05:30
st . markdown ( "### ⚡ HIFFI Intelligence Suite" )
st . caption ( "Hip-Hop 500 & Master Catalog Intelligence" )
2026-10-22 17:20:44 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-31 14:43:43 +05:30
catalog_source = st . selectbox (
"🗂️ Active Data Scope:" ,
[ "⚡ Hip-Hop 500 (Executive Telemetry)" , "🌐 Global Master Catalog (17,000+ Acts)" ],
2026-11-04 16:49:39 +05:30
index = 0 ,
2026-10-22 17:20:44 +05:30
)
2026-10-31 14:43:43 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
# =====================================================================
# MODULE 1: GLOBAL MASTER CATALOG (17,000+ ACTS)
# =====================================================================
if "Global Master Catalog" in catalog_source :
with st . sidebar :
st . markdown ( "##### 🔍 17k Catalog Filters" )
if df_17k . empty :
st . error ( "Master 17k dataset not found at data/master_artists_intelligence_17k_final.csv" )
st . stop ()
tier_list = [ "All Tiers" ] + sorted ( df_17k [ "catalog_intelligence_tier" ] . dropna () . unique () . tolist ())
sel_tier = st . selectbox ( "Intelligence Tier:" , tier_list , index = 0 )
search_17k = st . text_input ( "Search Artist Name:" , placeholder = "e.g. Eminem, The Roots..." )
filt_17k = df_17k . copy ()
if sel_tier != "All Tiers" :
filt_17k = filt_17k [ filt_17k [ "catalog_intelligence_tier" ] == sel_tier ]
if search_17k :
filt_17k = filt_17k [ filt_17k [ "name" ] . str . contains ( search_17k , case = False , na = False )]
head1 , head2 = st . columns ([ 3 , 1 ])
with head1 :
st . markdown ( "<h2 style='margin-bottom: 2px;'>🌐 Global Master Artist Catalog (17k)</h2>" , unsafe_allow_html = True )
st . markdown ( "<p style='color: #9ca3af; font-size: 0.92rem;'>Empirical registry validation via CSPC sales, RIAA certifications, and verified Last.fm global scrobbles.</p>" , unsafe_allow_html = True )
with head2 :
st . markdown ( f "<div style='text-align: right; color: #6b7280; font-size: 0.8rem; padding-top: 10px;'>Filtered: <b> { len ( filt_17k ) : , } / { len ( df_17k ) : , } </b> acts</div>" , unsafe_allow_html = True )
# 17k Macro KPIs
mk1 , mk2 , mk3 , mk4 , mk5 = st . columns ( 5 )
with mk1 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title">Universe Size</div><div class="kpi-value"> { len ( df_17k ) : , } </div><div class="kpi-subtitle">Total Cataloged</div></div>' , unsafe_allow_html = True )
with mk2 :
ver_cnt = df_17k [ "catalog_rank" ] . notna () . sum ()
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #10b981;">Verified Entities</div><div class="kpi-value" style="color: #10b981;"> { ver_cnt : , } </div><div class="kpi-subtitle">Registry Authenticated</div></div>' , unsafe_allow_html = True )
with mk3 :
t1_cnt = ( df_17k [ "catalog_intelligence_tier" ] == "TIER_1_GLOBAL_SUPERSTAR_CSPC" ) . sum ()
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #f59e0b;">Tier 1 Superstars</div><div class="kpi-value" style="color: #f59e0b;"> { t1_cnt : , } </div><div class="kpi-subtitle">Audited CSPC EAS</div></div>' , unsafe_allow_html = True )
with mk4 :
lfm_cnt = ( df_17k [ "catalog_intelligence_tier" ] == "TIER_3_LASTFM_VERIFIED_ENTITY" ) . sum ()
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #38bdf8;">Last.fm Verified</div><div class="kpi-value" style="color: #38bdf8;"> { lfm_cnt : , } </div><div class="kpi-subtitle">Active Platform Entities</div></div>' , unsafe_allow_html = True )
with mk5 :
unver_cnt = len ( df_17k ) - ver_cnt
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #ef4444;">Unaudited</div><div class="kpi-value" style="color: #ef4444;"> { unver_cnt : , } </div><div class="kpi-subtitle">Zero-Registry Matches</div></div>' , unsafe_allow_html = True )
2026-10-22 17:20:44 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-31 14:43:43 +05:30
render_cols = [
"catalog_rank" , "tier_rank" , "name" , "catalog_intelligence_tier" ,
"audited_sales_units" , "lastfm_listeners" , "lastfm_playcount" , "lastfm_url"
2026-10-22 17:20:44 +05:30
]
2026-10-31 14:43:43 +05:30
disp_cols = [ c for c in render_cols if c in filt_17k . columns ]
2026-10-22 17:20:44 +05:30
2026-10-30 11:10:54 +05:30
st . dataframe (
2026-10-31 14:43:43 +05:30
filt_17k [ disp_cols ] . reset_index ( drop = True ),
use_container_width = True ,
height = 560 ,
2026-10-30 11:10:54 +05:30
column_config = {
2026-10-31 14:43:43 +05:30
"catalog_rank" : st . column_config . NumberColumn ( "Global Rank" , format = "# %d " , width = "small" ),
"tier_rank" : st . column_config . NumberColumn ( "Tier Rank" , format = "# %d " , width = "small" ),
"name" : st . column_config . TextColumn ( "Artist Name" , width = "medium" ),
"catalog_intelligence_tier" : st . column_config . TextColumn ( "Registry Tier" , width = "medium" ),
"audited_sales_units" : st . column_config . NumberColumn ( "Audited Sales Units" , format = "%,d" , width = "medium" ),
"lastfm_listeners" : st . column_config . NumberColumn ( "Verified Listeners" , format = "%,d" , width = "medium" ),
"lastfm_playcount" : st . column_config . NumberColumn ( "Global Scrobbles" , format = "%,d" , width = "medium" ),
2026-11-04 16:49:39 +05:30
"lastfm_url" : st . column_config . LinkColumn ( "Last.fm Profile" , width = "small" ),
},
2026-10-30 11:10:54 +05:30
)
2026-10-23 10:52:54 +05:30
2026-10-31 14:43:43 +05:30
with st . sidebar :
st . markdown ( "##### 💾 17k Data Export" )
csv_17k = filt_17k . to_csv ( index = False ) . encode ( "utf-8" )
st . download_button ( "📥 Export 17k Table CSV" , data = csv_17k , file_name = "master_17k_catalog.csv" , mime = "text/csv" , use_container_width = True )
2026-10-28 17:07:19 +05:30
2026-10-31 14:43:43 +05:30
# =====================================================================
2026-11-04 16:49:39 +05:30
# MODULE 2: HIFFI HIP-HOP 500 (EXECUTIVE DASHBOARD)
2026-10-31 14:43:43 +05:30
# =====================================================================
2026-10-28 17:07:19 +05:30
else :
2026-10-31 14:43:43 +05:30
df = df_500
2026-11-04 16:49:39 +05:30
if df . empty :
st . error ( "Hip-Hop 500 dataset not found. Please verify data/hiffi_catalog.db exists." )
st . stop ()
2026-10-31 14:43:43 +05:30
with st . sidebar :
view_mode = st . radio (
"Leaderboard Perspective:" ,
[
"🏆 Published Multi-Platform Rank" ,
"🚀 Breakout Velocity (BVI)" ,
"💿 Record Sales (CSPC Methodology)" ,
"🧪 Commercial Simulation Engine (CPI)" ,
"🔍 Full Cohort Audit Grid" ,
],
index = 0 ,
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
catalog_filter = "All Monitored Artists (500)"
if view_mode in ( "💿 Record Sales (CSPC Methodology)" , "🧪 Commercial Simulation Engine (CPI)" ):
st . markdown ( "##### 🔍 Sales Catalog Scope" )
catalog_filter = st . radio (
"Filter Rows by Sales Telemetry:" ,
[ "All Monitored Artists (500)" , "Verified Only (321)" , "Pure CSPC Only (62)" ],
index = 0 ,
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
sim_weight = 0.15
sim_mode = "matched_only"
if view_mode == "🧪 Commercial Simulation Engine (CPI)" and engine is not None :
st . markdown ( "##### 🧪 Simulation Parameters" )
sim_mode_choice = st . radio (
"Evaluation Scope:" ,
[ "🎯 Matched Cohort Only" , "🌐 Global Cohort (N=500, Weight Redistribution)" ],
index = 1 if catalog_filter == "All Monitored Artists (500)" else 0 ,
)
sim_mode = "matched_only" if "Matched" in sim_mode_choice else "global_redistribution"
sim_weight = st . select_slider (
"Commercial Signal Weight:" ,
options = [ 0.0 , 0.05 , 0.10 , 0.15 , 0.20 ],
value = 0.15 ,
format_func = lambda x : f " { int ( x * 100 ) } % Commercial" ,
)
st . caption ( f "Baseline Score Weight: ** { int (( 1.0 - sim_weight ) * 100 ) } %**" )
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
st . markdown ( "##### 🛡️ Cohort Filters" )
all_verticals = sorted ( df [ "subgenre" ] . dropna () . unique () . tolist ())
selected_verticals = st . multiselect ( "Vertical" , options = all_verticals , default = all_verticals )
tier_options = sorted ( df [ "platform_evidence_tier" ] . dropna () . unique () . astype ( int ) . tolist (), reverse = True )
selected_tiers = st . multiselect ( "Evidence Tier" , options = tier_options , default = tier_options )
min_xp = st . slider ( "Min HIFFI-XP Score" , 0.0 , 100.0 , 0.0 , 5.0 )
filtered_df = df [
( df [ "subgenre" ] . isin ( selected_verticals ))
& ( df [ "platform_evidence_tier" ] . isin ( selected_tiers ))
& ( df [ "hiffi_xp_score" ] . fillna ( 0.0 ) >= min_xp )
] . copy ()
2026-11-04 16:49:39 +05:30
if "sales_data_status" in filtered_df . columns :
if catalog_filter == "Pure CSPC Only (62)" :
filtered_df = filtered_df [ filtered_df [ "sales_data_status" ] == "VERIFIED_CSPC" ] . copy ()
elif catalog_filter == "Verified Only (321)" :
filtered_df = filtered_df [ filtered_df [ "sales_data_status" ] . isin ([ "VERIFIED_CSPC" , "VERIFIED_RIAA" ])] . copy ()
2026-10-31 14:43:43 +05:30
sim_metrics = {}
if view_mode == "🧪 Commercial Simulation Engine (CPI)" and engine is not None :
try :
filtered_df = engine . simulate_ranking ( filtered_df , commercial_weight = sim_weight , mode = sim_mode )
sim_metrics = engine . compute_simulation_metrics ( filtered_df )
except Exception :
pass
with st . sidebar :
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
st . markdown ( "##### 💾 Unified Audit Exports" )
if generate_executive_sales_workbook is not None :
try :
excel_workbook_bytes = generate_executive_sales_workbook ( filtered_df , commercial_weight = sim_weight , mode = sim_mode )
st . download_button (
"📊 Multi-Tab Audit Excel (.xlsx)" ,
data = excel_workbook_bytes ,
file_name = "hiffi_executive_sales_audit.xlsx" ,
mime = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ,
use_container_width = True ,
2026-10-30 11:10:54 +05:30
)
2026-10-31 14:43:43 +05:30
except Exception :
pass
csv_payload = filtered_df . to_csv ( index = False ) . encode ( "utf-8" )
st . download_button (
"📥 Filtered Table CSV" ,
data = csv_payload ,
file_name = "hiffi_multiplatform_filtered.csv" ,
mime = "text/csv" ,
use_container_width = True ,
)
2026-10-30 11:10:54 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-31 14:43:43 +05:30
st . caption ( "Governance: CSPC Methodology • EAS Units • Zero-Imputation Compliant" )
2026-10-28 17:07:19 +05:30
2026-10-31 14:43:43 +05:30
head_col1 , head_col2 = st . columns ([ 3 , 1 ])
with head_col1 :
st . markdown ( "<h2 style='margin-bottom: 2px;'>HIFFI Hip-Hop 500 Intelligence Hub</h2>" , unsafe_allow_html = True )
st . markdown ( "<p style='color: #9ca3af; font-size: 0.92rem; margin-top: 0;'>Multi-platform composite rankings with zero-imputation policy, dynamic weight redistribution, and verified record sales.</p>" , unsafe_allow_html = True )
with head_col2 :
st . markdown (
f "<div style='text-align: right; color: #6b7280; font-size: 0.8rem; padding-top: 10px;'>Filtered Cohort: <b> { len ( filtered_df ) } / { len ( df ) } </b> artists</div>" ,
unsafe_allow_html = True ,
)
2026-10-30 11:10:54 +05:30
2026-11-04 16:49:39 +05:30
# 500 Macro KPI Cards (6 Columns with YouTube Telemetry)
k1 , k2 , k3 , k4 , k5 , k6 = st . columns ( 6 )
2026-10-31 14:43:43 +05:30
with k1 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title">Tracked Artists</div><div class="kpi-value"> { len ( df ) } </div><div class="kpi-subtitle">Monitored Cohort</div></div>' , unsafe_allow_html = True )
with k2 :
t3_count = len ( df [ df [ "platform_evidence_tier" ] == 3 ])
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #10b981;">Tier 3 (Complete)</div><div class="kpi-value" style="color: #10b981;"> { t3_count } </div><div class="kpi-subtitle">YouTube + Spotify + Instagram</div></div>' , unsafe_allow_html = True )
with k3 :
2026-11-04 16:49:39 +05:30
yt_count = df [ "subscriber_count" ] . fillna ( 0 ) . gt ( 0 ) . sum () if "subscriber_count" in df . columns else len ( df )
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #ef4444;">YouTube Telemetry</div><div class="kpi-value" style="color: #ef4444;"> { yt_count } </div><div class="kpi-subtitle">Verified video channels</div></div>' , unsafe_allow_html = True )
2026-10-31 14:43:43 +05:30
with k4 :
2026-11-04 16:49:39 +05:30
sp_count = df [ "spotify_monthly_listeners" ] . fillna ( 0 ) . gt ( 0 ) . sum () if "spotify_monthly_listeners" in df . columns else len ( df )
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #38bdf8;">Spotify Telemetry</div><div class="kpi-value" style="color: #38bdf8;"> { sp_count } </div><div class="kpi-subtitle">Verified monthly listeners</div></div>' , unsafe_allow_html = True )
2026-10-31 14:43:43 +05:30
with k5 :
2026-11-04 16:49:39 +05:30
ig_count = df [ "instagram_followers" ] . fillna ( 0 ) . gt ( 0 ) . sum () if "instagram_followers" in df . columns else len ( df )
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #f59e0b;">Instagram Audience</div><div class="kpi-value" style="color: #f59e0b;"> { ig_count } </div><div class="kpi-subtitle">Verified public followings</div></div>' , unsafe_allow_html = True )
with k6 :
cataloged_count = df [ "total_eas_cspc" ] . fillna ( 0 ) . gt ( 0 ) . sum () if "total_eas_cspc" in df . columns else 0
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #ec4899;">Catalog Coverage</div><div class="kpi-value" style="color: #ec4899;"> { cataloged_count } </div><div class="kpi-subtitle">Commercial Units Indexed</div></div>' , unsafe_allow_html = True )
2026-10-30 11:10:54 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-11-04 16:49:39 +05:30
if view_mode in ( "💿 Record Sales (CSPC Methodology)" , "🧪 Commercial Simulation Engine (CPI)" ) and "sales_data_status" in df . columns :
2026-10-31 14:43:43 +05:30
verified_cspc_cnt = int (( df [ "sales_data_status" ] == "VERIFIED_CSPC" ) . sum ())
verified_riaa_cnt = int (( df [ "sales_data_status" ] == "VERIFIED_RIAA" ) . sum ())
estimated_sea_cnt = int (( df [ "sales_data_status" ] == "ESTIMATED_SEA" ) . sum ())
total_active_coverage = verified_cspc_cnt + verified_riaa_cnt + estimated_sea_cnt
2026-11-04 16:49:39 +05:30
coverage_pct = ( total_active_coverage / len ( df )) * 100.0 if len ( df ) > 0 else 0.0
2026-10-30 11:10:54 +05:30
2026-10-31 14:43:43 +05:30
st . markdown (
f """
<div class="coverage-card">
<div>
<span style="font-weight: 800; color: #f9fafb; font-size: 0.92rem;">📡 Commercial Telemetry Coverage Progress:</span>
<span style="color: #10b981; font-weight: 700; margin-left: 8px;"> { verified_cspc_cnt } CSPC Verified</span>
<span style="color: #64748b; margin: 0 6px;">•</span>
<span style="color: #38bdf8; font-weight: 700;"> { verified_riaa_cnt } RIAA Certified</span>
<span style="color: #64748b; margin: 0 6px;">•</span>
<span style="color: #a855f7; font-weight: 600;"> { estimated_sea_cnt } Streaming SEA</span>
</div>
<div style="font-size: 0.85rem; color: #94a3b8;">
Active Commercial Coverage: <strong style="color: #10b981;"> { coverage_pct : .1f } %</strong> ( { total_active_coverage } / { len ( df ) } )
</div>
</div>
""" ,
unsafe_allow_html = True ,
)
if view_mode == "💿 Record Sales (CSPC Methodology)" :
st . markdown ( "### 💿 Global Record Sales & Lifetime Commercial Ranking" )
st . caption ( "Standardized on ChartMasters CSPC, verified RIAA certifications, and video/audio streaming equivalent units." )
sc1 , sc2 , sc3 , sc4 = st . columns ( 4 )
2026-11-04 16:49:39 +05:30
total_sales_volume = filtered_df [ "total_eas_cspc" ] . fillna ( 0 ) . sum () if "total_eas_cspc" in filtered_df . columns else 0
cspc_count = ( filtered_df [ "sales_data_status" ] == "VERIFIED_CSPC" ) . sum () if "sales_data_status" in filtered_df . columns else 0
riaa_count = ( filtered_df [ "sales_data_status" ] == "VERIFIED_RIAA" ) . sum () if "sales_data_status" in filtered_df . columns else 0
sea_count = ( filtered_df [ "sales_data_status" ] == "ESTIMATED_SEA" ) . sum () if "sales_data_status" in filtered_df . columns else 0
2026-10-31 14:43:43 +05:30
with sc1 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title">Tracked Catalog Volume</div><div class="kpi-value"> { total_sales_volume / 1e6 : .1f } M</div><div class="kpi-subtitle">Total Equivalent Album Sales (EAS)</div></div>' , unsafe_allow_html = True )
with sc2 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #10b981;">CSPC Verified</div><div class="kpi-value" style="color: #10b981;"> { cspc_count } </div><div class="kpi-subtitle">ChartMasters Full Dossiers</div></div>' , unsafe_allow_html = True )
with sc3 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #38bdf8;">RIAA Certified</div><div class="kpi-value" style="color: #38bdf8;"> { riaa_count } </div><div class="kpi-subtitle">Domestic Certifications</div></div>' , unsafe_allow_html = True )
with sc4 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #a855f7;">Streaming SEA</div><div class="kpi-value" style="color: #a855f7;"> { sea_count } </div><div class="kpi-subtitle">Luminate/Billboard Conversion</div></div>' , unsafe_allow_html = True )
st . markdown ( "#### 🏆 All-Time Global Sales Leaderboard" )
2026-11-04 16:49:39 +05:30
sales_table_df = filtered_df . sort_values ( by = "total_eas_cspc" , ascending = False ) . copy () if "total_eas_cspc" in filtered_df . columns else filtered_df . copy ()
if "sales_data_status" in sales_table_df . columns :
sales_table_df [ "provenance_badge" ] = sales_table_df [ "sales_data_status" ] . apply ( get_provenance_badge )
2026-10-31 14:43:43 +05:30
sales_cols = [
"cohort_sales_rank" , "chartmasters_sales_rank" , "name" , "provenance_badge" ,
"total_eas_cspc" , "pure_album_sales" , "streaming_eas" , "physical_singles_sales" ,
"digital_singles_sales" , "commercial_power_index" , "hiffi_xp_published_rank"
]
render_s_cols = [ c for c in sales_cols if c in sales_table_df . columns ]
st . dataframe (
sales_table_df [ render_s_cols ] . reset_index ( drop = True ),
use_container_width = True ,
height = 380 ,
column_config = {
"cohort_sales_rank" : st . column_config . NumberColumn ( "Cohort Sales Rank" , format = "# %d " , width = "small" ),
"chartmasters_sales_rank" : st . column_config . NumberColumn ( "All-Time Global Rank" , format = "# %d " , width = "small" ),
"name" : st . column_config . TextColumn ( "Artist" , width = "medium" ),
"provenance_badge" : st . column_config . TextColumn ( "Audit Provenance" , width = "medium" ),
"total_eas_cspc" : st . column_config . NumberColumn ( "Total EAS Units" , format = "%,d" , width = "medium" ),
"pure_album_sales" : st . column_config . NumberColumn ( "Pure Studio Albums" , format = "%,d" , width = "medium" ),
"streaming_eas" : st . column_config . NumberColumn ( "Streaming EAS" , format = "%,d" , width = "medium" ),
"physical_singles_sales" : st . column_config . NumberColumn ( "Physical Singles" , format = "%,d" , width = "small" ),
"digital_singles_sales" : st . column_config . NumberColumn ( "Digital Downloads" , format = "%,d" , width = "small" ),
"commercial_power_index" : st . column_config . ProgressColumn ( "CPI Score" , min_value = 0 , max_value = 100 , format = " %.1f " , width = "small" ),
"hiffi_xp_published_rank" : st . column_config . NumberColumn ( "HIFFI Base Rank" , format = "# %d " , width = "small" ),
},
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
c_s1 , c_s2 = st . columns ( 2 )
with c_s1 :
2026-11-04 16:49:39 +05:30
if "total_eas_cspc" in sales_table_df . columns :
top_sellers = sales_table_df [ sales_table_df [ "total_eas_cspc" ] . fillna ( 0 ) > 0 ] . head ( 12 )
fig_format = go . Figure ()
fig_format . add_trace ( go . Bar ( name = "Traditional Albums" , x = top_sellers [ "name" ], y = top_sellers . get ( "pure_album_sales" , 0 ), marker_color = "#8b5cf6" ))
fig_format . add_trace ( go . Bar ( name = "Digital Singles" , x = top_sellers [ "name" ], y = top_sellers . get ( "digital_singles_sales" , 0 ), marker_color = "#38bdf8" ))
fig_format . add_trace ( go . Bar ( name = "Streaming EAS" , x = top_sellers [ "name" ], y = top_sellers . get ( "streaming_eas" , 0 ), marker_color = "#10b981" ))
fig_format . update_layout (
barmode = "stack" , title = "Format Contribution: Pure Albums vs Downloads vs Streaming EAS" ,
template = "plotly_dark" , paper_bgcolor = "#111827" , plot_bgcolor = "#111827" ,
font = dict ( color = "#9ca3af" ), height = 360 , margin = dict ( l = 20 , r = 20 , t = 50 , b = 20 ),
legend = dict ( orientation = "h" , yanchor = "bottom" , y = 1.02 , xanchor = "right" , x = 1.0 ),
)
st . plotly_chart ( fig_format , use_container_width = True )
2026-10-31 14:43:43 +05:30
with c_s2 :
2026-11-04 16:49:39 +05:30
if "total_eas_cspc" in sales_table_df . columns and "hiffi_xp_score" in sales_table_df . columns :
scatter_data = sales_table_df . dropna ( subset = [ "total_eas_cspc" , "hiffi_xp_score" ]) . copy ()
if not scatter_data . empty :
fig_quad = px . scatter (
scatter_data , x = "hiffi_xp_score" , y = "total_eas_cspc" , size = "total_eas_cspc" ,
color = "provenance_badge" if "provenance_badge" in scatter_data . columns else None ,
hover_name = "name" , log_y = True ,
title = "Legacy vs. Velocity Quadrant (All-Time Sales vs HIFFI-XP)" ,
labels = { "hiffi_xp_score" : "Current Velocity (HIFFI-XP)" , "total_eas_cspc" : "Total Lifetime EAS Units (Log Scale)" },
template = "plotly_dark" ,
)
fig_quad . update_layout ( paper_bgcolor = "#111827" , plot_bgcolor = "#111827" , font = dict ( color = "#9ca3af" ), height = 360 , margin = dict ( l = 20 , r = 20 , t = 50 , b = 20 ))
st . plotly_chart ( fig_quad , use_container_width = True )
2026-10-31 14:43:43 +05:30
2026-10-30 11:10:54 +05:30
else :
2026-10-31 14:43:43 +05:30
top3 = filtered_df . sort_values ( by = "hiffi_xp_published_rank" , ascending = True ) . head ( 3 )
if len ( top3 ) >= 3 and view_mode != "🧪 Commercial Simulation Engine (CPI)" :
st . markdown ( "#### 👑 Market Leaders (Published Baseline Rankings)" )
p1 , p2 , p3 = st . columns ( 3 )
podium_data = [
( p1 , top3 . iloc [ 0 ], "🥇 PUBLISHED #1" , "podium-gold" , "#f59e0b" ),
( p2 , top3 . iloc [ 1 ], "🥈 PUBLISHED #2" , "podium-silver" , "#94a3b8" ),
( p3 , top3 . iloc [ 2 ], "🥉 PUBLISHED #3" , "podium-bronze" , "#f97316" ),
]
for col , row_data , rank_label , css_class , accent_color in podium_data :
tier_val = int ( row_data . get ( "platform_evidence_tier" , 1 ))
2026-11-04 16:49:39 +05:30
yt_str = f " { int ( row_data [ 'subscriber_count' ]) : , } " if pd . notna ( row_data . get ( "subscriber_count" )) else "NaN"
2026-10-31 14:43:43 +05:30
sp_str = f " { int ( row_data [ 'spotify_monthly_listeners' ]) : , } " if pd . notna ( row_data . get ( "spotify_monthly_listeners" )) else "NaN"
ig_str = f " { int ( row_data [ 'instagram_followers' ]) : , } " if pd . notna ( row_data . get ( "instagram_followers" )) else "NaN"
with col :
st . markdown (
f """
<div class="podium-tile { css_class } ">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;">
<span style="font-weight: 800; color: { accent_color } ; font-size: 0.85rem;"> { rank_label } </span>
<span class="badge badge-tier { tier_val } ">Tier { tier_val } Evidence</span>
</div>
<div style="font-size: 1.35rem; font-weight: 800; color: #ffffff; margin-bottom: 2px;"> { row_data [ 'name' ] } </div>
<div style="font-size: 0.8rem; color: #6b7280; margin-bottom: 12px;"> { row_data . get ( 'channel_title' , '' ) } </div>
2026-11-04 16:49:39 +05:30
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; background: #0b0f17; padding: 10px 10px; border-radius: 8px;">
<div><div style="font-size: 0.64rem; color: #9ca3af;">HIFFI-XP</div><div style="font-size: 1.15rem; font-weight: 800; color: { accent_color } ;"> { row_data . get ( 'hiffi_xp_score' , 0.0 ) : .2f } </div></div>
<div><div style="font-size: 0.64rem; color: #9ca3af;">YT Subs</div><div style="font-size: 0.95rem; font-weight: 700; color: #ef4444;"> { yt_str } </div></div>
<div><div style="font-size: 0.64rem; color: #9ca3af;">Spotify</div><div style="font-size: 0.95rem; font-weight: 700; color: #38bdf8;"> { sp_str } </div></div>
<div><div style="font-size: 0.64rem; color: #9ca3af;">IG Follow</div><div style="font-size: 0.95rem; font-weight: 700; color: #e5e7eb;"> { ig_str } </div></div>
2026-10-31 14:43:43 +05:30
</div>
</div>
""" ,
unsafe_allow_html = True ,
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
if view_mode == "🧪 Commercial Simulation Engine (CPI)" :
st . markdown ( "#### 🧪 Simulation Impact & Decision Summary" )
sm1 , sm2 , sm3 , sm4 = st . columns ( 4 )
g_delta = f "+ { sim_metrics . get ( 'top_gainer_delta' , 0 ) } " if sim_metrics . get ( 'top_gainer_delta' , 0 ) > 0 else f " { sim_metrics . get ( 'top_gainer_delta' , 0 ) } "
l_delta = f " { sim_metrics . get ( 'top_loser_delta' , 0 ) } "
with sm1 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Top Gainer</div><div class="sim-kpi-val" style="color: #10b981;"> { sim_metrics . get ( "top_gainer_name" , "None" ) } <span style="font-size: 0.85rem;">(▲ { g_delta } )</span></div></div>' , unsafe_allow_html = True )
with sm2 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Top Loser</div><div class="sim-kpi-val" style="color: #ef4444;"> { sim_metrics . get ( "top_loser_name" , "None" ) } <span style="font-size: 0.85rem;">(▼ { l_delta } )</span></div></div>' , unsafe_allow_html = True )
with sm3 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Mean Absolute Shift</div><div class="sim-kpi-val" style="color: #38bdf8;">± { sim_metrics . get ( "mean_abs_delta" , 0.0 ) } <span style="font-size: 0.85rem; color: #94a3b8;">positions</span></div></div>' , unsafe_allow_html = True )
with sm4 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Simulation Scope</div><div class="sim-kpi-val" style="color: #f59e0b;"> { sim_metrics . get ( "matched_coverage" , 0 ) } / { len ( filtered_df ) } <span style="font-size: 0.85rem; color: #94a3b8;">( { sim_mode } )</span></div></div>' , unsafe_allow_html = True )
st . caption ( f "💡 **Executive Takeaway:** At ** { int ( sim_weight * 100 ) } % commercial weight**, the average cataloged artist moves **± { sim_metrics . get ( 'mean_abs_delta' , 0.0 ) } positions**." )
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
st . markdown ( f "#### 📋 { view_mode } " )
if view_mode == "🏆 Published Multi-Platform Rank" :
table_df = filtered_df . sort_values ( by = "hiffi_xp_published_rank" , ascending = True ) . copy ()
2026-11-04 16:49:39 +05:30
# Explicitly placing subscriber_count right after HIFFI-XP Score
cols = [
"hiffi_xp_published_rank" , "hiffi_xp_rank" , "name" ,
"platform_evidence_tier" , "hiffi_xp_score" , "subscriber_count" ,
"spotify_monthly_listeners" , "instagram_followers" ,
"effective_weights" , "anomaly_flags"
]
2026-10-31 14:43:43 +05:30
elif view_mode == "🚀 Breakout Velocity (BVI)" :
2026-11-04 16:49:39 +05:30
bvi_series = filtered_df . get ( "breakout_velocity_index" , pd . Series ( 0.0 , index = filtered_df . index )) . fillna ( 0.0 )
table_df = filtered_df [ bvi_series . notna ()] . copy ()
table_df [ "breakout_velocity_index" ] = bvi_series
table_df = table_df . sort_values ( by = "breakout_velocity_index" , ascending = False )
2026-10-31 14:43:43 +05:30
cols = [ "name" , "breakout_velocity_index" , "hiffi_xp_published_rank" , "daily_view_velocity" , "momentum_30d" , "subscriber_count" , "subgenre" ]
elif view_mode == "🧪 Commercial Simulation Engine (CPI)" :
2026-11-04 16:49:39 +05:30
table_df = filtered_df . sort_values ( by = "simulated_rank" , ascending = True ) . copy () if "simulated_rank" in filtered_df . columns else filtered_df . copy ()
2026-10-31 14:43:43 +05:30
def format_rank_delta ( val ):
if pd . isna ( val ):
return "N/A"
ival = int ( val )
if ival > 0 :
return f "▲ + { ival } (Up)"
elif ival < 0 :
return f "▼ { ival } (Down)"
else :
return "— 0 (Equal)"
2026-11-04 16:49:39 +05:30
if "simulation_rank_delta" in table_df . columns :
table_df [ "rank_shift_indicator" ] = table_df [ "simulation_rank_delta" ] . apply ( format_rank_delta )
else :
table_df [ "rank_shift_indicator" ] = "— 0"
2026-10-31 14:43:43 +05:30
comp_rank = "baseline_matched_rank" if sim_mode == "matched_only" else "hiffi_xp_published_rank"
cols = [
"simulated_rank" , comp_rank , "rank_shift_indicator" , "name" ,
"simulated_hiffi_score" , "hiffi_xp_score" , "commercial_power_index" ,
"total_eas_cspc" , "sales_data_status" ,
]
else :
table_df = filtered_df . sort_values ( by = "hiffi_xp_published_rank" , ascending = True ) . copy ()
2026-11-04 16:49:39 +05:30
cols = [ "hiffi_xp_published_rank" , "name" , "production_hiffi_rank" , "hiffi_xp_rank" , "rank_delta" , "platform_evidence_tier" , "hiffi_xp_score" , "subscriber_count" , "spotify_monthly_listeners" , "instagram_followers" , "total_eas_cspc" , "sales_data_status" , "evidence_exclusions" , "anomaly_flags" ]
2026-10-31 14:43:43 +05:30
display_table = table_df . copy ()
if "sales_data_status" in display_table . columns :
display_table [ "sales_data_status" ] = display_table [ "sales_data_status" ] . apply ( get_provenance_badge )
render_cols = [ c for c in cols if c in display_table . columns ]
st . dataframe (
display_table [ render_cols ] . reset_index ( drop = True ),
use_container_width = True ,
height = 340 ,
column_config = {
"hiffi_xp_published_rank" : st . column_config . NumberColumn ( "Published Rank" , format = " %d " , width = "small" ),
2026-11-04 16:49:39 +05:30
"hiffi_xp_rank" : st . column_config . NumberColumn ( "Raw Rank" , format = " %d " , width = "small" ),
"name" : st . column_config . TextColumn ( "Artist" , width = "medium" ),
"platform_evidence_tier" : st . column_config . NumberColumn ( "Tier" , format = "Tier %d " , width = "small" ),
2026-10-31 14:43:43 +05:30
"baseline_matched_rank" : st . column_config . NumberColumn ( "Baseline Match Rank" , format = " %d " , width = "small" ),
"simulated_rank" : st . column_config . NumberColumn ( "Simulated Rank" , format = " %d " , width = "small" ),
"rank_shift_indicator" : st . column_config . TextColumn ( "Simulated Δ (Movement)" , width = "medium" ),
"simulated_hiffi_score" : st . column_config . ProgressColumn ( "Simulated Score" , format = " %.2f " , min_value = 0 , max_value = 100 , width = "medium" ),
"hiffi_xp_score" : st . column_config . ProgressColumn ( "HIFFI-XP Score" , format = " %.2f " , min_value = 0 , max_value = 100 , width = "medium" ),
2026-11-04 16:49:39 +05:30
"subscriber_count" : st . column_config . NumberColumn ( "YouTube Subscribers" , format = "%,d" , width = "medium" ),
"spotify_monthly_listeners" : st . column_config . NumberColumn ( "Spotify Monthly Listeners" , format = "%,d" , width = "medium" ),
"instagram_followers" : st . column_config . NumberColumn ( "Instagram Followers" , format = "%,d" , width = "medium" ),
"breakout_velocity_index" : st . column_config . ProgressColumn ( "Breakout Velocity Index" , format = " %.2f " , min_value = 0 , max_value = 100 , width = "medium" ),
2026-10-31 14:43:43 +05:30
"commercial_power_index" : st . column_config . ProgressColumn ( "Commercial Power Index" , format = " %.1f " , min_value = 0 , max_value = 100 , width = "medium" ),
"total_eas_cspc" : st . column_config . NumberColumn ( "Total Equivalent Album Sales" , format = "%,d" , width = "medium" ),
"pure_album_sales" : st . column_config . NumberColumn ( "Traditional Album Sales" , format = "%,d" , width = "medium" ),
"streaming_eas" : st . column_config . NumberColumn ( "Streaming-Equivalent Album Sales" , format = "%,d" , width = "medium" ),
"sales_data_status" : st . column_config . TextColumn ( "Sales Audit Status" , width = "medium" ),
},
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-30 11:10:54 +05:30
c_left , c_right = st . columns ( 2 )
with c_left :
2026-11-04 16:49:39 +05:30
chart_df = filtered_df . dropna ( subset = [ "spotify_monthly_listeners" , "instagram_followers" , "hiffi_xp_score" ]) . copy () if all ( c in filtered_df . columns for c in [ "spotify_monthly_listeners" , "instagram_followers" , "hiffi_xp_score" ]) else pd . DataFrame ()
2026-10-30 11:10:54 +05:30
if not chart_df . empty :
fig_scatter = px . scatter (
2026-10-31 14:43:43 +05:30
chart_df , x = "spotify_monthly_listeners" , y = "instagram_followers" ,
size = "hiffi_xp_score" , color = "platform_evidence_tier" , hover_name = "name" ,
log_x = True , log_y = True , title = "Spotify Monthly Listeners vs. Instagram Followers" ,
2026-10-30 11:10:54 +05:30
labels = { "spotify_monthly_listeners" : "Spotify Monthly Listeners (Log Scale)" , "instagram_followers" : "Instagram Followers (Log Scale)" , "platform_evidence_tier" : "Tier" },
template = "plotly_dark" ,
)
2026-10-31 14:43:43 +05:30
fig_scatter . update_layout ( paper_bgcolor = "#111827" , plot_bgcolor = "#111827" , font = dict ( color = "#9ca3af" ), height = 320 , margin = dict ( l = 20 , r = 20 , t = 40 , b = 20 ))
st . plotly_chart ( fig_scatter , use_container_width = True )
2026-10-30 11:10:54 +05:30
with c_right :
2026-11-04 16:49:39 +05:30
if "platform_evidence_tier" in filtered_df . columns :
tier_counts = filtered_df [ "platform_evidence_tier" ] . value_counts () . reset_index ()
tier_counts . columns = [ "Tier" , "Count" ]
fig_pie = px . pie ( tier_counts , values = "Count" , names = "Tier" , title = "Evidence Tier Cohort Distribution" , template = "plotly_dark" , color = "Tier" , color_discrete_map = { 3 : "#10b981" , 2 : "#38bdf8" , 1 : "#f59e0b" , 0 : "#ef4444" })
fig_pie . update_layout ( paper_bgcolor = "#111827" , plot_bgcolor = "#111827" , font = dict ( color = "#9ca3af" ), height = 320 , margin = dict ( l = 20 , r = 20 , t = 40 , b = 20 ))
st . plotly_chart ( fig_pie , use_container_width = True )
2026-10-22 17:20:44 +05:30
2026-10-31 14:43:43 +05:30
# Dossier for 500
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
st . markdown ( "#### 🔎 Artist Dossier" )
selected_name = st . selectbox ( "Inspect Artist Details:" , df [ "name" ] . unique (), label_visibility = "collapsed" )
row = df [ df [ "name" ] == selected_name ] . iloc [ 0 ]
2026-10-22 17:20:44 +05:30
2026-11-04 16:49:39 +05:30
d1 , d2 , d3 , d4 , d5 , d6 = st . columns ( 6 )
2026-10-31 14:43:43 +05:30
with d1 :
h_val = row . get ( "hiffi_xp_score" )
st . metric ( "HIFFI-XP Score" , f " { h_val : .2f } " if pd . notna ( h_val ) else "N/A" )
with d2 :
pub_rank = row . get ( "hiffi_xp_published_rank" )
st . metric ( "Published Rank" , f "# { int ( pub_rank ) } " if pd . notna ( pub_rank ) else "Unranked" )
with d3 :
2026-11-04 16:49:39 +05:30
yt_s = row . get ( "subscriber_count" )
st . metric ( "YouTube Subscribers" , f " { int ( yt_s ) : , } " if pd . notna ( yt_s ) else "Unindexed (NaN)" )
with d4 :
2026-10-31 14:43:43 +05:30
sp_l = row . get ( "spotify_monthly_listeners" )
st . metric ( "Spotify Listeners" , f " { int ( sp_l ) : , } " if pd . notna ( sp_l ) else "Unindexed (NaN)" )
2026-11-04 16:49:39 +05:30
with d5 :
2026-10-31 14:43:43 +05:30
ig_f = row . get ( "instagram_followers" )
st . metric ( "Instagram Followers" , f " { int ( ig_f ) : , } " if pd . notna ( ig_f ) else "Unindexed (NaN)" )
2026-11-04 16:49:39 +05:30
with d6 :
2026-10-31 14:43:43 +05:30
sales_val = row . get ( "total_eas_cspc" )
st . metric ( "Total EAS Sales" , f " { int ( sales_val ) : , } " if pd . notna ( sales_val ) else "Awaiting Ingestion" )
2026-10-22 17:20:44 +05:30
2026-10-31 14:43:43 +05:30
st . markdown (
f """
<div style="background: #111827; padding: 14px 18px; border-radius: 8px; border: 1px solid #1f2937; margin-top: 10px; font-size: 0.85rem;">
<div style="display: flex; gap: 20px; flex-wrap: wrap;">
<div><b>Artist:</b> { row [ 'name' ] } </div>
<div><b>Evidence Tier:</b> Tier { int ( row . get ( 'platform_evidence_tier' , 1 )) } </div>
2026-11-04 16:49:39 +05:30
<div><b>YouTube Subscribers:</b> { f " { int ( row . get ( 'subscriber_count' )) : , } " if pd . notna ( row . get ( 'subscriber_count' )) else "N/A" } </div>
2026-10-31 14:43:43 +05:30
<div><b>Global Sales Rank:</b> { f "# { int ( row . get ( 'chartmasters_sales_rank' )) } " if pd . notna ( row . get ( 'chartmasters_sales_rank' )) else "Unranked" } </div>
<div><b>Cohort Sales Rank:</b> { f "# { int ( row . get ( 'cohort_sales_rank' )) } " if pd . notna ( row . get ( 'cohort_sales_rank' )) else "Uncataloged" } </div>
<div><b>Commercial Power Index:</b> { f " { row . get ( 'commercial_power_index' ) : .1f } " if pd . notna ( row . get ( 'commercial_power_index' )) else "Awaiting Audit" } </div>
<div><b>Traditional Albums:</b> { f " { int ( row . get ( 'pure_album_sales' )) : , } " if pd . notna ( row . get ( 'pure_album_sales' )) else "N/A" } </div>
<div><b>Streaming-Equivalent EAS:</b> { f " { int ( row . get ( 'streaming_eas' )) : , } " if pd . notna ( row . get ( 'streaming_eas' )) else "N/A" } </div>
<div><b>Sales Status:</b> { get_provenance_badge ( row . get ( 'sales_data_status' , '' )) } </div>
</div>
2026-10-23 10:52:54 +05:30
</div>
2026-10-31 14:43:43 +05:30
""" ,
unsafe_allow_html = True ,
)