### Hanjoon Ko
### Deuxième viz
### M1 DES 22/23

### version modifiée

# Attaching packages ─────────────────────────────────────────────────────────────────────────── tidyverse 1.3.2 ──
# ✔ ggplot2 3.4.1      ✔ dplyr   1.0.10
# ✔ tibble  3.1.8      ✔ stringr 1.4.1 
# ✔ tidyr   1.2.1      ✔ forcats 0.5.2 
# ✔ purrr   1.0.1      
# Conflicts ────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
# ✖ dplyr::filter() masks stats::filter()
# ✖ dplyr::lag()    masks stats::lag()


library(readr)
library(skimr)
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.4.1      ✔ dplyr   1.0.10
## ✔ tibble  3.1.8      ✔ stringr 1.4.1 
## ✔ tidyr   1.2.1      ✔ forcats 0.5.2 
## ✔ purrr   1.0.1      
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
Netflix <- read_csv("C:/Users/Ko/OneDrive/Nanterre/S2/Visualisation/cours de viz/NetflixOriginals.csv")
## Rows: 584 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): Title, Genre, Premiere, Language
## dbl (2): Runtime, IMDB Score
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(Netflix)

# Le nom de dataset : Netflix Original Films & IMDB Scores 
# URL : https://www.kaggle.com/datasets/luiscorter/netflix-original-films-imdb-scores?select=NetflixOriginals.csv


# L'analyse générale -------------------------------------------------------

skim(Netflix)
Data summary
Name Netflix
Number of rows 584
Number of columns 6
_______________________
Column type frequency:
character 4
numeric 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
Title 0 1 2 105 0 584 0
Genre 0 1 3 36 0 115 0
Premiere 0 1 11 18 0 390 0
Language 0 1 4 26 0 38 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Runtime 0 1 93.58 27.76 4.0 86.0 97.00 108 209 ▁▂▇▁▁
IMDB Score 0 1 6.27 0.98 2.5 5.7 6.35 7 9 ▁▂▇▇▁
# Les données consistent de 584 films produits par Netflix jusqu'au 1 juin 2021
# Il y a 6 colonnes : Title, Genre, Premiere (la date de sortie), Language, Runtime, IMDB Score. Dans cet analyse, on va focaliser sur IMDB Score

# Il y a 115 genres incluant les films documentaires
# 38 langues sont offertes. Certains films sont disponibles en plusieurs de langues (ex. l'anglais/l'hindi)
# La durée moyenne de films est 93.6 minutes. Il y a une donnée atypique qui dure 209 minutes (The Irishman)

Netflix <- Netflix %>%
  filter(Runtime < 209)
# On a supprimé une donnée trop atypique qui dure 209 minutes

Netflix %>%
  arrange(-`IMDB Score`)
## # A tibble: 583 × 6
##    Title                                   Genre Premi…¹ Runtime IMDB …² Langu…³
##    <chr>                                   <chr> <chr>     <dbl>   <dbl> <chr>  
##  1 David Attenborough: A Life on Our Plan… Docu… Octobe…      83     9   English
##  2 Emicida: AmarElo - It's All For Yester… Docu… Decemb…      89     8.6 Portug…
##  3 Springsteen on Broadway                 One-… Decemb…     153     8.5 English
##  4 Ben Platt: Live from Radio City Music … Conc… May 20…      85     8.4 English
##  5 Taylor Swift: Reputation Stadium Tour   Conc… Decemb…     125     8.4 English
##  6 Winter on Fire: Ukraine's Fight for Fr… Docu… Octobe…      91     8.4 Englis…
##  7 Cuba and the Cameraman                  Docu… Novemb…     114     8.3 English
##  8 Dancing with the Birds                  Docu… Octobe…      51     8.3 English
##  9 13th                                    Docu… Octobe…     100     8.2 English
## 10 Disclosure: Trans Lives on Screen       Docu… June 1…     107     8.2 English
## # … with 573 more rows, and abbreviated variable names ¹​Premiere,
## #   ²​`IMDB Score`, ³​Language
# Le score moyen d'IMDB est 6.27 sur 9. Le film le mieux noté est David Attenborough: A Life on Our Planet 

library(png)
library(grid)

setwd("C:/Users/Ko/OneDrive/Documents/")

mon_image <- readPNG("IMDB.png") %>% 
  rasterGrob(interpolate=TRUE)
