##%######################################################%##
#                                                          #
####   Vizualizace dat prostřednictvím balíčku ggplot   ####
#                                                          #
##%######################################################%##

library(tidyverse)
set.seed(123)

# Data preparation --------------------------------------------------------
df <- foreign::read.spss("data/eukids.sav", to.data.frame = TRUE,
                         trim.factor.names = TRUE, reencode = TRUE) %>% 
  as_tibble() %>% 
  mutate(
    across(b01_99:p10_99, as.integer),
    trida = factor(trida, levels = unique(trida)) %>% as.integer()
  )

df_sml <- sample_n(df, 100)

glimpse(df)
tibble(
  var_name = names(attributes(df)$variable.labels),
  var_label = attributes(df)$variable.labels
) %>% 
  View()

names(df)

# qplot() function: Draw quick exploratory plots -----------------------

# The qplot() function is very similar to the standard R base plot() function. It can
# be used to create quickly and easily different types of graphs: scatter plots, box
# plots, violin plots, histogram and density plots.

# A simplified format of qplot() is :

# qplot(x, y = NULL, data, geom="auto")
  #  x, y : x and y values, respectively. The argument y is optional depending on
  # the type of graphs to be created.
  # data : data frame to use (optional).
  #  geom : Character vector specifying geom to use. Defaults to "point" if x and y
  # are specified, and "histogram" if only x is specified.

##### Scatter plots
# Basic scatter plot
qplot(x = selfe, y = deprese, data = df_sml, geom = "point") # na menším vzorku
qplot(x = selfe, y = deprese, data = df, geom = "point") # na celém vzorku

# Scatter plot with smoothed line
qplot(x = selfe, y = deprese, data = df_sml, 
      geom = c("point", "smooth"))

# Change the color by a continuous numeric variable
qplot(x = selfe, y = deprese, color = ziv_sp, data = df_sml, 
      geom = "point")

# Change color and shape by categorical variable
qplot(x = selfe, y = deprese, color = pohlavi, data = df_sml, 
      geom = "point")

# Change the size of points according to
# the values of a continuous variable
qplot(x = selfe, y = deprese, size = ziv_sp, data = df_sml, 
      geom = "point")

##### Box plots
# Basic boxplot
qplot(pohlavi, zdravi, data = df, geom = "boxplot")

# Change fill color by sex
qplot(pohlavi, zdravi, fill = pohlavi, data = df,
      geom = "boxplot")

##### Histograms
# Basic histogram
qplot(vekr, data = df, geom = "histogram")

qplot(vekr, data = df, geom = "histogram", binwidth = 0.1)

qplot(vekr, data = df, geom = "histogram", binwidth = 1, center = 12)


# ggplot() function: Build plots piece by piece ---------------------------
# the concept of ggplot divides a plot into three different fundamental
# parts: plot = data + Aesthetics + geometry.

# To demonstrate how the function ggplot() works, we’ll draw a scatter plot. The
# function aes() is used to specify x and y variables as well as aesthetics 
# (e.g., color, shape, size). An alternative option is the function aes_string() 
# which, generates mappings from a string.

# Basic scatter plot
ggplot(data = df_sml) +
  geom_point(aes(x = deprese, y = zdravi))

# Change the point size, and shape
ggplot(data = df_sml) +
  geom_point(aes(x = deprese, y = zdravi), size = 3, shape = 18)

# The function aes_string() can be used as follow:
ggplot(data = df_sml) +
  geom_point(aes_string(x = "deprese", y = "zdravi"), size = 1.5, shape = 23)

# It’s also possible to make a ggplot and to save it from the screen using 
# the function ggsave():
ggplot(data = df_sml) +
  geom_point(aes(x = deprese, y = zdravi))

ggsave(filename = "plots/sp_deprese_zdravi.png", dpi = 300, type = "cairo",
       width = 19, height = 10, units = "cm")

# Make a scatterplot of self and deprese.

# What happens if you make a scatterplot of zn_mat and zn_cj? 
# Why is the plot not useful?
# Try to use geom_jitter() and then geom_count() instead of geom_point()

# Aesthetic mappings ------------------------------------------------------
# You can convey information about your data by mapping the aesthetics 
# in your plot to the variables in your dataset.
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi, color = pohlavi))

# we could have mapped class to the size aesthetic in the same way. 
# In this case, the exact size of each point would reveal its class affiliation. 
# We get a warning here, because mapping an unordered variable (class) 
# to an ordered aesthetic (size) is not a good idea.
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi, size = pohlavi))

# Or we could have mapped class to the alpha aesthetic, which controls 
# the transparency of the points, or to the shape aesthetic, 
# which controls the shape of the points.
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi, alpha = pohlavi),
             size = 3)

ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi, shape = pohlavi),
             size = 3)

