DataViz.manishdatt.com

Billboard Hot 100 Number Ones

Keys for Billboard hits over the years.

By Manish Datt

TidyTuesday dataset of 2025-08-26

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
billboard = pd.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2025/2025-08-26/billboard.csv')
topics = pd.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2025/2025-08-26/topics.csv')
billboard

song artist date weeks_at_number_one non_consecutive rating_1 rating_2 rating_3 overall_rating divisiveness ... featured_in_a_then_contemporary_play written_for_a_film featured_in_a_then_contemporary_film written_for_a_t_v_show featured_in_a_then_contemporary_t_v_show associated_with_dance topped_the_charts_by_multiple_artist double_a_side eurovision_entry u_s_artwork
0 Poor Little Fool Ricky Nelson 1958-08-04T00:00:00Z 2 0 4 5 3 4.000000 1.333333 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Cannot Locate
1 Nel Blu Dipinto Di Blu Domenico Modugno 1958-08-18T00:00:00Z 5 1 7 7 5 6.333333 1.333333 ... NaN 0 NaN 0 NaN 0 0 NaN 1 Cannot Locate
2 Little Star The Elegants 1958-08-25T00:00:00Z 1 0 5 6 6 5.666667 0.666667 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Cannot Locate
3 It's All in the Game Tommy Edwards 1958-09-29T00:00:00Z 6 0 3 3 7 4.333333 2.666667 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Cannot Locate
4 It's Only Make Believe Conway Twitty 1958-11-10T00:00:00Z 2 1 7 8 9 8.000000 1.333333 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Cannot Locate
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1172 Please Please Please Sabrina Carpenter 2024-06-29T00:00:00Z 1 0 8 7 8 7.666667 0.666667 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Artist Photograph
1173 A Bar Song (Tipsy) Shaboozey 2024-07-13T00:00:00Z 19 1 6 4 9 6.333333 3.333333 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Artist Photograph;Photograph Related to Song T...
1174 Love Somebody Morgan Wallen 2024-11-02T00:00:00Z 1 0 3 5 5 4.333333 1.333333 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Photograph Not Related to Song
1175 squabble up Kendrick Lamar 2024-12-07T00:00:00Z 1 0 9 10 9 9.333333 0.666667 ... NaN 0 NaN 0 NaN 0 0 NaN 0 NaN
1176 Die with a Smile Bruno Mars & Lady Gaga 2025-01-11T00:00:00Z 2 0 8 7 4 6.333333 2.666667 ... NaN 0 NaN 0 NaN 0 0 NaN 0 Artist Photograph;Text

1177 rows × 105 columns

billboard.columns.values

array(['song', 'artist', 'date', 'weeks_at_number_one', 'non_consecutive',
'rating_1', 'rating_2', 'rating_3', 'overall_rating',
'divisiveness', 'label', 'parent_label', 'cdr_genre', 'cdr_style',
'discogs_genre', 'discogs_style', 'artist_structure',
'featured_artists', 'multiple_lead_vocalists',
'group_named_after_non_lead_singer', 'talent_contestant',
'posthumous', 'artist_place_of_origin', 'front_person_age',
'artist_male', 'artist_white', 'artist_black', 'songwriters',
'songwriters_w_o_interpolation_sample_credits', 'songwriter_male',
'songwriter_white', 'artist_is_a_songwriter',
'artist_is_only_songwriter', 'producers', 'producer_male',
'producer_white', 'artist_is_a_producer',
'artist_is_only_producer', 'songwriter_is_a_producer',
'time_signature', 'keys', 'simplified_key', 'bpm', 'energy',
'danceability', 'happiness', 'loudness_d_b', 'acousticness',
'vocally_based', 'bass_based', 'guitar_based',
'piano_keyboard_based', 'orchestral_strings', 'horns_winds',
'accordion', 'banjo', 'bongos', 'clarinet', 'cowbell',
'falsetto_vocal', 'flute_piccolo', 'handclaps_snaps', 'harmonica',
'human_whistling', 'kazoo', 'mandolin', 'pedal_lap_steel',
'ocarina', 'saxophone', 'sitar', 'trumpet', 'ukulele', 'violin',
'sound_effects', 'song_structure', 'rap_verse_in_a_non_rap_song',
'length_sec', 'instrumental', 'instrumental_length_sec',
'intro_length_sec', 'vocal_introduction',
'free_time_vocal_introduction', 'fade_out', 'live', 'cover',
'sample', 'interpolation', 'inspired_by_a_different_song',
'lyrics', 'lyrical_topic', 'lyrical_narrative', 'spoken_word',
'explicit', 'foreign_language', 'written_for_a_play',
'featured_in_a_then_contemporary_play', 'written_for_a_film',
'featured_in_a_then_contemporary_film', 'written_for_a_t_v_show',
'featured_in_a_then_contemporary_t_v_show',
'associated_with_dance', 'topped_the_charts_by_multiple_artist',
'double_a_side', 'eurovision_entry', 'u_s_artwork'], dtype=object)

billboard['date'] = pd.to_datetime(billboard['date'])
# add a new  col date2 having three categories Before 75, 75-2000, After 2000
billboard['date2'] = pd.cut(billboard['date'].dt.year, bins=[0, 1975, 2000, 2025], labels=['Before 1975', '1975-2000', 'After 2000'])
billboard['date2'].value_counts()

date2
1975-2000 484
Before 1975 383
After 2000 310
Name: count, dtype: int64

billboard['simplified_key_mod'] = billboard['simplified_key'].replace('Multiple Keys', 'multi')
sk_values = billboard['simplified_key_mod'].value_counts()
sk_values

simplified_key_mod
C 120
multi 96
G 83
F 76
D 70
E 69
A 67
Db 57
Ab 49
Bb 48
Eb 42
Am 40
Fm 34
Cm 32
Gm 31
Dbm 29
Dm 29
Gb 29
B 29
Bbm 28
Em 27
Ebm 26
Bm 25
Gbm 21
Abm 20
Name: count, dtype: int64

fig,ax = plt.subplots(figsize=(10,5))

sns.swarmplot(data=billboard, x='date2', y='simplified_key_mod', hue='weeks_at_number_one', \
ax=ax, alpha=0.75)
ax.legend(loc='lower center', ncol=6, bbox_to_anchor=(0.5, -0.2), \
frameon=False, title="")
ax.text(-0.55,29.4, "Weeks at Number One →")
sns.despine(bottom=True)
ax.tick_params(axis='x', which='both', length=0)

plt.xlabel('')
plt.ylabel('Key (simplified)')
plt.title("Changing key preference over the years in Billboard hits.", fontfamily='serif', \
         fontsize=14)
plt.savefig('billboard_hits.png', dpi=300, bbox_inches='tight')
plt.show()

sns.pairplot(billboard[['bpm', 'energy','danceability', 'happiness','weeks_at_number_one']], hue='weeks_at_number_one',\
corner=True)
plt.show()

Update

A revised visualization for this data was submitted to Plotnine contest 2025 (Repo).

Plot