Spaces:
Sleeping
Sleeping
Initial files
Browse files- app.py +133 -0
- requirements.txt +1 -0
app.py
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import spotipy
|
3 |
+
from spotipy.oauth2 import SpotifyClientCredentials
|
4 |
+
import pandas as pd
|
5 |
+
import matplotlib.pyplot as plt
|
6 |
+
import os
|
7 |
+
|
8 |
+
|
9 |
+
# Carica le credenziali di Spotify
|
10 |
+
SPOTIPY_CLIENT_ID = os.getenv("SPOTIPY_CLIENT_ID")
|
11 |
+
SPOTIPY_CLIENT_SECRET = os.getenv("SPOTIPY_CLIENT_SECRET")
|
12 |
+
auth_manager = SpotifyClientCredentials(client_id=SPOTIPY_CLIENT_ID, client_secret=SPOTIPY_CLIENT_SECRET)
|
13 |
+
sp = spotipy.Spotify(auth_manager=auth_manager)
|
14 |
+
|
15 |
+
def get_artist_info(artist_name):
|
16 |
+
artist = sp.search(q=artist_name, type='artist')['artists']['items'][0]
|
17 |
+
return {
|
18 |
+
'name': artist['name'],
|
19 |
+
'id': artist['id'],
|
20 |
+
'followers': artist['followers']['total'],
|
21 |
+
'popularity': artist['popularity'],
|
22 |
+
'genres': artist['genres'],
|
23 |
+
'image': artist['images'][0]['url'] if artist['images'] else None
|
24 |
+
}
|
25 |
+
|
26 |
+
def get_top_tracks(artist_id):
|
27 |
+
results = sp.artist_top_tracks(artist_id)
|
28 |
+
tracks = results['tracks'][:10] # Limit to top 10 tracks
|
29 |
+
return [{
|
30 |
+
'name': track['name'],
|
31 |
+
'album': track['album']['name'],
|
32 |
+
'artist': track['artists'][0]['name'],
|
33 |
+
'release_date': track['album']['release_date'],
|
34 |
+
'popularity': track['popularity'],
|
35 |
+
'album_cover': track['album']['images'][0]['url'] if track['album']['images'] else None,
|
36 |
+
'danceability': sp.audio_features(track['id'])[0]['danceability'] if sp.audio_features(track['id']) else 0,
|
37 |
+
'loudness': sp.audio_features(track['id'])[0]['loudness'] if sp.audio_features(track['id']) else 0,
|
38 |
+
'energy': sp.audio_features(track['id'])[0]['energy'] if sp.audio_features(track['id']) else 0,
|
39 |
+
'valence': sp.audio_features(track['id'])[0]['valence'] if sp.audio_features(track['id']) else 0,
|
40 |
+
'tempo': sp.audio_features(track['id'])[0]['tempo'] if sp.audio_features(track['id']) else 0,
|
41 |
+
'artist_id': artist_id
|
42 |
+
} for track in tracks]
|
43 |
+
|
44 |
+
def plot_features_comparison(data_tracks, artist1_info, artist2_info):
|
45 |
+
df = pd.DataFrame(data_tracks)
|
46 |
+
fig, ax = plt.subplots()
|
47 |
+
colors = {artist1_info['id']: 'blue', artist2_info['id']: 'red'}
|
48 |
+
|
49 |
+
for artist_id, group in df.groupby('artist_id'):
|
50 |
+
ax.scatter(group['danceability'], group['loudness'], alpha=0.7, label=group['artist'].iloc[0], c=colors[artist_id])
|
51 |
+
|
52 |
+
plt.title('Confronto Danceability vs. Loudness')
|
53 |
+
plt.xlabel('Danceability')
|
54 |
+
plt.ylabel('Loudness (dB)')
|
55 |
+
plt.legend(title='Artist')
|
56 |
+
st.pyplot(fig)
|
57 |
+
|
58 |
+
def plot_audio_features_boxplot(data_tracks, artist1_name, artist2_name):
|
59 |
+
df = pd.DataFrame(data_tracks)
|
60 |
+
fig, axs = plt.subplots(1, 4, figsize=(20, 5)) # 1 riga, 4 colonne per 4 features
|
61 |
+
features = ['danceability', 'energy', 'valence', 'tempo']
|
62 |
+
for i, feature in enumerate(features):
|
63 |
+
ax = axs[i]
|
64 |
+
artist1_data = df[df['artist'] == artist1_name][feature]
|
65 |
+
artist2_data = df[df['artist'] == artist2_name][feature]
|
66 |
+
ax.boxplot([artist1_data, artist2_data], labels=[artist1_name, artist2_name])
|
67 |
+
ax.set_title(f'Distribution of {feature}')
|
68 |
+
ax.set_ylabel(feature)
|
69 |
+
|
70 |
+
plt.tight_layout()
|
71 |
+
st.pyplot(fig)
|
72 |
+
|
73 |
+
def plot_audio_features_violinplot(data_tracks, artist1_name, artist2_name):
|
74 |
+
df = pd.DataFrame(data_tracks)
|
75 |
+
fig, axs = plt.subplots(1, 4, figsize=(20, 5)) # 1 riga, 4 colonne per 4 features
|
76 |
+
features = ['danceability', 'energy', 'valence', 'tempo']
|
77 |
+
for i, feature in enumerate(features):
|
78 |
+
ax = axs[i]
|
79 |
+
data_to_plot = [df[df['artist'] == artist1_name][feature], df[df['artist'] == artist2_name][feature]]
|
80 |
+
ax.violinplot(data_to_plot)
|
81 |
+
ax.set_xticks([1, 2])
|
82 |
+
ax.set_xticklabels([artist1_name, artist2_name])
|
83 |
+
ax.set_title(f'Distribution of {feature}')
|
84 |
+
ax.set_ylabel(feature)
|
85 |
+
|
86 |
+
plt.tight_layout()
|
87 |
+
st.pyplot(fig)
|
88 |
+
|
89 |
+
def show_average_features(data_tracks):
|
90 |
+
df = pd.DataFrame(data_tracks)
|
91 |
+
numeric_columns = ['loudness', 'danceability', 'energy', 'valence', 'tempo', 'artist']
|
92 |
+
df = df[numeric_columns]
|
93 |
+
average_features = df.groupby('artist').mean()[['loudness', 'danceability', 'energy', 'valence', 'tempo']]
|
94 |
+
st.write("Media delle Caratteristiche Audio per Artista:")
|
95 |
+
st.dataframe(average_features)
|
96 |
+
|
97 |
+
def main():
|
98 |
+
st.title("Confronto Artisti su Spotify")
|
99 |
+
|
100 |
+
artist1_name = st.text_input("Inserisci il nome del primo artista")
|
101 |
+
artist2_name = st.text_input("Inserisci il nome del secondo artista")
|
102 |
+
|
103 |
+
if st.button("Confronta"):
|
104 |
+
if artist1_name and artist2_name:
|
105 |
+
artist1_info = get_artist_info(artist1_name)
|
106 |
+
artist2_info = get_artist_info(artist2_name)
|
107 |
+
artist1_tracks = get_top_tracks(artist1_info['id'])
|
108 |
+
artist2_tracks = get_top_tracks(artist2_info['id'])
|
109 |
+
data_tracks = artist1_tracks + artist2_tracks
|
110 |
+
|
111 |
+
col1, col2 = st.columns(2)
|
112 |
+
with col1:
|
113 |
+
st.image(artist1_info['image'], caption=artist1_info['name'])
|
114 |
+
st.markdown(f"**Nome:** {artist1_info['name']}")
|
115 |
+
st.markdown(f"**Follower:** {artist1_info['followers']:,}")
|
116 |
+
st.markdown(f"**Popolarità:** {artist1_info['popularity']}")
|
117 |
+
st.markdown(f"**Generi:** {', '.join(artist1_info['genres'])}")
|
118 |
+
with col2:
|
119 |
+
st.image(artist2_info['image'], caption=artist2_info['name'])
|
120 |
+
st.markdown(f"**Nome:** {artist1_info['name']}")
|
121 |
+
st.markdown(f"**Follower:** {artist2_info['followers']:,}")
|
122 |
+
st.markdown(f"**Popolarità:** {artist2_info['popularity']}")
|
123 |
+
st.markdown(f"**Generi:** {', '.join(artist2_info['genres'])}")
|
124 |
+
show_average_features(data_tracks)
|
125 |
+
plot_features_comparison(data_tracks, artist1_info, artist2_info)
|
126 |
+
plot_audio_features_boxplot(data_tracks, artist1_info['name'], artist1_info['name'])
|
127 |
+
plot_audio_features_violinplot(data_tracks, artist1_info['name'], artist1_info['name'])
|
128 |
+
|
129 |
+
else:
|
130 |
+
st.error("Per favore inserisci i nomi di entrambi gli artisti.")
|
131 |
+
|
132 |
+
if __name__ == "__main__":
|
133 |
+
main()
|
requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
spotipy
|