SkyLimit Tech Hub: Data Science Training Center

Course 4: Data Visualization with ggplot2

ggplot2 is a powerful package in the tidyverse ecosystem that enables users to create visually appealing, layered graphics based on the grammar of graphics. This course introduces learners to ggplot2, covering its foundational concepts, various plot types, and advanced visualization techniques. Designed for those with basic R knowledge, it equips students to transform raw data into compelling visualizations over one week.

Objective: By the end of the course, learners will be proficient in using ggplot2 to create scatter plots, bar plots, histograms, boxplots, and heatmaps, and customize them with themes, annotations, and scales for effective data communication.

Scope: The course covers ggplot2’s core functions (ggplot(), geom_*(), aes()), plot customization (labs(), theme()), faceting, and real-world visualization projects using datasets like mtcars and Palmer Penguins.

Day 1: Introduction to ggplot2

Introduction: ggplot2 is a powerful and flexible package within the tidyverse ecosystem that enables users to create visually appealing, layered graphics based on a coherent system known as the grammar of graphics. It offers an elegant, modular approach to building plots, where users start with a simple structure and iteratively add layers to construct complex visualizations. With ggplot2, users can transform raw data into compelling stories, revealing trends, patterns, and outliers with clarity and precision. Its ability to produce publication-quality graphics has made ggplot2 the default choice for data visualization in the R community.

Objective: The main objective of this lesson is to introduce learners to the foundational concepts of ggplot2, including how to initiate a basic plot using ggplot(), define aesthetics with aes(), and apply geometric objects (geoms) such as points and lines. By the end of the session, learners should be able to build simple yet informative visualizations that can later be expanded with additional layers, themes, and customizations. Understanding this framework will set the stage for developing more advanced, customized, and interactive data visualizations in subsequent lessons.

Scope of the Lesson: This session focuses on the installation of ggplot2, the basic structure of a ggplot() call, and the use of common geoms to visualize data. Learners will cover how to set up aesthetic mappings (aes()), how to add layers like geom_point() for scatter plots and geom_line() for line charts, and how the + operator is used to combine multiple plot elements. The modular nature of ggplot2 will be emphasized, encouraging learners to think of plots as compositions of different parts rather than one-off static commands. This session lays the groundwork necessary for more complex plotting tasks involving facets, themes, scales, and annotations.

Background Information: ggplot2 was developed by Hadley Wickham based on the "grammar of graphics" concept introduced by Leland Wilkinson. The idea is that every plot can be broken down into components: a dataset, mappings between variables and visual properties (aesthetics), a set of geoms that represent data points, and other optional layers such as scales, coordinates, and themes. A basic ggplot2 plot starts with ggplot(data, aes(x, y)), which specifies the dataset and the mappings between variables and axes. Adding a geom like geom_point() then tells ggplot2 how to represent the data visually. The + operator is used to layer multiple components, allowing for extremely flexible, readable, and maintainable plotting workflows. Unlike traditional plotting in R, which often involves imperative commands (one-off actions), ggplot2 adopts a declarative style where users declare what they want to plot and how.

Simple Code Examples:

# Load the ggplot2 library
library(ggplot2)

# Sample data
df <- data.frame(
  x = 1:10,
  y = c(2, 4, 5, 7, 11, 13, 17, 19, 23, 29)
)

# Basic scatter plot
ggplot(df, aes(x = x, y = y)) +
  geom_point()

# Basic line plot
ggplot(df, aes(x = x, y = y)) +
  geom_line()

# Combined scatter and line plot
ggplot(df, aes(x = x, y = y)) +
  geom_point(color = "blue") +
  geom_line(color = "red")
                

Interpretation of the Example Codes: In the examples above, the ggplot2 library is first loaded to make its plotting functions available. A simple dataset df is created with two numeric columns, x and y. The first plot initializes a ggplot object using ggplot(df, aes(x = x, y = y)) and then adds geom_point(), creating a scatter plot that visualizes the points (x, y) on a two-dimensional plane. The second example uses the same ggplot initialization but adds geom_line(), resulting in a line graph that connects the (x, y) points in order. The third example demonstrates the compositional nature of ggplot2 by layering both geom_point() and geom_line() together in a single plot. Here, the points are colored blue, and the connecting line is colored red, illustrating how different aesthetics can be applied to different layers. This layering approach will allow users to create more complex visualizations such as adding trendlines, annotations, error bars, or reference lines in future lessons. Overall, the key takeaway is that ggplot2 builds plots step-by-step, using a clear, flexible grammar that separates data, mappings, and visual representation.