# You can also set the aesthetic properties of your geom manually. 
# For example, we can make all of the points in our plot blue:
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi), 
             color = "blue", size = 3)

# Here, the color doesn’t convey information about a variable, 
# but only changes the appearance of the plot. 

# You’ll need to pick a level that makes sense for that aesthetic:
# The name of a color as a character string. http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf
# The size of a point in mm.
# The shape of a point as a number, as shown in Figure 3.1.
shapes_df <- tibble(
  id = 0:25,
  x = rep(1:13, 2),
  y = rep(1:2, each = 13)
)

# Shapes overview
ggplot(shapes_df, aes(x, factor(y), shape = factor(id))) +
  geom_point(size = 5, fill = "red") +
  scale_shape_manual(values = 0:25) +
  geom_text(aes(label = id), nudge_y = 0.1) +
  theme_void() +
  theme(legend.position = "none")

### Exercises
# What’s gone wrong with this code? Why are the points not blue?
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi,  color = "blue"))

# Create the scatterplot of deprese (X) and zdravi (Y) with df_sml data
# First map a categorical variable "pohlavi" to color, size, and shape, step by step
# then do the same for a continuous variable "ziv_sp"
# How do these aesthetics behave differently for 
# categorical vs. continuous variables?



# What happens if you map the same variable to multiple aesthetics?
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi, color = ziv_sp, size = ziv_sp))

# What happens if you map an aesthetic to something other than a variable name,
# like color = ziv_sp < 2.5


# Facets ------------------------------------------------------------------
# One way to add additional variables is with aesthetics. Another way, 
# particularly useful for categorical variables, is to split your plot 
# into facets, subplots that each display one subset of the data.

# basis plot 
p <- ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi))

p + facet_wrap(~kohorta, nrow = 2) # dva řádky

p + facet_wrap(~kohorta, ncol = 2) # dva sloupce

# Použití dvou proměnných jako fazet 
p + facet_wrap(~kohorta + pohlavi, nrow = 2)

# To facet your plot on the combination of two variables, add facet_grid() 
# to your plot call. The first argument of facet_grid() is also a formula. 
# This time the formula should contain two variable names separated by a ~.
p + facet_grid(kohorta ~ pohlavi) # řádky ~ sloupce

p + facet_grid(pohlavi ~ kohorta) # řádky ~ sloupce

### Exercises
# What happens if you facet on a continuous variable?
# try facet_wrap() with optim


# What do the empty cells in this plot mean?
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = deprese, y = zdravi)) + 
  facet_grid(zn_mat ~ zn_cj)

# How do they relate to this plot?
ggplot(data = df_sml) + 
  geom_count(mapping = aes(x = zn_mat, y = zn_cj))


#  Geometric objects ------------------------------------------------------
# A geom is the geometrical object that a plot uses to represent data. 
# People often describe plots by the type of geom that the plot uses. 
# For example, bar charts use bar geoms, line charts use line geoms, 
# boxplots use boxplot geoms, and so on.

# representing data using points, geom_point()
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = selfe, y = deprese))

# representing data using a smooth curve, geom_smooth()
ggplot(data = df_sml) + 
  geom_smooth(mapping = aes(x = selfe, y = deprese))

# Every geom function in ggplot2 takes a mapping argument. 
# However, not every aesthetic works with every geom.

# You could set the shape of a point, but you couldn’t set the “shape” of a line. 
# On the other hand, you could set the linetype of a line.

# Create a scatterplot of selfe and deprese,
# and try mapping pohlavi to shape, linetype, group, and color
ggplot(data = df_sml) + 
  geom_smooth(mapping = aes(x = selfe, y = deprese, shape = pohlavi))

ggplot(data = df_sml) + 
  geom_smooth(mapping = aes(x = selfe, y = deprese, linetype = pohlavi))

ggplot(data = df_sml) + 
  geom_smooth(mapping = aes(x = selfe, y = deprese, group = pohlavi))

ggplot(data = df_sml) + 
  geom_smooth(mapping = aes(x = selfe, y = deprese, color = pohlavi),
              show.legend = TRUE)

# To display multiple geoms in the same plot, add multiple geom functions to ggplot():
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = selfe, y = deprese)) +
  geom_smooth(mapping = aes(x = selfe, y = deprese))

# This, however, introduces some duplication in our code. 
# Imagine if you wanted to change the y-axis to display cty instead of hwy. 
# You’d need to change the variable in two places, and you might forget to update one. 
# You can avoid this type of repetition by passing a set of mappings to ggplot()

# See if these lines procude identical plots
ggplot(data = df_sml) + 
  geom_point(mapping = aes(x = selfe, y = deprese)) +
  geom_smooth(mapping = aes(x = selfe, y = deprese))