# Je prépare une image du logo d'IMDB pour ajouter dans le plot


# Viz 1 -------------------------------------------------------------------

library(ggplot2)
library(ggforce)
library(plotly)
## 
## Attachement du package : 'plotly'
## 
## L'objet suivant est masqué depuis 'package:ggplot2':
## 
##     last_plot
## 
## L'objet suivant est masqué depuis 'package:stats':
## 
##     filter
## 
## L'objet suivant est masqué depuis 'package:graphics':
## 
##     layout
library(htmlwidgets)

### La relation entre la durée de films et le score d'IMDB


viz1 <- ggplot(Netflix) +
  aes(x = Runtime, y = `IMDB Score`, colour = `IMDB Score`) +
  geom_point(shape = "square", 
             size = 3L) +
  scale_color_viridis_c(option = "viridis", direction = 1) +
  labs(title = "La relation entre la durée de film et le score d'IMDB", subtitle = "Films produits par Netflix jusqu'à juin 2021", 
      color = "Score", x = "Durée (min)", y = "IMDB Score (sur 9.0)") +
  geom_hline(aes(yintercept = mean(`IMDB Score`)), linewidth = 1.3, color = "firebrick", linetype ="dashed") + # hline pour visualiser la moyenne du score
  annotate("text", x = 4, y = 6.1, 
           label = "la moyenne (6.27)", 
           color = "firebrick", size = 4, fontface = 3) +
  annotate("text", x = 140, y = 2, 
           label = "Université Paris Nanterre DES 22/23
        Deuxième visualisation - Hanjoon Ko", 
           color = "black", size = 3) +
  annotate("text", x = 0, y = 9, 
           label = "R = -0.05", 
           color = "black", size = 4, fontface = 2) +
  annotation_custom(mon_image,
                    xmin=140, xmax=160, 
                    ymin=2.5, ymax=3) + # Le logo d'IMDB est ajouté pour mettre en avant de la source de score
  theme_light()
  
viz1

### VIZ

ggplotly(viz1, tooltip = c("x","y")) %>%
  layout(title = list(text = paste0("La relation entre la durée de film et le score d'IMDB",
                                    "<br>",
                                    "<sup>",
                                    "Films produits par Netflix jusqu'à juin 2021",'</sup>')))
## Warning in geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]): geom_GeomCustomAnn() has yet to be implemented in plotly.
##   If you'd like to see this geom implemented,
##   Please open an issue with your example code at
##   https://github.com/ropensci/plotly/issues
saveWidget(ggplotly(viz1, tooltip = c("x","y")) %>%
             layout(title = list(text = paste0("La relation entre la durée de film et le score d'IMDB",
                                               "<br>",
                                               "<sup>",
                                               "Films produits par Netflix jusqu'à juin 2021",'</sup>')))
           , "viz1_hanjoon.html", selfcontained = FALSE)
## Warning in geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]): geom_GeomCustomAnn() has yet to be implemented in plotly.
##   If you'd like to see this geom implemented,
##   Please open an issue with your example code at
##   https://github.com/ropensci/plotly/issues
### COR
cor(Netflix$Runtime, Netflix$`IMDB Score`, use = "complete.obs")
## [1] -0.05294635
# R = -0.05

# On ne voit pas la relation entre la durée de films et le score


# Viz 2 -------------------------------------------------------------------

library(gifski)
library(gganimate)

### Est-ce la langue affecte-t-elle le score ?

skim(Netflix$Language)
Data summary
Name Netflix$Language
Number of rows 583
Number of columns 1
_______________________
Column type frequency:
character 1
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
data 0 1 4 26 0 38 0
Netflix <- Netflix %>%
  mutate(Language2 = fct_collapse(Language,
                                  Anglais = c("English/Japanese", "English", "English/Spanish", "English/Swedish", 
                                              "English/Taiwanese/Mandarin", "Thia/English", "English/Mandarin", "Khmer/English/French", "English/Hindi", 
                                              "Spanish/English", "English/Korean", "English/Arabic", "English/Russian", "English/Akan", "English/Ukranian/Russian"),
                                  Européen = c("Dutch", "French", "Georgian", "German", "Norwegian", "Polish", "Portuguese", "Spanish/Basque",
                                               "Spanish/Catalan", "Swedish", "Spanish", "Italian"),
                                  Asiatique = c("Bengali", "Tamil", "Thai", "Filipino", "Hindi", "Indonesian", "Japanese", "Korean", "Malay",
                                            "Marathi", "Turkish")))