Supplemental Information:

Discussion Points:

  • What are the advantages of thinking about plots as a combination of layers rather than as one-off drawings?
  • How does the use of aesthetics (aes()) improve the clarity and modularity of your plots?
  • Why is the + operator used in ggplot2 instead of chaining functions like %>%?
  • How could you extend a simple plot with additional information, such as trendlines or text labels?
  • In what ways might ggplot2's structure be limiting compared to base R graphics, if any?
  • How can careful selection of colors, shapes, and line types in geoms enhance or mislead interpretation of a plot?

Day 2: Bar Plots and Histograms

Introduction: Bar plots and histograms are two fundamental types of visualizations that help in understanding the structure of data quickly and intuitively. In ggplot2, creating these plots is straightforward and highly customizable. Bar plots are particularly useful when comparing different categories or groups, while histograms reveal the underlying distribution of continuous numerical variables. Mastering these basic plots provides a strong foundation for more advanced exploratory data analysis, offering insights into the frequency, spread, and shape of data.

Objective: The goal of this lesson is to teach learners how to generate bar plots for categorical data and histograms for continuous data using ggplot2. Learners will also understand how to customize the appearance of these plots using arguments related to color, fill, bin width (for histograms), and labeling axes and titles. By the end of the session, learners should be capable of producing clear, informative bar plots and histograms that can be further refined for reports, presentations, or deeper analysis.

Scope of the Lesson: This session focuses on the application of geom_bar() for creating bar plots and geom_histogram() for creating histograms. Learners will practice how to define aesthetic mappings appropriately, control the number of bins in histograms, change colors and borders of bars, and add meaningful titles and axis labels using the labs() function. Special attention will be given to understanding when to use each plot type appropriately: bar plots for discrete/categorical variables and histograms for continuous variables. Additionally, the session covers basic customization options that enhance the readability and visual appeal of plots.

Background Information: In ggplot2, bar plots are constructed using the geom_bar() function, which automatically counts the number of observations for each category. If the dataset already contains summarized counts, users must specify stat = "identity" inside geom_bar() to plot the provided counts directly. A typical bar plot in ggplot2 involves mapping a categorical variable to the x-axis and letting geom_bar() calculate frequencies. Histograms, on the other hand, are created using geom_histogram(), which groups continuous variables into bins and counts how many observations fall into each bin. The bins argument controls how many bins are used and thus affects the appearance of the histogram. Fewer bins provide a more general view of the distribution, while more bins reveal finer details. Histograms are crucial for identifying skewness, modality, and outliers in continuous data. Customization, such as adjusting fill color, outline color, and labels, further enhances the plots' clarity and aesthetic quality.

Simple Code Examples:

# Load ggplot2
library(ggplot2)

# Sample dataset for bar plot
df_bar <- data.frame(
  category = c("A", "B", "C", "D", "E"),
  count = c(5, 7, 8, 3, 6)
)

# Bar plot with counts
ggplot(df_bar, aes(x = category, y = count)) +
  geom_bar(stat = "identity", fill = "skyblue", color = "black") +
  labs(title = "Category Counts", x = "Category", y = "Count")

# Sample dataset for histogram
df_hist <- data.frame(
  values = rnorm(1000, mean = 50, sd = 10)
)

# Basic histogram
ggplot(df_hist, aes(x = values)) +
  geom_histogram(bins = 30, fill = "lightgreen", color = "black") +
  labs(title = "Distribution of Values", x = "Value", y = "Frequency")

# Customized histogram with different bin width
ggplot(df_hist, aes(x = values)) +
  geom_histogram(binwidth = 5, fill = "orange", color = "darkred") +
  labs(title = "Distribution with Binwidth 5", x = "Value", y = "Frequency")
                