ggplot(data = df_sml, mapping = aes(x = selfe, y = deprese)) + 
  geom_point() + 
  geom_smooth()

# If you place mappings in a geom function, ggplot2 will treat them 
# as local mappings for the layer. 
ggplot(data = df_sml, mapping = aes(x = selfe, y = deprese)) + 
  geom_point(mapping = aes(color = pohlavi)) + # mapovat pohlaví na barvu jen pro body
  geom_smooth()

ggplot(data = df_sml, mapping = aes(x = selfe, y = deprese)) + 
  geom_point() + 
  geom_smooth(mapping = aes(color = pohlavi)) # mapovat pohlaví na barvu jen pro křivku

# * Exercises ---------------------
# Run this code in your head and predict what the output will look like. 
# Then, run the code in R and check your predictions.
ggplot(data = df_sml, mapping = aes(x = monit, y = duv_r)) + 
  geom_point() +
  geom_smooth()

# What does show.legend = FALSE do? What happens if you remove it?
ggplot(data = df_sml, mapping = aes(x = selfe, y = deprese)) + 
  geom_point() +
  geom_smooth(mapping = aes(color = pohlavi),
              show.legend = FALSE)

# What does the se argument to geom_smooth() do?
# Try running this code
ggplot(data = df_sml, mapping = aes(x = selfe, y = deprese)) + 
  geom_point() +
  geom_smooth(se = FALSE)

ggplot(data = df_sml, mapping = aes(x = selfe, y = deprese)) + 
  geom_point() +
  geom_smooth(se = TRUE)


# Try to create plots from scratch ----------------------------------------

### Tvorba histogramu
# Vytvořte histogram selfe pomocí geom_histogram()
# šírku sloupců (binwidth) nastavte na 0.2
# barvu (color) na "black"
# a výplň (fill) na "grey"

### Tvorba bodového grafu / Scatterplotu
# Nejprve z dat vyřaďte případy s chybějící hodnotou v pohlavi
# Vytvořte scatteplot selfe pomocí geom_jitter()
# v geom_jitter() nastavte argumenty width i height na 0.05
# přidejte geom geom_smooth()
# v rámci toho nastavte method = "lm" a color = "black"
# nastavte barvu bodů podle pohlaví, ale nikoli křivky

### Trorba krabicového grafu / boxplotu
# Nejprve z dat vyřaďte případy s chybějící hodnotou v kohorta a pohlavi
# Vytvořte boxplot monit pomocí geom_boxplot()
# na osu X dejte "kohorta" a na osu Y "monit"
# nastavte výplň (fill) podle pohlavi
# ve geom_boxplot nastavte argument notch = TRUE

### Tvorba sloupcového grafu / barplotu
# Vyřaďte respondenty, kteří neuvedli kohortu anebo pohlaví
# pomocí geom_bar() vytvořte sloupcový graf ocek_vzd
# prohoďte osy pomocí přidáním: + coord_flip()
# pomocí facet_wrap() rozdělte graf na dva řádky podle kohorty
# nastave výplň (fill) podle pohlaví
# do estetického mapování přidejte: y = stat(prop), group = kohorta:pohlavi

### Tvorba spojnicovového grafu / line plots
# Vyřaďte respondenty, kteří neuvedli kohortu anebo pohlaví
# na osu X dejte kohortu, na osu Y monitorování
# na barvu mapujte pohlaví
# přidejte stat_summary(geom = "pointrange" fun.data = "mean_cl_normal")
# přidejte stat_summary(geom = "line", fun = "mean", aes(group = pohlavi))
# definutje objekt pos <- position_dodge(width = 0.1)
# do obou stat_summary() přidejte argument position = pos 

# Labels -----------------------------------------------------------------------
# The easiest place to start when turning an exploratory graphic into an 
# expository graphic is with good labels. You add labels with the labs() function. 
# This example adds a plot title:
ggplot(df_sml, aes(selfe, deprese, color = pohlavi)) +
  geom_point() +
  geom_smooth(se = FALSE, method = lm) +
  labs(
    title = "Depresivita klesá s rostoucím sebehodnocením"
  )

# subtitle adds additional detail in a smaller font beneath the title.
# caption adds text at the bottom right of the plot, often used to describe 
# the source of the data.
ggplot(df_sml, aes(selfe, deprese, color = pohlavi)) +
  geom_point() +
  geom_smooth(se = FALSE, method = lm) +
  labs(
    title = "Depresivita klesá s rostoucím sebehodnocením",
    subtitle = "Tento vztah je silnější u dívek",
    caption = "Data z projektu Cesty do dospělosti"
  )

