Wizualizacja danych z biblioteką ggplot2
- Wykresy zmiennej ilościowej
- Wykresy zmiennej jakościowej
- Wykresy dwóch zmiennych ilościowych
- Wykresy dwóch zmiennych jakościowych
- Wykresy zmiennej ilościowej vs zmiennej jakościowej
- Wykresy bąbelkowe (3x Challenge)
- Kilka wykresów na jednym panelu (2x Challenge).
Przydatne materiały:
- ggplot2
cheatsheet
- A.
Kassambara - Guide to Create Beautiful Graphics in R. - Hadley Wickham “ggplot2”
Dane pochodzą ze strony https://flixgem.com/ (wersja zbioru danych z dnia 12 marca 2021). Dane zawierają informacje na temat 9425 filmów i seriali dostępnych na Netlix.
Wizualizacja danych z ggplot2
Zadanie domowe
Korzystając z paczki danych “germancredit” dotyczącą oceny kredytowej (creditability) wybranych klientów pewnego banku wykreśl zmienną ilościową (np. wysokość kredytu); zmienną jakościową (ryzyko); ilościową wg jakościowej (np. wiek wg ryzyka); 2 ilościowe (wiek wg wysokości kredytu) oraz wykres bąbelkowy wg własnego pomysłu + przedstaw kilka wykresów na 1 panelu.
data("germancredit")
attach(germancredit)
# http://archive.ics.uci.edu/ml/datasets/Statlog+(German+Credit+Data)
Wykres 1 zmiennej ilościowej - Credit.Amount
ggplot(germancredit, aes(x=credit.amount)) +
geom_density(alpha=.25) +
labs(title = 'Gęstość rozkładu ocen')
Wykres 1 zmiennej jakościowej - Creditability
germancredit %>%
filter(creditability != '') %>%
ggplot(aes(creditability)) +
geom_bar(aes(fill = creditability))
Wiek według ryzyka
mediana = germancredit %>%
group_by(creditability) %>%
summarize(m = median(age.in.years, na.rm = TRUE))
ggplot(germancredit, aes(x = creditability, y = age.in.years)) +
geom_boxplot(
aes(fill = creditability)
,outlier.alpha = 0.25
) +
geom_text(
data = mediana
,aes(x = creditability, y = m, label = m)
,color = 'blue'
,hjust = 7
) +
stat_boxplot(geom ='errorbar', position = 'dodge') +
stat_summary(
aes(ymax = ..y.., ymin = ..y..)
,fun = mean
,geom = 'errorbar'
,width = .75
,linetype = 'solid'
,position = 'dodge'
,color = 'white'
,size = 1)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## Warning: The dot-dot notation (`..y..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(y)` instead.
Wiek według wysokości kredytu
ggplot(germancredit, aes(x = credit.amount, y = age.in.years)) +
geom_point(aes(color = credit.amount),
method = 'loess'
,se = FALSE
)
## Warning in geom_point(aes(color = credit.amount), method = "loess", se = FALSE):
## Ignoring unknown parameters: `method` and `se`
Wykres bąbelkowy - średnia wartość kredytu według rodzaju zatrudnienia
PRACA <- germancredit %>%
select(job) %>%
unlist() %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
PRACA1 <- data.frame(
Rodzaj.Pracy = PRACA$.
,`Count` = PRACA$Freq
,`age.average` = NA
,`credit.amount.average` = NA
)
for (i in 1:nrow(PRACA1)) {
PRACA1$age.average[i] <- germancredit %>%
filter(str_detect(job, PRACA1$Rodzaj.Pracy[i] %>%
as.character() %>% eval())) %>%
select(age.in.years) %>% unlist() %>% mean(na.rm = TRUE)
PRACA1$credit.amount.average[i] <- germancredit %>%
filter(str_detect(job, PRACA1$Rodzaj.Pracy[i] %>%
as.character() %>% eval())) %>%
select(credit.amount) %>% unlist() %>% mean(na.rm = TRUE)
}
ggplot(PRACA1, aes(age.average, credit.amount.average, label = Rodzaj.Pracy)) +
geom_point(aes(color = Rodzaj.Pracy, size = Count))
Kilka wykresów na jednym panelu - histogram wysokości kredytu z podziałem na property:
germancredit %>% filter(age.in.years != '') %>% ggplot(aes(x = credit.amount)) +
geom_histogram(
aes(fill = property)
,bins = 10
,color = 'black'
) + facet_wrap(vars(property), ncol = 2, nrow=2)
Zadania dodatkowe - dla chętnych:
CHALLENGE 1: Stwórz wykres pokazujący aktorów grających w najpopularniejszych produkcjach.
produkcje = 30
aktory = 10
Dane_Aktorow <- dane %>%
select(c(Title, Actors, IMDb.Votes, IMDb.Score)) %>%
arrange(-IMDb.Votes) %>%
head(produkcje)
Podzial_Aktorow <- Dane_Aktorow %>%
select(Actors) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
Podzial_Aktorow <- data.frame(
Actors = Podzial_Aktorow$.
,`Count` = Podzial_Aktorow$Freq
,`IMDb Score Average` = NA
,`IMDb Votes Average` = NA
)
for (i in 1:nrow(Podzial_Aktorow)) {
Podzial_Aktorow$IMDb.Score.Average[i] <- Dane_Aktorow %>%
filter(str_detect(Actors, Podzial_Aktorow$Actors[i] %>%
as.character() %>% eval())) %>%
select(IMDb.Score) %>% unlist() %>% mean(na.rm = TRUE)
Podzial_Aktorow$IMDb.Votes.Average[i] <- Dane_Aktorow %>%
filter(str_detect(Actors, Podzial_Aktorow$Actors[i] %>%
as.character() %>% eval())) %>%
select(IMDb.Votes) %>% unlist() %>% mean(na.rm = TRUE)
}
library(ggrepel)
Podzial_Aktorow%>%
# arrange(desc(IMDb.Votes.Average))%>%
arrange(-Count, -IMDb.Votes.Average)%>%
head(aktory)%>%
ggplot(aes(IMDb.Score.Average, IMDb.Votes.Average, label = Actors)) +
geom_point(aes(color = Actors, size = Count)) +
geom_text_repel() +
theme(legend.position = 'none') +
labs(title = 'Top 10 aktorów')
CHALLENGE 2: Stwórz wykres pokazujący w jakich latach powstawały najpopularniejsze produkcje. a. podział na dekady
dane = dane %>%
mutate(
Release.Date = Release.Date %>% as.Date(format = '%m/%d/%Y')
,Netflix.Release.Date = Netflix.Release.Date %>% as.Date(format = '%m/%d/%Y')
)
n=200
dane %>%
select(c(Title, Release.Date, IMDb.Votes)) %>%
arrange(-IMDb.Votes) %>%
head(n) %>%
mutate(Dekada = floor(lubridate:: year(Release.Date)/10)*10)%>%
count(Dekada)%>%
arrange(Dekada)%>%
mutate(Dekada = as.character(Dekada))%>%
rename(Ilosc = n)%>%
ggplot(aes(x=Dekada,y=Ilosc))+
geom_col(aes(fill=Dekada))+
scale_fill_brewer(palette="Set5")+
labs(title = 'Liczba wyprodukowanych produkcji w danej dekadzie dla top 200 filmów')+
geom_text(aes(label = Ilosc), vjust = 1.5)
b. podział na lata
n=200
dane %>% mutate(Rok = lubridate:: year(Release.Date))%>%
select(c(Title, Release.Date, IMDb.Votes,Rok)) %>%
arrange(-IMDb.Votes) %>%
head(n) %>% count(Rok) %>%
arrange(Rok)%>%
rename(Ilosc = n) %>%
ggplot(aes(x=Rok,y=Ilosc))+
geom_col(aes(fill=Rok))+
labs(title = 'Liczba wyprodukowanych produkcji w danym roku dla top 200 filmów') +
geom_text(aes(label = Ilosc), vjust = 1.5)
CHALLENGE 3: Jakie są najpopularniejsze języki dostępne na Netflixie? Podpowiedź: wykres kolumnowy.
dane%>% pull(Languages) %>% paste0(collapse = ', ') %>%
str_extract_all('[A-Za-z]+') %>% unlist() %>% table() %>%
as.data.frame()%>% rename(Jezyk = ".", Ilosc = Freq)%>% arrange(-Ilosc)%>%
head(10)%>% ggplot(aes(x=Jezyk,y=Ilosc))+
geom_col(aes(fill=Jezyk))+
labs(title = "Top 10 najpopularniejszych języków")+
geom_text(aes(label = Ilosc), vjust = 1.4)
CHALLENGE 4: Dla filmów i seriali stwórz wykresy ocen z poszczególnych portali (Hidden Gem, IMDb, Rotten Tomatoes, Metacritic). Podpowiedź: warto odpiwotować dane do formatu long.
library("gridExtra")
n_top = 3
p_movies<-dane %>%
select(Title, Series.or.Movie, Hidden.Gem.Score, IMDb.Score, Rotten.Tomatoes.Score, Metacritic.Score)%>% filter(Series.or.Movie == "Movie")%>% drop_na()%>% mutate(Rotten.Tomatoes.Score=Rotten.Tomatoes.Score/10, Metacritic.Score=Metacritic.Score/10, SredniaOcena = (Hidden.Gem.Score + IMDb.Score + Rotten.Tomatoes.Score + Metacritic.Score)/4)%>% arrange(-SredniaOcena) %>% head(n_top)%>% pivot_longer(Hidden.Gem.Score:Metacritic.Score)%>% rename(Ocena = value, Witryna = name )%>%
ggplot(aes(x=Title, y = Ocena, fill=Witryna))+
geom_bar(stat="identity", position="dodge")+
labs(title = sprintf("Oceny filmów z różnych witryn dla 3 najlepszych filmów", n_top))+
theme(axis.text.x = element_text(angle = 90, vjust = 0.8))+
scale_x_discrete(labels = function(x) str_wrap(x, width = 10))
p_series<-dane %>%
select(Title, Series.or.Movie, Hidden.Gem.Score, IMDb.Score, Rotten.Tomatoes.Score, Metacritic.Score)%>%
filter(Series.or.Movie == "Series")%>%
drop_na()%>%
mutate(Rotten.Tomatoes.Score=Rotten.Tomatoes.Score/10, Metacritic.Score=Metacritic.Score/10, SredniaOcena = (Hidden.Gem.Score + IMDb.Score + Rotten.Tomatoes.Score + Metacritic.Score)/4)%>%
arrange(-SredniaOcena)%>%
head(n_top)%>%
pivot_longer(Hidden.Gem.Score:Metacritic.Score)%>%
rename(Ocena = value, Witryna = name )%>%
ggplot(aes(x=Title, y = Ocena, fill=Witryna))+
geom_bar(stat="identity", position="dodge")+
labs(title = sprintf("Oceny seriali z różnych witryn dla 3 najlepszych seriali", n_top))+
theme(axis.text.x = element_text(angle = 90, vjust = 0.8))+
scale_x_discrete(labels = function(x) str_wrap(x, width = 10))
grid.arrange(p_movies, p_series, nrow = 2)
CHALLENGE 5: Jakie wytwórnie filmowe produkują najwięcej i jak się to zmieniało na przestrzeni ostatnich lat?
LATA <- dane %>%
mutate(Release = Release.Date %>% as.Date(format = '%m/%d/%Y')) %>%
mutate(release_year = format(Release, format = "%Y"))
Wyt.2k20<- LATA %>%
filter(release_year == 2020) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k20) <- c('Wytwórnia', 'Liczba')
Wyt.2k20<- Wyt.2k20%>%
arrange(desc(Liczba))
POP_2020 <- Wyt.2k20[1:5,]
Wyt.2k19 <- LATA %>%
filter(release_year == 2019) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k19) <- c('Wytwórnia', 'Liczba')
Wyt.2k19 <- Wyt.2k19 %>%
arrange(desc(Liczba))
POP_2019 <- Wyt.2k19[1:5,]
Wyt.2k18 <- LATA %>%
filter(release_year == 2018) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k18) <- c('Wytwórnia', 'Liczba')
Wyt.2k18 <- Wyt.2k18 %>%
arrange(desc(Liczba))
POP_2018 <- Wyt.2k18[1:5,]
Wyt.2k17 <- LATA %>%
filter(release_year == 2017) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k17) <- c('Wytwórnia', 'Liczba')
Wyt.2k17 <- Wyt.2k17 %>%
arrange(desc(Liczba))
POP_2017 <- Wyt.2k17[1:5,]
Wyt.2k16 <- LATA %>%
filter(release_year == 2016) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k16) <- c('Wytwórnia', 'Liczba')
Wyt.2k16 <- Wyt.2k16 %>%
arrange(desc(Liczba))
POP_2016 <- Wyt.2k16[1:5,]
Wyt.2k15 <- LATA %>%
filter(release_year == 2015) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k15) <- c('Wytwórnia', 'Liczba')
Wyt.2k15 <- Wyt.2k15 %>%
arrange(desc(Liczba))
POP_2015 <- Wyt.2k15[1:5,]
Wyt.2k14 <- LATA %>%
filter(release_year == 2014) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k14) <- c('Wytwórnia', 'Liczba')
Wyt.2k14 <- Wyt.2k14 %>%
arrange(desc(Liczba))
POP_2014 <- Wyt.2k14[1:5,]
Wyt.2k13 <- LATA %>%
filter(release_year == 2013) %>%
select(Production.House) %>%
unlist() %>%
strsplit(',') %>%
unlist() %>%
trimws() %>%
table() %>%
as.data.frame()
colnames(Wyt.2k13) <- c('Wytwórnia', 'Liczba')
Wyt.2k13 <- Wyt.2k13 %>%
arrange(desc(Liczba))
POP_2013 <- Wyt.2k13[1:5,]
library("RColorBrewer")
w1 <- ggplot(POP_2020, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2020') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
w2 <- ggplot(POP_2019, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2019') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
w3 <- ggplot(POP_2018, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2018') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
w4 <- ggplot(POP_2017, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2017') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
w5 <- ggplot(POP_2016, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2016') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
w6 <- ggplot(POP_2015, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2015') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
w7 <- ggplot(POP_2014, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2014') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
w8 <- ggplot(POP_2013, aes(x = reorder(Wytwórnia, -Liczba), y = Liczba)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
scale_fill_manual(values = brewer.pal(4, 'Dark2')) +
labs(title = 'Top 2013') +
xlab('Wytwórnia') +
ylab('Liczba filmów')
grid.arrange(w1, w2, w3, w4, w5, w6, w7, w8, ncol = 4, nrow = 2)
- Jak zmieniało się to w latach? Sam Netflix
LATA%>%
select(Production.House, release_year)%>%
filter(Production.House =="Netflix" | Production.House==",Netflix,")%>%
count(Production.House, release_year)%>%
arrange(release_year)%>%
rename(Wytwornia=Production.House, Ilosc = n)
## Wytwornia release_year Ilosc
## 1 Netflix 2013 2
## 2 Netflix 2014 3
## 3 Netflix 2015 3
## 4 Netflix 2016 10
## 5 Netflix 2017 15
## 6 Netflix 2018 8
## 7 Netflix 2019 12
- Jak to wygląda na wykresie? Liniowy - sam Netflix
data1 <- dane%>%
select(Production.House, Series.or.Movie, Release.Date)%>%
filter(Series.or.Movie == "Movie" & Production.House =="Netflix")%>%
mutate(Rok = lubridate:: year(Release.Date))%>%
count(Production.House, Rok) %>% as.data.frame()
plot(data1$Rok, data1$n, type="l", xlab="Rok", ylab="Ilosc", main="Zmiany Netflix w latach 2013-2019")