Interpretation of the Example Codes: In the bar plot example, a simple data frame df_bar is created, containing two columns: category (categorical variable) and count (number of observations). When using geom_bar(stat = "identity"), it is crucial because we are plotting pre-counted values rather than letting ggplot2 automatically count. The bars are filled with a light blue color and outlined with a black border for better visibility. Labels are added to the x-axis, y-axis, and as the plot title using labs(). In the histogram examples, a continuous variable values is simulated using a normal distribution (rnorm() function). The first histogram uses bins = 30, meaning the data will be divided into 30 intervals. The bars are filled with light green and outlined with black. This visualization gives a clear sense of the distribution’s bell-shaped pattern, typical of normal data. The second histogram changes the bin width to 5 using binwidth = 5, offering another view where each bar covers a 5-unit range on the x-axis. By adjusting bin sizes, users can either emphasize fine-grained patterns or smooth out noise, depending on the goal of the analysis. The fill color is changed to orange with a dark red border, highlighting how color customization can improve plot readability and make plots more visually appealing or thematically aligned.

Supplemental Information:

Discussion Points:

  • When should you use geom_bar() versus geom_histogram()?
  • What considerations should you have when choosing the number of bins in a histogram?
  • How can color be used strategically in bar plots and histograms to improve interpretation?
  • Why is stat = "identity" necessary when manually supplying bar plot values?
  • How might different bin widths change the interpretation of a histogram?
  • In what real-world situations would histograms reveal critical insights about data distributions (e.g., skewness, modality, outliers)?

Day 3: Scatter Plots and Line Plots

Introduction: Scatter plots and line plots are two of the most widely used types of visualizations in data analysis. Scatter plots are invaluable for examining relationships or correlations between two continuous variables, while line plots are often used to display trends over time or across ordered categories. Both types of plots are essential for data exploration, helping to identify patterns, outliers, and trends. In ggplot2, these visualizations are created with simplicity and offer deep customization for enhancing clarity and aesthetic appeal.

Objective: The primary objective of this lesson is to teach learners how to create scatter plots and line plots using ggplot2. Additionally, learners will explore how to customize these plots by adding layers, changing aesthetics, faceting (to split plots by categories), and adding annotations such as titles and axis labels. By the end of this session, learners should be able to create insightful scatter and line plots and tailor their presentation to suit analysis needs.

Scope of the Lesson: In this session, learners will focus on using the geom_point() function to create scatter plots and geom_line() to create line plots. These functions will be demonstrated with sample data, and their use will be illustrated for revealing relationships and trends. Faceting with facet_wrap() will be introduced to break a plot into multiple subplots based on a grouping variable. Further, the lesson will touch on customizing plots with annotations such as labs() and theme(). This will help learners enhance the readability and design of their plots.

Background Information: Scatter plots, created with geom_point(aes(x, y)), display individual data points and are typically used to visualize correlations between two continuous variables. By mapping one variable to the x-axis and another to the y-axis, scatter plots can show whether there is a positive, negative, or no relationship between the two variables. They are fundamental for exploring bivariate relationships and are useful for identifying outliers or clusters of data. Line plots, on the other hand, are often used for displaying trends over time or across ordered categories. geom_line(aes(x, y)) connects points in a sequence to emphasize continuity and trends. Line plots are particularly useful in time-series analysis where the x-axis represents time and the y-axis represents values over that period. Faceting allows for the creation of subplots that display different aspects of the data. The facet_wrap(~col) function in ggplot2 splits a plot into multiple panels based on the unique values of a specified column (col). This is useful for comparing relationships across different subgroups within the data. Annotations like labs() are used to add titles, axis labels, and legends to improve clarity. The theme() function in ggplot2 allows further customization of the plot’s appearance, including adjusting text size, background color, and gridlines.

Simple Code Examples:

# Load ggplot2
library(ggplot2)

# Sample dataset for scatter plot
df_scatter <- data.frame(
  x = rnorm(100),
  y = rnorm(100)
)

# Basic scatter plot
ggplot(df_scatter, aes(x = x, y = y)) +
  geom_point() +
  labs(title = "Scatter Plot of x vs y", x = "X Value", y = "Y Value")

# Sample dataset for line plot (time series example)
df_line <- data.frame(
  time = seq(1, 100),
  value = cumsum(rnorm(100))
)

# Basic line plot
ggplot(df_line, aes(x = time, y = value)) +
  geom_line() +
  labs(title = "Time Series Line Plot", x = "Time", y = "Value")

# Scatter plot with faceting by another variable
df_scatter2 <- data.frame(
  x = rnorm(100),
  y = rnorm(100),
  category = sample(c("A", "B"), 100, replace = TRUE)
)

