Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import plotly.express as px | |
| import seaborn as sns | |
| import matplotlib.pyplot as plt | |
| import networkx as nx | |
| import plotly.graph_objects as go | |
| from itertools import chain, combinations | |
| import numpy as np | |
| from collections import Counter | |
| def generate_popularity_trends(df): | |
| st.header("Popularity Trends Over Time") | |
| tab1, tab2, tab3 = st.tabs( | |
| ["Average Popularity", "Individual Songs", "Top 10 Songs"]) | |
| with tab1: | |
| st.markdown( | |
| "**Average Popularity by Decade:** This chart shows how the average popularity of songs has changed over different decades.") | |
| if 'Decade' in df.columns: | |
| top_decades = df.groupby('Decade')['Popularity'].mean( | |
| ).reset_index().nlargest(10, 'Popularity') | |
| fig1 = go.Figure() | |
| fig1.add_trace(go.Scatter( | |
| x=top_decades['Decade'], | |
| y=top_decades['Popularity'], | |
| mode='lines+markers', | |
| fill='tonexty', | |
| line=dict(color='royalblue', width=3), | |
| marker=dict(size=8, color='darkblue', | |
| line=dict(width=2, color='white')), | |
| name='Popularity', | |
| hovertext=top_decades['Decade'] | |
| )) | |
| fig1.update_layout( | |
| title='Top 10 Decades by Average Popularity', | |
| xaxis_title='Decade', | |
| yaxis_title='Average Popularity Score', | |
| template='plotly_white', | |
| width=900, | |
| height=450 | |
| ) | |
| st.plotly_chart(fig1) | |
| else: | |
| st.error("Cannot plot: 'Decade' column missing.") | |
| with tab2: | |
| st.markdown( | |
| "**Top 10 Individual Songs:** This scatter plot highlights the popularity of the top 10 most popular songs over time.") | |
| if 'Year' in df.columns: | |
| top_songs = df.nlargest(10, 'Popularity') | |
| fig2 = px.scatter( | |
| top_songs, x='Year', y='Popularity', | |
| color='Popularity', | |
| size='Popularity', | |
| color_continuous_scale='viridis', | |
| title='Top 10 Individual Songs by Popularity', | |
| hover_data=['Track Name', 'Artist Name(s)', 'Year'] | |
| ) | |
| fig2.update_layout( | |
| xaxis_title='Release Year', | |
| yaxis_title='Popularity Score', | |
| template='plotly_white', | |
| width=900, | |
| height=500 | |
| ) | |
| st.plotly_chart(fig2) | |
| else: | |
| st.error("Cannot plot: 'Year' column missing.") | |
| with tab3: | |
| st.markdown( | |
| "**Top 10 Most Popular Songs:** This bar chart displays the top 10 songs based on their popularity scores.") | |
| if 'Track Name' in df.columns and 'Popularity' in df.columns: | |
| top_songs = df.nlargest(10, 'Popularity')[ | |
| ['Track Name', 'Artist Name(s)', 'Popularity']] | |
| fig3 = px.bar( | |
| top_songs, y='Track Name', x='Popularity', | |
| orientation='h', color='Popularity', | |
| color_continuous_scale='deep', | |
| title='Top 10 Most Popular Songs', | |
| labels={'Track Name': 'Song Title', | |
| 'Popularity': 'Popularity Score'}, | |
| hover_data=['Track Name', 'Artist Name(s)'] | |
| ) | |
| fig3.update_layout( | |
| xaxis_title='Popularity Score', | |
| yaxis_title='Song Title', | |
| template='plotly_white', | |
| width=900, | |
| height=500 | |
| ) | |
| st.plotly_chart(fig3) | |
| else: | |
| st.error("Cannot plot: 'Track Name' or 'Popularity' column missing.") | |
| def generate_audio_features(df): | |
| st.header("Audio Features Analysis") | |
| feature = st.selectbox( | |
| "Select Feature", ['Danceability', 'Energy', 'Tempo', 'Loudness'] | |
| ) | |
| tab1, tab2 = st.tabs(["Distribution", "By Decade"]) | |
| with tab1: | |
| st.markdown( | |
| f"**Top 20 {feature} Values:** This bar chart displays the distribution of the top 20 songs based on {feature}.") | |
| top_features = df.nlargest(20, feature) | |
| fig = px.bar( | |
| top_features, x='Track Name', y=feature, | |
| color='Decade' if 'Decade' in df.columns else None, | |
| title=f'Top 20 Songs by {feature}', | |
| color_discrete_sequence=px.colors.qualitative.Set2, | |
| hover_data=['Track Name', 'Artist Name(s)'] | |
| ) | |
| fig.update_layout(xaxis_tickangle=-45, template='plotly_white') | |
| st.plotly_chart(fig) | |
| with tab2: | |
| st.markdown( | |
| f"**{feature} by Decade:** This line chart compares the top {feature} trends over different decades.") | |
| if 'Decade' in df.columns: | |
| avg_feature_by_decade = df.groupby( | |
| 'Decade')[feature].mean().reset_index() | |
| fig2 = px.line( | |
| avg_feature_by_decade, x='Decade', y=feature, | |
| title=f'Average {feature} by Decade', | |
| markers=True, | |
| color_discrete_sequence=['red'], | |
| hover_data=['Decade'] | |
| ) | |
| fig2.update_layout(template='plotly_white', width=800, height=400) | |
| st.plotly_chart(fig2) | |
| else: | |
| st.error("Cannot plot: 'Decade' column missing.") | |
| def generate_genre_analysis(df): | |
| st.header("Genre & Artist Analysis") | |
| tab1, tab2, tab3 = st.tabs( | |
| ["Top Genres", "Genre Distribution", "Artist Popularity"]) | |
| with tab1: | |
| st.markdown( | |
| "**Top Genres in Top 10 Songs:** Displays the most common genres among the top 10 most popular songs.") | |
| top_songs = df.nlargest(10, 'Popularity') | |
| top_genres = top_songs.explode( | |
| 'Genres')['Genres'].value_counts().reset_index() | |
| fig1 = px.bar( | |
| top_genres, x='count', y='Genres', | |
| orientation='h', color='count', | |
| color_continuous_scale='viridis', | |
| title='Top Genres in Top 10 Songs', | |
| labels={'count': 'Number of Songs', 'Genres': 'Genre Name'}, | |
| hover_data=['Genres', 'count'] | |
| ) | |
| fig1.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig1) | |
| with tab2: | |
| st.markdown( | |
| "**Genre Distribution in Top 10 Songs:** Shows how different genres contribute to the top 10 songs.") | |
| genre_song_data = top_songs.explode('Genres') | |
| fig2 = px.bar( | |
| genre_song_data, x='Track Name', y='Popularity', color='Genres', | |
| title='Genre Distribution in Top 10 Songs', | |
| labels={'Track Name': 'Song Title', | |
| 'Popularity': 'Popularity Score', 'Genres': 'Genre'}, | |
| barmode='stack', | |
| hover_data=['Track Name', 'Genres'] | |
| ) | |
| fig2.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig2) | |
| with tab3: | |
| st.markdown( | |
| "**Artist Popularity in Top 10 Songs:** Visualizes the most popular artists in the top 10 songs with their song count and names.") | |
| artist_popularity = top_songs.groupby('Artist Name(s)').agg( | |
| {'Popularity': 'sum', 'Track Name': lambda x: list(x)}).reset_index().sort_values(by='Popularity', ascending=False) | |
| artist_popularity['Song Count'] = artist_popularity['Track Name'].apply( | |
| len) | |
| fig3 = px.bar( | |
| artist_popularity, x='Popularity', y='Artist Name(s)', | |
| orientation='h', color='Popularity', | |
| color_continuous_scale='blues', | |
| title='Artist Popularity in Top 10 Songs', | |
| labels={'Artist Name(s)': 'Artist Name', | |
| 'Popularity': 'Total Popularity Score', 'Song Count': 'Number of Songs'}, | |
| hover_data={'Artist Name(s)': True, 'Popularity': True, | |
| 'Song Count': True, 'Track Name': True} | |
| ) | |
| fig3.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig3) | |
| def generate_explicit_trends(df): | |
| st.header("Explicit Content Trends") | |
| st.markdown("**Explicit vs Non-Explicit Songs Over Time:** This line chart shows how the number of explicit and non-explicit songs has changed over different decades.") | |
| if 'Decade' in df.columns and 'Explicit' in df.columns: | |
| explicit_trends = df.groupby( | |
| ['Decade', 'Explicit']).size().reset_index(name='Count') | |
| fig = px.line( | |
| explicit_trends, x='Decade', y='Count', color='Explicit', | |
| markers=True, line_shape='linear', | |
| title='Explicit vs Non-Explicit Songs Over Time', | |
| labels={'Decade': 'Decade', 'Count': 'Number of Songs', | |
| 'Explicit': 'Song Type'}, | |
| color_discrete_map={True: 'purple', False: 'green'} | |
| ) | |
| fig.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig) | |
| else: | |
| st.error("Cannot plot: 'Decade' or 'Explicit' column missing.") | |
| def generate_album_insights(df): | |
| st.header("Album & Label Insights") | |
| tab1, tab2 = st.tabs(["Top Labels", "Album Popularity"]) | |
| with tab1: | |
| st.markdown( | |
| "**Top Record Labels:** Displays the most dominant record labels based on the number of songs they have released.") | |
| if 'Label' in df.columns: | |
| top_labels = df['Label'].value_counts().nlargest(10).reset_index() | |
| fig9 = px.sunburst( | |
| top_labels, path=['Label'], values='count', | |
| title='Top Record Labels by Song Count', | |
| color='count', color_continuous_scale='blues', | |
| labels={'Label': 'Record Label', 'count': 'Number of Songs'} | |
| ) | |
| fig9.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig9) | |
| else: | |
| st.error("Cannot plot: 'Label' column missing.") | |
| with tab2: | |
| st.markdown( | |
| "**Album Popularity:** Compares the popularity of albums based on the number of songs and their average popularity score.") | |
| if 'Album Name' in df.columns and 'Popularity' in df.columns: | |
| album_pop = df.groupby('Album Name')['Popularity'].agg( | |
| ['mean', 'count']).reset_index() | |
| album_pop = album_pop.sort_values(by=['mean', 'count'], ascending=[ | |
| False, False]).nlargest(10, 'mean') | |
| fig10 = px.strip( | |
| album_pop, x='mean', y='Album Name', | |
| color='count', | |
| title='Top 10 Albums by Popularity', | |
| labels={'Album Name': 'Album', | |
| 'mean': 'Average Popularity Score', 'count': 'Number of Songs'}, | |
| hover_data={'Album Name': True, 'count': True, 'mean': True}, | |
| color_discrete_sequence=px.colors.qualitative.Pastel | |
| ) | |
| fig10.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig10) | |
| else: | |
| st.error("Cannot plot: 'Album Name' or 'Popularity' column missing.") | |
| def generate_tempo_mood(df): | |
| st.header("Tempo & Mood Analysis") | |
| tab1, tab2 = st.tabs(["Tempo Trends", "Mood Scatter"]) | |
| with tab1: | |
| st.markdown("**Tempo Trends:** Tracks tempo changes.") | |
| if 'Year' in df.columns and 'Tempo' in df.columns: | |
| tempo_by_year = df.groupby('Year')['Tempo'].mean().reset_index() | |
| fig11 = px.line(tempo_by_year, x='Year', y='Tempo', | |
| title='Average Tempo Over Time', color_discrete_sequence=['orange']) | |
| fig11.update_layout(template='plotly_white', width=800, height=400) | |
| st.plotly_chart(fig11) | |
| else: | |
| st.error("Cannot plot: 'Year' or 'Tempo' column missing.") | |
| with tab2: | |
| st.markdown( | |
| "**Mood Analysis (Valence & Energy):** Categorizes songs based on mood and energy.") | |
| if 'Valence' in df.columns and 'Energy' in df.columns: | |
| top_songs = df.nlargest(10, 'Popularity') | |
| mood_by_valence = top_songs.groupby( | |
| 'Valence')['Energy'].mean().reset_index() | |
| fig12 = px.bar( | |
| mood_by_valence, x='Valence', y='Energy', | |
| title='Average Energy Levels by Valence (Mood Analysis)', | |
| color='Energy', color_continuous_scale='plasma' | |
| ) | |
| fig12.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig12) | |
| else: | |
| st.error("Cannot plot: 'Valence' or 'Energy' column missing.") | |
| def generate_top_artists_songs(df): | |
| st.header("Top Artists and Songs") | |
| tab1, tab2 = st.tabs(["Top Artists", "Top Songs"]) | |
| with tab1: | |
| st.markdown("**Most Featured Artists:** Shows top artists.") | |
| if 'Artist Name(s)' in df.columns: | |
| top_artists = df['Artist Name(s)'].value_counts().nlargest( | |
| 10).reset_index() | |
| fig13 = px.bar( | |
| top_artists, x='count', y='Artist Name(s)', | |
| orientation='h', | |
| title='Most Featured Artists', | |
| color='count', color_continuous_scale='greens' | |
| ) | |
| fig13.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig13) | |
| else: | |
| st.error("Cannot plot: 'Artist Name(s)' column missing.") | |
| with tab2: | |
| st.markdown("**Top 10 Songs:** Lists top songs.") | |
| if 'Track Name' in df.columns and 'Popularity' in df.columns: | |
| top_songs = df.nlargest(10, 'Popularity')[ | |
| ['Track Name', 'Popularity']] | |
| fig14 = px.pie( | |
| top_songs, values='Popularity', names='Track Name', | |
| title='Top 10 Songs by Popularity', color_discrete_sequence=px.colors.qualitative.Set3 | |
| ) | |
| fig14.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig14) | |
| else: | |
| st.error("Cannot plot: 'Track Name' or 'Popularity' column missing.") | |
| def generate_album_release_trends(df): | |
| st.header("Album Release Trends") | |
| tab1, tab2 = st.tabs(["Albums per Year", "Artist-Year Heatmap"]) | |
| with tab1: | |
| st.markdown("**Albums per Year:** Tracks release patterns.") | |
| if 'Year' in df.columns: | |
| albums_per_year = df['Year'].value_counts( | |
| ).sort_index().reset_index() | |
| fig15 = px.line(albums_per_year, x='Year', y='count', | |
| title='Number of Albums Released per Year', color_discrete_sequence=['purple']) | |
| fig15.update_layout(template='plotly_white', width=800, height=400) | |
| st.plotly_chart(fig15) | |
| else: | |
| st.error("Cannot plot: 'Year' column missing.") | |
| with tab2: | |
| st.markdown("**Songs by Artists and Years:** Visualizes trends.") | |
| if 'Artist Name(s)' in df.columns and 'Year' in df.columns: | |
| # Filter to only show the top 10 most featured artists | |
| top_artists = df['Artist Name(s)'].value_counts().nlargest( | |
| 10).index | |
| filtered_df = df[df['Artist Name(s)'].isin(top_artists)] | |
| # Grouping data | |
| artist_year = filtered_df.groupby( | |
| ['Year', 'Artist Name(s)']).size().reset_index(name='Count') | |
| # Create a grouped bar chart | |
| fig16 = px.bar( | |
| artist_year, x='Year', y='Count', color='Artist Name(s)', | |
| title='Songs Released by Top Artists Over the Years', | |
| labels={'Count': 'Number of Songs', 'Year': 'Year'}, | |
| barmode='group', # Grouped bars for each artist per year | |
| color_discrete_sequence=px.colors.qualitative.Set2 | |
| ) | |
| fig16.update_layout(width=900, height=500) | |
| st.plotly_chart(fig16) | |
| else: | |
| st.error("Cannot plot: 'Artist Name(s)' or 'Year' column missing.") | |
| def generate_duration_analysis(df): | |
| st.header("Track Duration Analysis") | |
| tab1, tab2 = st.tabs(["Distribution", "By Decade"]) | |
| # Filter out tracks longer than 900,000ms (15 minutes) | |
| df = df[df['Track Duration (ms)'] <= 900000] | |
| with tab1: | |
| st.markdown( | |
| "**Track Duration Distribution:** Illustrates how track durations vary, helping identify common song lengths.") | |
| if 'Track Duration (ms)' in df.columns: | |
| fig17 = px.histogram( | |
| df, x='Track Duration (ms)', | |
| title='Track Duration Distribution (Filtered)', | |
| nbins=50, | |
| color_discrete_sequence=['orange'] | |
| ) | |
| fig17.update_layout(template='plotly_white', width=800, height=400) | |
| st.plotly_chart(fig17) | |
| else: | |
| st.error("Cannot plot: 'Track Duration (ms)' column missing.") | |
| with tab2: | |
| st.markdown( | |
| "**Duration by Decade:** Compares the evolution of average track durations across decades, showing historical trends.") | |
| if 'Decade' in df.columns and 'Track Duration (ms)' in df.columns: | |
| fig18 = px.pie( | |
| df.groupby('Decade')[ | |
| 'Track Duration (ms)'].mean().reset_index(), | |
| names='Decade', values='Track Duration (ms)', | |
| title='Average Track Duration by Decade', | |
| color_discrete_sequence=px.colors.qualitative.Set2 | |
| ) | |
| fig18.update_layout(template='plotly_white', width=800, height=400) | |
| st.plotly_chart(fig18) | |
| else: | |
| st.error( | |
| "Cannot plot: 'Decade' or 'Track Duration (ms)' column missing.") | |
| def generate_streaming_insights(df): | |
| st.header("Streaming and Engagement Insights") | |
| tab1, tab2 = st.tabs(["Popularity vs Duration", "Time Signature"]) | |
| with tab1: | |
| st.markdown( | |
| "**Popularity vs Track Duration:** This line chart shows the trend of song popularity based on their duration.") | |
| if 'Track Duration (ms)' in df.columns and 'Popularity' in df.columns: | |
| df['Duration (minutes)'] = df['Track Duration (ms)'] / 60000 | |
| duration_bins = pd.cut(df['Duration (minutes)'], bins=[ | |
| 0, 2, 4, 6, 8, 10, 15], labels=['0-2', '2-4', '4-6', '6-8', '8-10', '10+']) | |
| avg_popularity = df.groupby(duration_bins)[ | |
| 'Popularity'].mean().reset_index() | |
| fig1 = px.line( | |
| avg_popularity, | |
| x='Duration (minutes)', | |
| y='Popularity', | |
| title='Popularity vs. Track Duration', | |
| markers=True, # Adds points to the line | |
| line_shape='spline', # Smoothens the line | |
| color_discrete_sequence=['blue'] | |
| ) | |
| fig1.update_layout( | |
| template='plotly_white', xaxis_title='Track Duration (Minutes)', yaxis_title='Average Popularity') | |
| st.plotly_chart(fig1) | |
| else: | |
| st.error( | |
| "Cannot plot: 'Track Duration (ms)' or 'Popularity' column missing.") | |
| with tab2: | |
| st.markdown( | |
| "**Popularity by Time Signature:** This bar chart compares the average popularity of songs based on their time signatures.") | |
| if 'Time Signature' in df.columns and 'Popularity' in df.columns: | |
| pop_by_time = df.groupby('Time Signature')[ | |
| 'Popularity'].mean().reset_index() | |
| fig2 = px.bar( | |
| pop_by_time, | |
| x='Time Signature', | |
| y='Popularity', | |
| title='Average Popularity by Time Signature', | |
| color='Popularity', | |
| color_continuous_scale='purples' | |
| ) | |
| fig2.update_layout( | |
| template='plotly_white', xaxis_title='Time Signature', yaxis_title='Average Popularity') | |
| st.plotly_chart(fig2) | |
| else: | |
| st.error( | |
| "Cannot plot: 'Time Signature' or 'Popularity' column missing.") | |
| def generate_feature_comparisons(df): | |
| st.header("Feature Comparisons Across Decades") | |
| tab1, tab2 = st.tabs(["Feature Comparison", "Loudness Trends"]) | |
| with tab1: | |
| st.markdown("**Feature Comparison:** Compares features across decades.") | |
| if 'Decade' in df.columns: | |
| features_by_decade = df.groupby( | |
| 'Decade')[['Danceability', 'Energy', 'Valence']].mean().reset_index() | |
| fig21 = px.bar(features_by_decade.melt(id_vars='Decade'), x='Decade', y='value', color='variable', | |
| barmode='group', title='Feature Comparison by Decade', color_discrete_sequence=px.colors.qualitative.Pastel) | |
| fig21.update_layout(template='plotly_white', width=800, height=400) | |
| st.plotly_chart(fig21) | |
| else: | |
| st.error("Cannot plot: 'Decade' column missing.") | |
| with tab2: | |
| st.markdown("**Loudness Over Time:** Tracks loudness trends.") | |
| if 'Year' in df.columns and 'Loudness' in df.columns: | |
| loudness_by_year = df.groupby( | |
| 'Year')['Loudness'].mean().reset_index() | |
| fig22 = px.line(loudness_by_year, x='Year', y='Loudness', | |
| title='Average Loudness Over Time', color_discrete_sequence=['green']) | |
| fig22.update_layout(template='plotly_white', width=800, height=400) | |
| st.plotly_chart(fig22) | |
| else: | |
| st.error("Cannot plot: 'Year' or 'Loudness' column missing.") | |
| def generate_top_artists_songs(df): | |
| st.header("Top Artists and Songs") | |
| tab1, tab2 = st.tabs(["Top Artists", "Top Songs"]) | |
| with tab1: | |
| st.markdown( | |
| "**Most Featured Artists:** Displays the top 10 artists with the highest song counts, highlighting their dominance in the dataset.") | |
| if 'Artist Name(s)' in df.columns: | |
| top_artists = df['Artist Name(s)'].value_counts().nlargest( | |
| 10).reset_index() | |
| top_artists.columns = ['Artist Name(s)', 'Count'] | |
| fig13 = px.sunburst( | |
| top_artists, path=['Artist Name(s)'], values='Count', | |
| title='Most Featured Artists', | |
| color='Count', | |
| color_continuous_scale='greens' | |
| ) | |
| fig13.update_layout(template='plotly_white', width=900, height=500) | |
| st.plotly_chart(fig13) | |
| else: | |
| st.error("Cannot plot: 'Artist Name(s)' column missing.") | |
| with tab2: | |
| st.markdown( | |
| "**Songs by Artists and Years:** Analyzes song release trends across different years, focusing on the top artists.") | |
| if 'Artist Name(s)' in df.columns and 'Year' in df.columns: | |
| artist_year = df.groupby( | |
| ['Artist Name(s)', 'Year']).size().reset_index(name='Count') | |
| fig16 = px.sunburst( | |
| artist_year, path=['Year', 'Artist Name(s)'], values='Count', | |
| title='Songs Released by Artists Over the Years', | |
| color='Count', | |
| color_continuous_scale=px.colors.qualitative.Set2 | |
| ) | |
| fig16.update_layout(width=900, height=500) | |
| st.plotly_chart(fig16) | |
| else: | |
| st.error("Cannot plot: 'Artist Name(s)' or 'Year' column missing.") | |
| def generate_network_analysis(df): | |
| st.header("Network Analysis") | |
| tab1, tab2 = st.tabs(["Artist Collaborations", "Genre Crossover"]) | |
| # Ensure column names are stripped of spaces | |
| df.columns = df.columns.str.strip() | |
| with tab1: | |
| st.markdown( | |
| "**Top Collaborating Artists:** This chart highlights artists who frequently collaborate with each other.") | |
| if 'Artist Name(s)' in df.columns: | |
| df['Artist Name(s)'] = df['Artist Name(s)'].astype( | |
| str).str.split(', ') | |
| collaborations = [] | |
| for artists in df['Artist Name(s)']: | |
| collaborations.extend(combinations(sorted(artists), 2)) | |
| collab_counts = Counter(collaborations) | |
| top_collabs = sorted(collab_counts.items(), | |
| key=lambda x: x[1], reverse=True)[:20] | |
| G = nx.Graph() | |
| for (artist1, artist2), weight in top_collabs: | |
| G.add_edge(artist1, artist2, weight=weight) | |
| pos = nx.spring_layout(G, seed=42) | |
| plt.figure(figsize=(12, 8)) | |
| edges = nx.draw_networkx_edges(G, pos, alpha=0.5, width=[ | |
| G[u][v]['weight'] for u, v in G.edges()]) | |
| nodes = nx.draw_networkx_nodes( | |
| G, pos, node_size=700, node_color='orange') | |
| labels = nx.draw_networkx_labels( | |
| G, pos, font_size=10, font_weight='bold') | |
| plt.title("Top 20 Artist Collaborations") | |
| st.pyplot(plt) | |
| else: | |
| st.error( | |
| "Cannot plot: 'Artist Name(s)' column missing. Available columns: " + ", ".join(df.columns)) | |
| with tab2: | |
| st.markdown( | |
| "**Genre Crossover:** This chart shows how different music genres are connected and often blend together.") | |
| if 'Genres' in df.columns: | |
| df['Genres'] = df['Genres'].astype(str).str.split(', ') | |
| genre_pairs = [] | |
| for genres in df['Genres']: | |
| genre_pairs.extend(combinations(sorted(set(genres)), 2)) | |
| genre_counts = Counter(genre_pairs) | |
| top_genre_pairs = sorted( | |
| genre_counts.items(), key=lambda x: x[1], reverse=True)[:20] | |
| labels = list(set(chain.from_iterable( | |
| [pair[0] for pair in top_genre_pairs]))) | |
| matrix = [[0] * len(labels) for _ in range(len(labels))] | |
| label_index = {label: i for i, label in enumerate(labels)} | |
| for (genre1, genre2), count in top_genre_pairs: | |
| i, j = label_index[genre1], label_index[genre2] | |
| matrix[i][j] = count | |
| matrix[j][i] = count | |
| fig = go.Figure(data=[go.Heatmap( | |
| z=matrix, x=labels, y=labels, colorscale='OrRd', text=matrix, hoverinfo='text')]) | |
| fig.update_layout(title="Genre Crossover Chord Diagram", | |
| xaxis_title="Genres", yaxis_title="Genres") | |
| st.plotly_chart(fig) | |
| else: | |
| st.error( | |
| "Cannot plot: 'Genres' column missing. Available columns: " + ", ".join(df.columns)) | |