# You can also use labs() to replace the axis and legend titles. 
# It’s usually a good idea to replace short variable names with 
# more detailed descriptions, and to include the units.
ggplot(df_sml, aes(selfe, deprese)) +
  geom_point(aes(color = pohlavi)) +
  geom_smooth(se = FALSE, method = lm) +
  labs(
    x = "Sebehodnocení (RSES)",
    y = "Depresivita (ADS)",
    color = "Pohlaví žáka:"
  )

# Scales ------------------------------------------------------------------
# The third way you can make your plot better for communication is to adjust the 
# scales. Scales control the mapping from data values to things that you can perceive. 
# Normally, ggplot2 automatically adds scales for you. For example, when you type
ggplot(df_sml, aes(selfe, deprese)) +
  geom_point()

# ggplot2 automatically adds default scales behind the scenes:
ggplot(df_sml, aes(selfe, deprese)) +
  geom_point(aes(colour = pohlavi)) +
  scale_x_continuous() +
  scale_y_continuous() +
  scale_colour_discrete()

# Note the naming scheme for scales: scale_ followed by the name of the aesthetic, 
# then _, then the name of the scale. The default scales are named according 
# to the type of variable they align with: continuous, discrete, datetime, or date. 

# There are two primary arguments that affect the appearance of the ticks on 
# the axes and the keys on the legend: breaks and labels. 
# Breaks controls the position of the ticks, or the values associated with 
# the keys. Labels controls the text label associated with each tick/key. 
# The most common use of breaks is to override the default choice:
ggplot(df_sml, aes(optim, zdravi)) +
  geom_point()

ggplot(df_sml, aes(optim, zdravi)) +
  geom_point() +
  scale_x_continuous(breaks = seq(8, 26, by = 2))


# Legend layout -----------------------------------------------------------
# To control the overall position of the legend, you need to use a theme() 
#setting. We’ll come back to themes at the end of the chapter, but in brief, 
# they control the non-data parts of the plot. The theme setting legend.position 
# controls where the legend is drawn:
p <- ggplot(df_sml, aes(vekr, deprese, color = kohorta:pohlavi)) +
  geom_point(alpha = 0.5) +
  scale_color_discrete(
    name = "Kohorta/pohlaví:", 
    labels = c("Mladší chlapci", "Mladší dívky", "Starší chlapci", "Starší dívky")
    )
p
p + theme(legend.position = "left")
p + theme(legend.position = "top")
p + theme(legend.position = "bottom")
p + theme(legend.position = "right") # the default
p + theme(legend.position = c(0.5, 0.25)) 

# You can also use legend.position = "none" to suppress the display of 
# the legend altogether.
p + theme(legend.position = "none")


# To control the display of individual legends, use guides() along with 
# guide_legend() or guide_colourbar(). The following example shows two important 
# settings: controlling the number of rows the legend uses with nrow, 
# and overriding one of the aesthetics to make the points bigger.
p +
  theme(legend.position = "top") +
  guides(
    colour = guide_legend(
      nrow = 2, override.aes = list(size = 4, alpha = 1)
      )
  )

# Themes ------------------------------------------------------------------
# Finally, you can customise the non-data elements of your plot with a theme:
p <- ggplot(df_sml, aes(deprese, zdravi)) +
  geom_point(aes(color = pohlavi)) +
  geom_smooth(se = FALSE)
p
p + theme_bw()
p + theme_classic()
p + theme_dark()
p + theme_grey() # Default
p + theme_light()
p + theme_linedraw()
p + theme_minimal()
p + theme_void()


# Save original theme and, at the same time, set a new theme (theme_bw())
old <- theme_set(theme_bw())
p

# Back to old theme
theme_set(old)
p

# Creating your own custom theme
# This saves the original theme and, at the same time, updates to a new theme
?theme

old <- theme_update(
  text = element_text(size = 12), # Bigger text
  axis.title = element_text(face = "bold"), # Axis titles in bold
  panel.grid.major = element_blank(), # Removing major grid lines
  panel.grid.minor = element_blank(), # Removing minor grid lines
  panel.background = element_blank(), # Removing grey background  
  axis.line = element_line(colour = "black"), # Adding black axis lines
  legend.key = element_blank() # transparent legend key
) 
p

# Saving a plot -----------------------------------------------------------

# Saves the plot "p"
ggsave(filename = "plots/deprese_zdravi.png", # set filename
       plot = p, # which plot to save
       dpi = 300, # Plot resolution
       type = "cairo", # Rendering device
       width = 19, height = 10, # Plot sizes
       units = "cm") # units to use

# Saves the last plot printed
ggsave(filename = "plots/deprese_zdravi.png", dpi = 300, type = "cairo",
       width = 19, height = 10, units = "cm")