ggplot(df_scatter2, aes(x = x, y = y)) +
  geom_point() +
  facet_wrap(~category) +
  labs(title = "Scatter Plot by Category", x = "X Value", y = "Y Value")

# Scatter plot with custom theme and annotations
ggplot(df_scatter, aes(x = x, y = y)) +
  geom_point(color = "blue", size = 3) +
  labs(title = "Customized Scatter Plot", x = "X Value", y = "Y Value") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))
                

Interpretation of the Example Codes: In the first example, a simple scatter plot is created using geom_point(), which maps the x and y variables to the x and y axes, respectively. This is useful for visualizing the relationship between two continuous variables. The labs() function adds a title and labels for the x and y axes, improving the plot's readability. Next, a line plot is created with geom_line(). Here, the data represents a time series, where time is plotted on the x-axis and value on the y-axis. The cumulative sum (cumsum()) of random values is plotted to simulate a time-series trend. The labs() function is again used to add relevant titles and labels. The third example introduces faceting with facet_wrap(~category). The category variable is used to split the scatter plot into two separate panels, one for each category. This helps compare the relationship between x and y across different categories. Lastly, a customized scatter plot is created by adjusting aesthetics such as point color (color = "blue") and size (size = 3). The theme_minimal() function applies a minimal theme to the plot, removing unnecessary gridlines and background. The theme() function customizes the plot further, centering the title with element_text(hjust = 0.5).

Supplemental Information:

Discussion Points:

  • What is the main difference between a scatter plot and a line plot in terms of their use and data type?
  • How does faceting help in comparing multiple categories within a dataset?
  • What are some advantages of using the theme() function for customizing ggplot2 plots?
  • How might you interpret a scatter plot with a strong linear relationship between x and y?
  • Why is it important to choose appropriate axis labels and plot titles? How do these annotations enhance communication?
  • How can you decide whether to use points or lines when visualizing trends over time?

Day 4: Advanced Visualizations

Introduction: As you advance in your data analysis journey, you will encounter more complex visualizations that provide deeper insights into data distributions and relationships. Advanced features of ggplot2—such as boxplots and heatmaps—are powerful tools that help visualize the spread of data, identify outliers, and examine correlations between variables. Boxplots are particularly useful for understanding the distribution and variability of a dataset, while heatmaps offer a clear view of relationships in matrix-like data. Mastering these visualizations will enable you to work with more sophisticated datasets and convey insights effectively.

Objective: The objective of this lesson is to teach learners how to create and customize advanced visualizations, specifically boxplots and heatmaps, using ggplot2. Learners will also explore various customization techniques to improve the clarity and aesthetic quality of their plots. By the end of this session, learners should be able to generate and customize these advanced plots to gain insights into complex datasets and convey meaningful relationships between variables.

Scope of the Lesson: In this lesson, learners will focus on creating boxplots using geom_boxplot() and heatmaps using geom_tile(). The session will cover how to visualize distributions with boxplots, which help identify outliers and understand the spread of data across different groups. Heatmaps will be introduced to represent matrix data, such as correlation matrices, where color intensity conveys information about the relationship between variables. Learners will also explore how to enhance the appearance of plots by adjusting scales with functions like scale_fill_gradient() to modify the color range in heatmaps. Additionally, the lesson will demonstrate how to apply different themes, such as theme_minimal(), to refine the visual design of the plots, ensuring they are aesthetically pleasing and readable.

Background Information: Boxplots are a common visualization for examining the distribution of data, particularly the spread and presence of outliers. geom_boxplot() displays a summary of a numerical variable by showing its median, quartiles, and potential outliers. This type of plot is especially useful when comparing the distributions of data across different categories. For example, comparing the exam scores of students from different schools or age groups can be done effectively using boxplots. Heatmaps, on the other hand, are typically used to visualize the intensity of relationships between two variables in a matrix form. With geom_tile(), you can create a heatmap where the x and y axes represent categorical or continuous variables, and the color fill represents the value or strength of the relationship between them. Heatmaps are often used for visualizing correlation matrices, where colors show the strength of the correlation between different variables. Scales like scale_fill_gradient() allow users to control the color scheme used in heatmaps. This is crucial for ensuring that the color range accurately reflects the data's significance. Similarly, theme() functions like theme_minimal() help in adjusting the plot's design, reducing unnecessary elements and focusing the viewer's attention on the data.

Simple Code Examples:

# Load ggplot2
library(ggplot2)

# Sample data for boxplot
df_box <- data.frame(
  category = rep(c("A", "B", "C"), each = 50),
  value = c(rnorm(50, mean = 5), rnorm(50, mean = 7), rnorm(50, mean = 6))
)

# Basic boxplot
ggplot(df_box, aes(x = category, y = value)) +
  geom_boxplot() +
  labs(title = "Boxplot of Values by Category", x = "Category", y = "Value")

# Customizing the boxplot (with color)
ggplot(df_box, aes(x = category, y = value, fill = category)) +
  geom_boxplot() +
  labs(title = "Boxplot with Custom Colors", x = "Category", y = "Value") +
  scale_fill_brewer(palette = "Set3")

# Sample data for heatmap
df_heatmap <- expand.grid(x = 1:10, y = 1:10)
df_heatmap$value <- runif(100, min = 0, max = 1)

# Basic heatmap
ggplot(df_heatmap, aes(x = x, y = y, fill = value)) +
  geom_tile() +
  scale_fill_gradient(low = "white", high = "blue") +
  labs(title = "Basic Heatmap", x = "X Axis", y = "Y Axis")

# Customizing the heatmap with different color scale
ggplot(df_heatmap, aes(x = x, y = y, fill = value)) +
  geom_tile() +
  scale_fill_gradient(low = "yellow", high = "red") +
  theme_minimal() +
  labs(title = "Customized Heatmap", x = "X Axis", y = "Y Axis")
                

Interpretation of the Example Codes: In the first set of examples, a boxplot is created using geom_boxplot(), with category on the x-axis and value on the y-axis. This simple boxplot provides an overview of the distribution of value across three categories (A, B, and C), including the median, interquartile range (IQR), and potential outliers. The second example adds color customization using scale_fill_brewer(), which applies a predefined color palette to the boxplots based on the category. The next set of examples demonstrates the creation of a heatmap using geom_tile(). Here, x and y represent the coordinates, and value is mapped to the fill color. In the first heatmap, the scale_fill_gradient() function is used to create a color gradient ranging from white (low values) to blue (high values), providing a visual representation of the intensity of the value variable. The second heatmap example customizes the color range from yellow to red and applies theme_minimal() for a clean, minimalistic appearance. These visualizations are crucial for understanding data patterns. The boxplot allows you to compare the distribution of values across categories, while the heatmap provides a visual representation of the strength of relationships between variables, useful for exploring complex datasets.

Supplemental Information:

Discussion Points:

  • How do boxplots help in identifying outliers and understanding data distribution?
  • What insights can heatmaps provide in relation to the correlation of variables?
  • How can the choice of color gradients impact the interpretation of heatmaps?
  • What are the advantages of using theme_minimal() or other ggplot2 themes in your visualizations?
  • How might you use these advanced visualizations in real-world analysis, such as comparing sales performance across regions or examining gene expression data?

Day 5: Visualization Projects

Introduction: Real-world data visualization projects allow learners to apply the concepts and techniques they've learned with ggplot2 to actual datasets. These projects help build skills in communicating data insights through various types of plots and visual representations. Whether it’s economic data, health data, or any other domain, visualizing the data effectively is crucial for discovering patterns, relationships, and trends that can drive decision-making. By the end of this session, learners will have hands-on experience with creating multiple plot types and adding meaningful annotations and themes for clarity and presentation.

Objective: The objective of this session is to guide learners through completing a series of visualization projects using ggplot2. These projects will cover several key plot types, such as scatter plots, bar plots, and boxplots, and provide learners with the opportunity to add annotations, labels, and customize themes. Learners will get a chance to apply their skills on real datasets, ensuring they understand how to transform raw data into insightful visualizations that are both informative and visually appealing.

Scope of the Lesson: In this session, learners will focus on creating a variety of visualizations, including: Histograms using geom_histogram() to explore the distribution of continuous variables; Scatter plots using geom_point() to examine relationships between two continuous variables; Bar plots using geom_bar() to compare categorical data; Boxplots using geom_boxplot() to visualize the distribution and spread of data within categories. The lesson will also cover the use of various customization options, such as adding titles and axis labels with labs(), modifying the color schemes, and applying different themes to improve the presentation of the visualizations. These tasks simulate real-world projects where professionals often need to create clear and effective visualizations for reporting purposes. Learners will practice working with datasets and applying their visualization skills to solve practical challenges.