# Il y a 38 différents langues disponibles incluant celles qui utilisent à la fois plusieurs de langues (ex. Spanish / English)
# J'ai divisé toutes les langues par 3 comme l'anglais, l'européen et l'asiatique vu que l'anglais est la langue plus utilisée

view(Netflix)

Netflix_ang <- Netflix %>%
  filter(Language2 == "English")

Netflix_eu_asia <- Netflix %>%
  filter(Language2 != "English")

skim(Netflix_ang)
Data summary
Name Netflix_ang
Number of rows 0
Number of columns 7
_______________________
Column type frequency:
character 4
factor 1
numeric 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
Title 0 NaN NA NA 0 0 0
Genre 0 NaN NA NA 0 0 0
Premiere 0 NaN NA NA 0 0 0
Language 0 NaN NA NA 0 0 0

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
Language2 0 NaN FALSE 0 Asi: 0, Eur: 0, Ang: 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Runtime 0 NaN NaN NA NA NA NA NA NA
IMDB Score 0 NaN NaN NA NA NA NA NA NA
skim(Netflix_eu_asia) # Skim pour comparer la note des films en anglais avec celle des films en autres langues
Data summary
Name Netflix_eu_asia
Number of rows 583
Number of columns 7
_______________________
Column type frequency:
character 4
factor 1
numeric 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
Title 0 1 2 105 0 583 0
Genre 0 1 3 36 0 115 0
Premiere 0 1 11 18 0 390 0
Language 0 1 4 26 0 38 0

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
Language2 0 1 FALSE 3 Ang: 421, Eur: 93, Asi: 69

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Runtime 0 1 93.38 27.37 4.0 86.0 97.0 107.5 155 ▁▁▅▇▁
IMDB Score 0 1 6.27 0.98 2.5 5.7 6.3 7.0 9 ▁▂▇▇▁
viz2 <- Netflix %>%
  ggplot() +
  aes(x = Runtime, y = `IMDB Score`, colour = Language2) +
  geom_point(shape = "circle", 
             size = 3L) +
  scale_color_viridis_d(option = "viridis", direction = 1) +
  labs(title = "La relation entre la langue de film et le score d'IMDB", subtitle = "Films produits par Netflix jusqu'à juin 2021", 
       caption = "Université Paris Nanterre DES 22/23
       Deuxième Visualisation - Hanjoon Ko", color = "Language", x = "Durée (min)", y = "IMDB Score (sur 9.0)") +
  geom_hline(aes(yintercept = mean(`IMDB Score`)), linewidth = 1, color = "firebrick", linetype ="dashed") +
  annotate("text", x = 10, y = 6.1, 
           label = "la moyenne (6.27)", 
           color = "firebrick", size = 4, fontface = 3) +
  annotate("text", x = 25, y = 2.4, 
           label = "La moyenne de score :
           6.39 (L'anglais), 5.95 (L'européen / L'asiatique)", 
           color = "black", size = 4, fontface =2) +
  annotation_custom(mon_image,
                    xmin=140, xmax=160, 
                    ymin=2, ymax=3.5) +
  theme_light()

viz2

viz2_anim <- (viz2 + transition_states(Language2, wrap = FALSE))

animate(viz2_anim, height = 600, width =800)

anim_save("viz2_hanjoon.gif")

# Il y a beaucoup plus de films qui sont disponibles en anglais (422) que ceux qui ne sont pas (117)
# Le moyen de score d'IMDB des films en anglais est plus haut (6.39 et 5.95)


# Conclusion --------------------------------------------------------------

# J'ai essayé  de voir si la durée affecte la note d'IMDB, mais les films bien notés et les films mal notés sont distribués de manière écrêtée
# Le teste de corrélation l'a prouvé cette interprétation
# Donc Netflix n'a pas forcément besoin de prendre en considération la durée pour produire un film bien noté 

# En deuxième lieu, j'ai comparé les films en anglais et les films en autres langues
# On a trouvé que le nombre des films en anglais est beaucoup plus
# Donc, pour produire un film bien noté, Netflix doit offrir l'anglais, même s'il est offrit avec d'autres langues ensemble (ex. l'anglais / l'hinde)