import requests
import pandas as pd
import re
from datetime import datetime, timedelta
from bs4 import BeautifulSoup as bs
import numpy as np
import time
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
from adjustText import adjust_text
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept-Language': 'fr-FR,fr;q=0.9,en;q=0.8',
'Referer': 'https://www.allocine.fr/'
}
print('On fait du webscrapping du site cine-directors.net pour sortir les films de 2025')
columns = ['Rang', 'NbSemaine', 'Titre', 'Entrées', 'Variation', 'Cumul', 'Budget', 'NbCopies', 'MoyCopies']
data = []
for idx in range(52):
url = f"http://www.cine-directors.net/box/2025/boxoff{str(idx+1).zfill(2)}.html"
page = requests.get(url, headers=headers)
soup = bs(page.content, 'lxml')
tbody = soup.find('tbody').find_next('tbody')
rows = tbody.find_all('tr')[4:]
rang = 1
for row in rows:
cells = row.find_all('td')
if len(cells) == 9:
row_data = {}
for i, col in enumerate(columns):
row_data[col] = cells[i].get_text().strip()
text = tbody.find('table').find('td').get_text().strip()
cleaned = ' '.join(text.split())
match = re.search(r'du\s+(.+?)\)', cleaned)
row_data['Date'] = match.group(1) if match else None
row_data['Rang2'] = rang
rang += 1
data.append(row_data)
BoxOffice = pd.DataFrame(data)
On fait du webscrapping du site cine-directors.net pour sortir les films de 2025
#Nous allons procéder au nettoyage du DataFrame
#Lorsque le rang est null, on supprime la ligne
BoxOffice = BoxOffice[BoxOffice['Rang']!='']
BoxOffice = BoxOffice.drop(columns='Rang').rename(columns={'Rang2': 'Rang'})
cols = ['Rang'] + [col for col in BoxOffice.columns if col != 'Rang']
BoxOffice = BoxOffice[cols]
#Nous remarquons que pour certains films, nous avons des doublons, car des films ont (FT) en fin de titre
BoxOffice = BoxOffice.replace(r' +\(FT\)', '', regex=True)
#On nettoie la colonne NbCopies et on la transforme en int
BoxOffice['NbCopies'] = BoxOffice['NbCopies'].str.replace(' ', '')
BoxOffice['NbCopies']= BoxOffice['NbCopies'].replace(['?','-',''], np.nan)
BoxOffice['NbCopies']= BoxOffice['NbCopies'].astype('Int64')
#On nettoie la colonne MoyCopies et on la transforme en int
BoxOffice['MoyCopies'] = BoxOffice['MoyCopies'].str.replace(' ', '')
BoxOffice['MoyCopies'] = BoxOffice['MoyCopies'].replace(['?','-',''], np.nan)
BoxOffice['MoyCopies'] = BoxOffice['MoyCopies'].astype('Int64')
#On nettoie la colonne Entrées et on la transforme en int
BoxOffice['Entrées'] = BoxOffice['Entrées'].str.replace(' ', '')
BoxOffice['Entrées'] = BoxOffice['Entrées'].replace('77entrées', '77')
BoxOffice['Entrées'] = BoxOffice['Entrées'].replace(['?','-',''], np.nan)
BoxOffice['Entrées'] = BoxOffice['Entrées'].astype('Int64')
#On nettoie la colonne Cumul, on la transforme en int et on multiplie par 1000 pour avoir le bon nombre
#On modifie le cumul d'un film car il y a une coquille sur le site
BoxOffice['Cumul'] = BoxOffice['Cumul'].str.replace(',','')
BoxOffice['Cumul'] = BoxOffice['Cumul'].astype('Int64')*1000
BoxOffice.loc[(BoxOffice['Titre'] == 'Demon slayer : La forteresse infinie - Film 1') & (BoxOffice['Rang'] == '1'),'Cumul']/=10
#On nettoie la colonne Budget. On fait d'un côté les dollars car il faut transformer la devise en euro.
mask2 = ~BoxOffice['Budget'].str.contains('M\$', regex=True, na=False)
BoxOffice.loc[mask2, 'Budget'] = BoxOffice.loc[mask2, 'Budget'].str.replace(' M\€', '', regex=True).str.replace(',','.').replace('-',np.nan).replace('- M£',np.nan).replace('',np.nan)
mask = BoxOffice['Budget'].str.contains('M\$', regex=True, na=False)
BoxOffice.loc[mask, 'Budget'] = (BoxOffice.loc[mask, 'Budget'].str.replace(' M\$', '', regex=True).replace('-',np.nan).str.replace(',','.'))
BoxOffice['Budget'] = BoxOffice['Budget'].astype(float)
BoxOffice['Budget'] = BoxOffice['Budget']*1000000
BoxOffice.loc[mask, 'Budget'] = BoxOffice.loc[mask, 'Budget'] * 1.20
#On modifie le type du Nombre de semaine
BoxOffice['NbSemaine'] = BoxOffice['NbSemaine'].astype(int)
#On rajoute une colonne où l'on va calculer le ratio entre le nombre total d'entrée d'un film avec son budget
BoxOffice['Ratio'] = BoxOffice['Cumul']/BoxOffice['Budget']
#Nous avons des films qui sont sorties avant 2025, donc on va créer une nouvelle colonne pour les pointer
Inter = BoxOffice.drop_duplicates(subset ='Titre')
TitreAPrendre = Inter.loc[Inter['Entrées'] == Inter['Cumul'],'Titre']
BoxOffice['En2025'] = BoxOffice['Titre'].isin(TitreAPrendre).map({True: 'Oui', False: 'Non'})
#BoxOffice = BoxOffice[BoxOffice['Titre'].isin(TitreAPrendre)]
print('On regarde les 5 premières lignes du tableau')
BoxOffice.head()
On regarde les 5 premières lignes du tableau
| Rang | NbSemaine | Titre | Entrées | Variation | Cumul | Budget | NbCopies | MoyCopies | Date | Ratio | En2025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 3 | Mufasa : Le roi lion | 986000 | - 28 % | 3574000 | 240000000.0 | 951 | 1037 | 1er au 7 janvier 2025 | 0.014892 | Non |
| 1 | 2 | 2 | Sonic 3, le film | 655000 | - 47 % | 1879000 | 146400000.0 | 772 | 848 | 1er au 7 janvier 2025 | 0.012835 | Non |
| 2 | 3 | 6 | Vaiana 2 | 557000 | - 43 % | 7506000 | 180000000.0 | 1063 | 524 | 1er au 7 janvier 2025 | 0.0417 | Non |
| 3 | 4 | 1 | Un ours dans le Jura | 453000 | New | 453000 | 12100000.0 | 580 | 782 | 1er au 7 janvier 2025 | 0.037438 | Oui |
| 4 | 5 | 6 | En fanfare | 244000 | - 19 % | 1854000 | 6100000.0 | 642 | 379 | 1er au 7 janvier 2025 | 0.303934 | Non |
print('On regarde les infos du tableau')
BoxOffice.info()
On regarde les infos du tableau <class 'pandas.core.frame.DataFrame'> Int64Index: 1368 entries, 0 to 1418 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Rang 1368 non-null int64 1 NbSemaine 1368 non-null int32 2 Titre 1368 non-null object 3 Entrées 1367 non-null Int64 4 Variation 1368 non-null object 5 Cumul 1368 non-null Int64 6 Budget 1070 non-null float64 7 NbCopies 1361 non-null Int64 8 MoyCopies 1361 non-null Int64 9 Date 1368 non-null object 10 Ratio 1368 non-null Float64 11 En2025 1368 non-null object dtypes: Float64(1), Int64(4), float64(1), int32(1), int64(1), object(4) memory usage: 140.3+ KB
print('Nous pouvons maintenant répondre à un certain nombre de questions')
Nous pouvons maintenant répondre à un certain nombre de questions
print('Nous pouvons avoir un premier aperçu des statistiques descriptives du DataFrame')
BoxOffice.describe()
Nous pouvons avoir un premier aperçu des statistiques descriptives du DataFrame
| Rang | NbSemaine | Entrées | Cumul | Budget | NbCopies | MoyCopies | Ratio | |
|---|---|---|---|---|---|---|---|---|
| count | 1368.000000 | 1368.000000 | 1.367000e+03 | 1.368000e+03 | 1.070000e+03 | 1361.000000 | 1361.000000 | 1368 |
| mean | 13.691520 | 3.521199 | 9.684157e+04 | 6.798260e+05 | 6.023672e+07 | 416.080088 | 215.566495 | NaN |
| std | 7.657912 | 2.890008 | 1.815052e+05 | 1.229805e+06 | 8.966206e+07 | 222.187540 | 274.058308 | <NA> |
| min | 1.000000 | 1.000000 | 0.000000e+00 | 6.000000e+03 | 5.200000e+05 | 24.000000 | 3.000000 | NaN |
| 25% | 7.000000 | 2.000000 | 2.200000e+04 | 9.475000e+04 | 5.500000e+06 | 242.000000 | 76.000000 | 0.0075 |
| 50% | 14.000000 | 3.000000 | 4.500000e+04 | 2.555000e+05 | 1.540000e+07 | 379.000000 | 137.000000 | 0.016032 |
| 75% | 20.000000 | 5.000000 | 1.000000e+05 | 6.807500e+05 | 7.200000e+07 | 553.000000 | 261.000000 | 0.042186 |
| max | 30.000000 | 25.000000 | 2.541000e+06 | 1.451000e+07 | 4.800000e+08 | 1377.000000 | 3490.000000 | NaN |
print("Quel est le nombre d'entrées en 2025 ?")
print("Le nombre d'entrées en 2025 est de ",BoxOffice['Entrées'].sum())
Quel est le nombre d'entrées en 2025 ? Le nombre d'entrées en 2025 est de 132382420
print("Quels films ont fait le plus d'entrées en une semaine ?")
BoxOffice[['Titre','Entrées','NbSemaine','Date']].dropna(subset='Entrées').sort_values('Entrées', ascending=False).head(10)
Quels films ont fait le plus d'entrées en une semaine ?
| Titre | Entrées | NbSemaine | Date | |
|---|---|---|---|---|
| 1367 | Avatar : De feu et de cendres | 2541000 | 1 | 17 au 23 décembre 2025 |
| 1393 | Avatar : De feu et de cendres | 2516000 | 2 | 24 au 30 décembre 2025 |
| 1283 | Zootopie 2 | 1736000 | 1 | 26 novembre au 2 décembre 2025 |
| 579 | Lilo & Stitch | 1349000 | 2 | 28 mai au 3 juin 2025 |
| 553 | Lilo & Stitch | 1325000 | 1 | 21 au 27 mai 2025 |
| 1394 | La femme de ménage | 1312000 | 1 | 24 au 30 décembre 2025 |
| 1368 | Zootopie 2 | 1284000 | 4 | 17 au 23 décembre 2025 |
| 1395 | Zootopie 2 | 1269000 | 5 | 24 au 30 décembre 2025 |
| 1309 | Zootopie 2 | 1269000 | 2 | 3 au 9 décembre 2025 |
| 977 | The conjuring : l'heure du jugement | 1109000 | 1 | 10 au 16 septembre 2025 |
print("Quels films ont fait le plus d'entrée en 2025 (exclusivement des films sortis en 2025) ?")
BoxOffice[BoxOffice['En2025'] == "Oui"][['Titre','Cumul','NbSemaine','Date']].dropna(subset='Cumul').sort_values('Cumul', ascending=False).drop_duplicates(subset='Titre').head(10)
Quels films ont fait le plus d'entrée en 2025 (exclusivement des films sortis en 2025) ?
| Titre | Cumul | NbSemaine | Date | |
|---|---|---|---|---|
| 1395 | Zootopie 2 | 6547000 | 5 | 24 au 30 décembre 2025 |
| 920 | Lilo & Stitch | 5137000 | 14 | 20 au 26 août 2025 |
| 1393 | Avatar : De feu et de cendres | 5057000 | 2 | 24 au 30 décembre 2025 |
| 1059 | F1 | 3290000 | 14 | 24 au 30 septembre 2025 |
| 1000 | Jurassic world : Renaissance | 3009000 | 11 | 10 au 16 septembre 2025 |
| 381 | God save the Tuche | 2986000 | 9 | 2 au 8 avril 2025 |
| 659 | Minecraft, le film | 2614000 | 11 | 11 au 17 juin 2025 |
| 946 | Dragons | 2569000 | 12 | 27 août au 2 septembre 2025 |
| 815 | Mission : Impossible - The final reckoning | 2462000 | 10 | 23 au 29 juillet 2025 |
| 1166 | The conjuring : l'heure du jugement | 2254000 | 7 | 22 au 28 octobre 2025 |
print("Quels films sont restés le plus longtemps au cinéma (exclusivement des films sortis en 2025) ?")
BoxOffice[BoxOffice['En2025'] == "Oui"][['Titre','NbSemaine']].sort_values('NbSemaine', ascending=False).drop_duplicates('Titre').head(10)
Quels films sont restés le plus longtemps au cinéma (exclusivement des films sortis en 2025) ?
| Titre | NbSemaine | |
|---|---|---|
| 1059 | F1 | 14 |
| 920 | Lilo & Stitch | 14 |
| 946 | Dragons | 12 |
| 659 | Minecraft, le film | 11 |
| 1000 | Jurassic world : Renaissance | 11 |
| 1114 | Les bad guys 2 | 11 |
| 921 | Elio | 10 |
| 815 | Mission : Impossible - The final reckoning | 10 |
| 574 | Ma mère, Dieu et Sylvie Vartan | 10 |
| 684 | Sinners | 10 |
print("Quels films ont le plus grand nombre de copies en une semaine (exclusivement des films sortis en 2025) ?")
BoxOffice[BoxOffice['En2025'] == "Oui"][['Titre','NbCopies','Date']].dropna(subset='NbCopies').sort_values('NbCopies', ascending=False).head(10)
Quels films ont le plus grand nombre de copies en une semaine (exclusivement des films sortis en 2025) ?
| Titre | NbCopies | Date | |
|---|---|---|---|
| 1395 | Zootopie 2 | 1377 | 24 au 30 décembre 2025 |
| 1368 | Zootopie 2 | 1275 | 17 au 23 décembre 2025 |
| 717 | Dragons | 1126 | 2 au 8 juillet 2025 - Fête du cinéma bis |
| 746 | Elio | 1104 | 9 au 15 juillet 2025 |
| 744 | Dragons | 1084 | 9 au 15 juillet 2025 |
| 662 | Lilo & Stitch | 1083 | 18 au 24 juin 2025 |
| 443 | Minecraft, le film | 1081 | 23 au 29 avril 2025 |
| 898 | Les bad guys 2 | 1071 | 20 au 26 août 2025 |
| 774 | Elio | 1060 | 16 au 22 juillet 2025 |
| 795 | Jurassic world : Renaissance | 1059 | 23 au 29 juillet 2025 |
print('Quels films ont le plus moins de copies (exclusivement des films sortis en 2025) ?')
BoxOffice[BoxOffice['En2025'] == "Oui"][['Titre','NbCopies','Date']].dropna(subset='NbCopies').sort_values('NbCopies', ascending=False).tail(10)
Quels films ont le plus moins de copies (exclusivement des films sortis en 2025) ?
| Titre | NbCopies | Date | |
|---|---|---|---|
| 889 | Coolie | 67 | 13 au 19 août 2025 |
| 922 | Coolie | 67 | 20 au 26 août 2025 |
| 497 | Ne zha 2 | 61 | 30 avril au 6 mai 2025 |
| 652 | Le rendez-vous de l'été | 56 | 11 au 17 juin 2025 |
| 43 | Personne n'y comprend rien | 52 | 8 au 14 janvier 2025 |
| 626 | Zion | 49 | 4 au 10 juin 2025 |
| 624 | Jardin d'été | 26 | 4 au 10 juin 2025 |
| 686 | Thunderbolts* | 26 | 18 au 24 juin 2025 |
| 684 | Sinners | 26 | 18 au 24 juin 2025 |
| 685 | Until dawn | 24 | 18 au 24 juin 2025 |
print("Quels films ont le plus grand nombre de moyenne de copies (exclusivement des films sortis en 2025) ?")
BoxOffice[BoxOffice['En2025'] == "Oui"][['Titre','MoyCopies','Date']].dropna(subset='MoyCopies').sort_values('MoyCopies', ascending=False).head(10)
Quels films ont le plus grand nombre de moyenne de copies (exclusivement des films sortis en 2025) ?
| Titre | MoyCopies | Date | |
|---|---|---|---|
| 1367 | Avatar : De feu et de cendres | 3490 | 17 au 23 décembre 2025 |
| 1393 | Avatar : De feu et de cendres | 3118 | 24 au 30 décembre 2025 |
| 1283 | Zootopie 2 | 2691 | 26 novembre au 2 décembre 2025 |
| 977 | The conjuring : l'heure du jugement | 2526 | 10 au 16 septembre 2025 |
| 553 | Lilo & Stitch | 2246 | 21 au 27 mai 2025 |
| 579 | Lilo & Stitch | 2212 | 28 mai au 3 juin 2025 |
| 1394 | La femme de ménage | 2140 | 24 au 30 décembre 2025 |
| 1309 | Zootopie 2 | 1888 | 3 au 9 décembre 2025 |
| 389 | Zion | 1833 | 9 au 15 avril 2025 |
| 689 | F1 | 1735 | 25 juin au 1er juillet 2025 |
print("Quels films ont le meilleur ratio Entrées/Budget (exclusivement des films sortis en 2025) ?")
BoxOffice[BoxOffice['En2025'] == "Oui"][['Titre','Cumul','Budget','Ratio']].dropna(subset='Budget').sort_values('Ratio', ascending = False).drop_duplicates(subset='Titre').head(10)
Quels films ont le meilleur ratio Entrées/Budget (exclusivement des films sortis en 2025) ?
| Titre | Cumul | Budget | Ratio | |
|---|---|---|---|---|
| 378 | A bicyclette ! | 525000 | 520000.0 | 1.009615 |
| 1280 | Sacré-coeur | 455000 | 690000.0 | 0.65942 |
| 1194 | Un simple accident | 620000 | 1000000.0 | 0.62 |
| 1398 | Le chant des forêts | 409000 | 1200000.0 | 0.340833 |
| 1025 | La nuit des clowns | 306000 | 1200000.0 | 0.255 |
| 1170 | Sirat | 673000 | 3000000.0 | 0.224333 |
| 1363 | La femme le plus riche du monde | 900000 | 4200000.0 | 0.214286 |
| 409 | On ira | 483000 | 3000000.0 | 0.161 |
| 381 | God save the Tuche | 2986000 | 19400000.0 | 0.153918 |
| 626 | Zion | 460000 | 3300000.0 | 0.139394 |
print("Quels films ont les pire ratio Cumul/Budget (exclusivement des films sortis en 2025) ?")
BoxOffice[BoxOffice['En2025'] == "Oui"][['Titre','Cumul','Budget','Ratio']].sort_values('Ratio').drop_duplicates(subset='Titre').head(10)
Quels films ont les pire ratio Cumul/Budget (exclusivement des films sortis en 2025) ?
| Titre | Cumul | Budget | Ratio | |
|---|---|---|---|---|
| 456 | Ne zha 2 | 46000 | 96000000.0 | 0.000479 |
| 258 | In the lost lands | 32000 | 66000000.0 | 0.000485 |
| 1079 | A big bold beautiful journey | 35000 | 54000000.0 | 0.000648 |
| 1094 | Tron : Ares | 200000 | 216000000.0 | 0.000926 |
| 664 | Elio | 168000 | 180000000.0 | 0.000933 |
| 1191 | Smashing machine | 57000 | 60000000.0 | 0.00095 |
| 82 | Better man | 142000 | 132000000.0 | 0.001076 |
| 1161 | Springsteen : Deliver me from nowhere | 76000 | 66000000.0 | 0.001152 |
| 108 | Toutes pour une | 12000 | 9900000.0 | 0.001212 |
| 1256 | Wicked : Partie 2 | 252000 | 180000000.0 | 0.0014 |
print("Quels films sont restés le plus longtemps en top 1 du box office ?")
BoxOfficeRang = BoxOffice[BoxOffice['Rang']==1].copy()
result = BoxOfficeRang.groupby('Titre')['Rang'].agg('sum').sort_values(ascending = False)
result[result == result.max()]
Quels films sont restés le plus longtemps en top 1 du box office ?
Titre Mufasa : Le roi lion 4 Minecraft, le film 4 Les bad guys 2 4 God save the Tuche 4 Name: Rang, dtype: int64
print('Quels films ont le meilleur ratio Budget/Cumul des entrées ?')
print("On regarde les films avec le meilleur Cumul, puis Budget, et on prend les 20 premiers films")
print("On a rajouté une courbe de tendance")
bo = BoxOffice[BoxOffice['En2025'] == "Oui"].sort_values(['Cumul','Budget'], ascending=False).drop_duplicates(subset='Titre', keep='first').head(20).copy()
bo['Cumul'] = bo['Cumul'].astype(float)
bo['Budget'] = bo['Budget'].astype(float)
fig, ax = plt.subplots(figsize=(18, 11))
sns.regplot(data=bo, x='Budget', y='Cumul', ci=None, ax=ax,
scatter_kws={'s': 300, 'alpha': 0.7, 'edgecolor': 'black', 'linewidth': 1.5, 'zorder': 3},
line_kws={'color': 'red', 'linewidth': 2.5, 'linestyle': '--', 'alpha': 0.6})
# Créer les textes avec style amélioré
texts = []
for idx, row in bo.iterrows():
texts.append(ax.text(row['Budget'], row['Cumul'], row['Titre'],
fontsize=10, # Taille augmentée
fontweight='bold', # Gras
alpha=0.95,
bbox=dict(boxstyle='round,pad=0.5',
facecolor='white',
edgecolor='lightgray',
alpha=0.85,
linewidth=0.8)))
# Ajuster avec paramètres corrigés pour éviter le warning
adjust_text(texts,
ax=ax, # Important: spécifier l'axe
arrowprops=dict(arrowstyle='->',
color='gray',
lw=0.8,
alpha=0.6,
shrinkA=5, # Évite que les flèches traversent le texte
shrinkB=5),
expand_points=(1.8, 1.8),
expand_text=(1.2, 1.2),
force_text=(0.7, 0.7),
force_points=(0.5, 0.5))
ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, p: f'{x/1e6:.0f}M'))
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, p: f'{x/1e6:.0f}M'))
ax.set_facecolor('#f8f9fa')
ax.grid(True, alpha=0.3, linestyle='--', linewidth=0.6)
ax.set_title('Budget vs Cumul des entrées avec tendance',
fontsize=20, fontweight='bold', pad=25)
ax.set_xlabel('Budget (millions €)', fontsize=15, fontweight='bold')
ax.set_ylabel('Cumul des entrées (millions)', fontsize=15, fontweight='bold')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
plt.show()
Quels films ont le meilleur ratio Budget/Cumul des entrées ? On regarde les films avec le meilleur Cumul, puis Budget, et on prend les 20 premiers films On a rajouté une courbe de tendance
print("Quels films sont dans le top 20 des films en terme d'entrées?")
bo = BoxOffice[BoxOffice['En2025'] == "Oui"].sort_values(['Cumul','NbSemaine'], ascending=False).drop_duplicates(subset='Titre').head(20)
plt.figure(figsize=(16, 7))
# Barplot avec palette dégradée
sns.barplot(data=bo, x='Titre', y='Cumul',
palette='rocket_r', edgecolor='black', linewidth=0.5)
# Formater l'axe Y
ax = plt.gca()
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, p: f'{x/1e6:.1f}M'))
ax = plt.gca()
for container in ax.containers:
labels = [f'{v/1e6:.1f}M' if v > 0 else '' for v in container.datavalues]
ax.bar_label(container, labels=labels, fontsize=10, fontweight='bold', padding=3)
# Fond et grille
ax.set_facecolor('#f8f9fa')
plt.grid(axis='y', alpha=0.4, linestyle='--', linewidth=0.7)
# Limites
plt.ylim(0, bo['Cumul'].max() * 1.1)
# Titres et labels
plt.title('Top 20 des films - Cumul des entrées',
fontsize=18, fontweight='bold', pad=20, color='#2B2D42')
plt.ylabel('Cumul des entrées (millions)', fontsize=13)
plt.xlabel('')
# Rotation et style
plt.xticks(rotation=45, ha='right', fontsize=13)
plt.xticks(rotation=45, ha='right', fontsize=10.5)
# Supprimer bordures
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_linewidth(0.8)
ax.spines['bottom'].set_linewidth(0.8)
plt.tight_layout()
plt.show()
Quels films sont dans le top 20 des films en terme d'entrées?
print("On regarde la courbe du nombre d'entrées pour le film God save the Tuche")
test = BoxOffice[BoxOffice['Titre']=='God save the Tuche']
titre_film = test['Titre'].iloc[0]
total_entrees = test['Entrées'].sum() # Calculer la somme
plt.figure(figsize=(14, 6))
# Style et couleur
sns.lineplot(data=test, x='Date', y='Entrées',
marker='o', linewidth=2.5, markersize=8,
color='#2E86AB', alpha=0.8)
# Ajouter les valeurs sur les points
for idx, row in test.iterrows():
if row['Entrées'] > 0: # Éviter d'afficher 0.000M
plt.text(row['Date'], row['Entrées'],
f"{row['Entrées']/1e6:.3f}M",
fontsize=9, fontweight='bold',
ha='center', va='bottom',
bbox=dict(boxstyle='round,pad=0.3', facecolor='white',
edgecolor='gray', alpha=0.7))
# Formater l'axe Y
ax = plt.gca()
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, p: f'{x/1e6:.1f}M'))
# Fond et grille
ax.set_facecolor('#f8f9fa')
plt.grid(True, alpha=0.4, linestyle='--', linewidth=0.7)
# Titre dynamique avec total
plt.title(f'Évolution des entrées pour {titre_film} ({total_entrees/1e6:.2f}M entrées)',
fontsize=16, fontweight='bold', pad=20)
plt.ylabel('Nombre d\'entrées', fontsize=12)
plt.xlabel('')
# Rotation des dates
plt.xticks(ha='right', rotation=45, fontsize=10)
plt.yticks(fontsize=10)
# Bordures plus fines
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_linewidth(0.8)
ax.spines['bottom'].set_linewidth(0.8)
plt.tight_layout()
plt.show()
On regarde la courbe du nombre d'entrées pour le film God save the Tuche
BoxOffice[BoxOffice['Titre']=='God save the Tuche']
| Rang | NbSemaine | Titre | Entrées | Variation | Cumul | Budget | NbCopies | MoyCopies | Date | Ratio | En2025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 136 | 1 | 1 | God save the Tuche | 1087000 | New | 1087000 | 19400000.0 | 734 | 1481 | 5 au 11 février 2025 | 0.056031 | Oui |
| 164 | 1 | 2 | God save the Tuche | 756000 | - 30 % | 1843000 | 19400000.0 | 755 | 1001 | 12 au 18 février 2025 | 0.095 | Oui |
| 192 | 1 | 3 | God save the Tuche | 517000 | - 32 % | 2360000 | 19400000.0 | 849 | 609 | 19 au 25 février 2025 | 0.121649 | Oui |
| 218 | 1 | 4 | God save the Tuche | 286000 | - 45 % | 2646000 | 19400000.0 | 909 | 315 | 25 février au 4 mars 2025 | 0.136392 | Oui |
| 246 | 3 | 5 | God save the Tuche | 142000 | - 50 % | 2788000 | 19400000.0 | 774 | 184 | 5 au 11 mars 2025 | 0.143711 | Oui |
| 279 | 8 | 6 | God save the Tuche | 86000 | - 40 % | 2874000 | 19400000.0 | 552 | 155 | 12 au 18 mars 2025 | 0.148144 | Oui |
| 309 | 11 | 7 | God save the Tuche | 79000 | - 8 % | 2952000 | 19400000.0 | 454 | 173 | 19 au 25 mars 2025 | 0.152165 | Oui |
| 348 | 20 | 8 | God save the Tuche | 24000 | - 69 % | 2976000 | 19400000.0 | 311 | 78 | 26 mars au 1er avril 2025 | 0.153402 | Oui |
| 381 | 25 | 9 | God save the Tuche | 9000 | - 61 % | 2986000 | 19400000.0 | 78 | 121 | 2 au 8 avril 2025 | 0.153918 | Oui |