Background Information: Visualization is a critical part of the data analysis process, as it allows analysts and decision-makers to quickly comprehend patterns, trends, and outliers. ggplot2 is a powerful tool for creating professional visualizations, and this session will emphasize the importance of selecting the appropriate type of plot for specific types of data and analysis goals. Histograms, scatter plots, and bar plots are fundamental chart types used in data analysis. A histogram displays the distribution of a single continuous variable, showing how the data is spread across different ranges. Scatter plots are used to examine the relationship between two continuous variables, providing insight into possible correlations. Bar plots are ideal for comparing categorical data, such as sales across different product categories or population counts by region. Additionally, boxplots help summarize data by showing its central tendency, spread, and outliers across categories. ggplot2 makes it easy to customize these plots by adding labels and adjusting themes. Adding titles, axis labels, and legends ensures that your plots are clear and understandable, while themes can help enhance the overall visual appeal and presentation quality of the charts.

Simple Code Examples:

# Load necessary libraries
library(ggplot2)

# Load example dataset: mtcars (built-in dataset)
data("mtcars")

# Scatter plot: Exploring relationship between mpg (miles per gallon) and hp (horsepower)
ggplot(mtcars, aes(x = hp, y = mpg)) +
  geom_point() +
  labs(title = "Scatter Plot: Horsepower vs Miles per Gallon", x = "Horsepower", y = "Miles per Gallon")

# Histogram: Distribution of miles per gallon (mpg)
ggplot(mtcars, aes(x = mpg)) +
  geom_histogram(binwidth = 2, fill = "skyblue", color = "black") +
  labs(title = "Histogram of Miles per Gallon", x = "Miles per Gallon", y = "Frequency")

# Bar plot: Comparison of number of cylinders
ggplot(mtcars, aes(x = factor(cyl))) +
  geom_bar(fill = "tomato") +
  labs(title = "Bar Plot: Number of Cylinders", x = "Cylinders", y = "Count")

# Boxplot: Distribution of mpg by number of cylinders
ggplot(mtcars, aes(x = factor(cyl), y = mpg)) +
  geom_boxplot(fill = "lightgreen") +
  labs(title = "Boxplot: Miles per Gallon by Cylinders", x = "Cylinders", y = "Miles per Gallon")
                

Interpretation of the Example Codes: Scatter Plot Example: The first example uses geom_point() to create a scatter plot that explores the relationship between horsepower (hp) and miles per gallon (mpg) in the mtcars dataset. This visualization helps understand how changes in horsepower may affect fuel efficiency. Histogram Example: The second example creates a histogram of the mpg variable to examine its distribution. The binwidth parameter controls the width of each bin, and the fill and color parameters are used to customize the look of the histogram. The plot shows how the values of mpg are spread across different ranges. Bar Plot Example: The third example uses geom_bar() to create a bar plot, visualizing the number of cars with different cylinder counts (cyl). The bars represent the frequency (or count) of each category of cylinders. This plot helps in comparing the number of cars with 4, 6, and 8 cylinders in the dataset. Boxplot Example: The fourth example creates a boxplot with geom_boxplot(), displaying the distribution of miles per gallon (mpg) for each category of cylinder count (cyl). Boxplots show the median, quartiles, and potential outliers, helping us understand the spread and central tendency of mpg for different cylinder counts. These visualizations represent the types of plots that are commonly used in data exploration. By creating them, you learn how to communicate insights andică System: relationships effectively through visual representations.

Supplemental Information:

Discussion Points:

  • How can scatter plots help in identifying relationships between two continuous variables?
  • What is the significance of histograms in understanding data distributions, and how can you determine the best bin width for your data?
  • How do you choose between a bar plot and a boxplot for comparing categorical data?
  • What role do annotations and themes play in making visualizations clearer and more accessible to an audience?
  • How would you present your visualizations in a professional report or dashboard?

Daily Quiz

Practice Lab

Select an environment to practice coding exercises.

Exercise

Download the following files to support your learning:

Grade

Day 1 Score: Not completed

Day 2 Score: Not completed

Day 3 Score: Not completed

Day 4 Score: Not completed

Day 5 Score: Not completed

Overall Average Score: Not calculated

Overall Grade: Not calculated

Generate Certificate

Click the button below to generate your certificate for completing the course.