Visualisasi Deskriptif

Visualisasi Deskriptif

Fikakampus.jpg


DataSet

library(readr)
data_bisnis <- read.csv("data_bisnis.csv")

data_bisnis

8.1 Categorical Data

8.1.1 Bar Chart

# Load required libraries
library(dplyr)        # For data manipulation
## Warning: package 'dplyr' was built under R version 4.4.2
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)      # For creating the bar chart
library(viridis)      # For color palette
## Warning: package 'viridis' was built under R version 4.4.2
## Loading required package: viridisLite
library(scales)       # For formatting currency labels
## 
## Attaching package: 'scales'
## The following object is masked from 'package:viridis':
## 
##     viridis_pal
## The following object is masked from 'package:readr':
## 
##     col_factor
# Step 1: Prepare the data
data_bisnis <- read.csv("data_bisnis.csv")
sales_summary <- data_bisnis %>%
  group_by(Product_Category) %>%                              
  summarise(Total_Sales = sum(Total_Price, na.rm = TRUE)) %>% 
  arrange(desc(Total_Sales))                                  

# Step 2: Generate a color palette
custom_colors <- viridis::turbo(n = nrow(sales_summary))      

# Step 3: Create bar chart with value labels
ggplot(sales_summary, aes(x = reorder(Product_Category, -Total_Sales), 
                          y = Total_Sales, 
                          fill = Product_Category)) +
  geom_col(show.legend = FALSE) +                         
  geom_text(aes(label = scales::label_comma(prefix = "Rp ")(Total_Sales)),
            vjust = -0.3, size = 3) +                       
  scale_fill_manual(values = custom_colors) +             
  scale_y_continuous(labels = scales::label_comma(prefix = "Rp "),
                     expand = expansion(mult = c(0, 0.1))) + 
  labs(
    title = "Total Sales by Product Category (2020–2024)",
    subtitle = "Based on Transaction Value",
    x = "Product Category",
    y = "Total Sales",
    caption = "@siregarbakti") +
    theme_minimal(base_size = 10)                             

8.1.2 Pie Chart

# Load necessary libraries
library(dplyr)      # For data manipulation
library(ggplot2)    # For data visualization
library(viridis)    # For color palettes
library(scales)     # For formatting percentages

# Step 1: Summarize total sales by product category
data_bisnis <- read.csv("data_bisnis.csv")
sales_summary <- data_bisnis %>%
  group_by(Product_Category) %>%
  summarise(Total_Sales = sum(Total_Price, na.rm = TRUE)) %>%
  arrange(desc(Total_Sales)) %>%
  mutate(
    Percentage = Total_Sales / sum(Total_Sales),# Calculate share
    Label = paste0(Product_Category, "\n",      # Create label with line break
                   scales::percent(Percentage, accuracy = 1)))

# Step 2: Create custom color palette
custom_colors <- viridis::turbo(n = nrow(sales_summary))

# Step 3: Plot donut chart
ggplot(sales_summary, aes(x =2, y = Percentage, fill = Product_Category)) +
  geom_col(width = 1, color = "white", show.legend = FALSE) + # donut slices
  coord_polar(theta = "y") +                    # Convert to circular layout
  geom_text(aes(label = Label),                 # Add labels inside slices
            position = position_stack(vjust = 0.5),
            size = 3, color = "white", fontface = "bold") +
  scale_fill_manual(values = custom_colors) +
  xlim(0.5, 2.5) +                             # Expand size of donut
  labs(
    title = "Sales Distribution by Product Category (2020–2024)",
    subtitle = "Based on Total Transaction Value",
    caption = "@siregarbakti"
  ) +
  theme_void(base_size = 10) +                 # Clean theme
  theme(
    plot.title = element_text(face = "bold", hjust = 0.6), # Centered title
    plot.subtitle = element_text(margin = margin(t = 8, b = 16), hjust = 0.5),
    plot.caption = element_text(margin = margin(t = 15), hjust = 1.5,
                                color = "gray20", face = "italic")
  )

8.1.3 Word Could

# ==============================
# 1. Install & Load Required Packages
# ==============================
packages <- c("dplyr", "tm", "wordcloud", "RColorBrewer")
new_packages <- packages[!(packages %in% installed.packages()[, "Package"])]
if(length(new_packages)) install.packages(new_packages)

library(dplyr)
library(tm)
## Warning: package 'tm' was built under R version 4.4.3
## Loading required package: NLP
## Warning: package 'NLP' was built under R version 4.4.2
## 
## Attaching package: 'NLP'
## The following object is masked from 'package:ggplot2':
## 
##     annotate
library(wordcloud)
## Warning: package 'wordcloud' was built under R version 4.4.3
## Loading required package: RColorBrewer
library(RColorBrewer)

# ==============================
# 2. Read and Combine Text Columns
# ==============================
data_bisnis <- read.csv("data_bisnis.csv")

# Combine text columns into one
text_data <- paste(data_bisnis$Product_Category,
                   data_bisnis$Region,
                   data_bisnis$Sales_Channel,
                   sep = " ")

# ==============================
# 3. Clean and Prepare Text
# ==============================
corpus <- VCorpus(VectorSource(text_data))

corpus_clean <- corpus %>%
  tm_map(content_transformer(tolower)) %>%  # convert to lowercase
  tm_map(removePunctuation) %>%             # remove punctuation
  tm_map(removeNumbers) %>%                 # remove numbers
  tm_map(removeWords, stopwords("english")) %>%  # remove English stopwords
  tm_map(stripWhitespace)                   # remove extra whitespace

# Remove empty documents (if any)
non_empty_idx <- sapply(corpus_clean, function(doc) {
  nchar(content(doc)) > 0
})
corpus_clean <- corpus_clean[non_empty_idx]

# ==============================
# 4. Create Term-Document Matrix & Word Frequencies
# ==============================
tdm <- TermDocumentMatrix(corpus_clean)
m <- as.matrix(tdm)
word_freqs <- sort(rowSums(m), decreasing = TRUE)
df_words <- data.frame(word = names(word_freqs), freq = word_freqs)

# ==============================
# 5. Generate Word Cloud (Full Screen)
# ==============================
set.seed(123)
wordcloud(words = df_words$word,
          freq = df_words$freq,
          scale = c(4, 4),       # adjust for large size
          min.freq = 1,
          max.words = 200,
          random.order = FALSE,
          rot.per = 0.3,
          colors = brewer.pal(8, "Dark2"))
## Warning in wordcloud(words = df_words$word, freq = df_words$freq, scale = c(4,
## : groceries could not be fit on page. It will not be plotted.

8.1.4 Treemap

# ==============================
# 1. Install & Load Required Packages
# ==============================
packages <- c("treemapify", "dplyr", "ggplot2")
new_packages <- packages[!(packages %in% installed.packages()[, "Package"])]
if(length(new_packages)) install.packages(new_packages)

# Load libraries
library(treemapify)
## Warning: package 'treemapify' was built under R version 4.4.3
library(ggplot2)
library(dplyr)

# ==============================
# 2. Prepare Aggregated Treemap Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv")
tree_data <- data_bisnis %>%
  group_by(Product_Category, Region) %>%
  summarise(
    Total_Sales = sum(Total_Price, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  mutate(
    label_combined = paste0(Region, "\n", round(Total_Sales, 0))
  )

# ==============================
# 3. Create Static Tree Map with Combined Labels
# ==============================

ggplot(tree_data, aes(
  area = Total_Sales,
  fill = Product_Category,
  subgroup = Product_Category
)) +
  geom_treemap() +
  geom_treemap_subgroup_border(color = "white") +

  geom_treemap_text(
    aes(label = label_combined),
    colour = "white",
    place = "centre",
    grow = FALSE,
    reflow = TRUE,
    size = 20 / .pt,       # Adjust overall font size
    min.size = 3
  ) +

  labs(
    title = "Tree Map of Total Sales by Product Category and Region"
  ) +
  theme_minimal()

8.2 Numerical Data

8.2.1 Histogram

# ==============================
# 1. Load Required Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# 2. Prepare Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv")
data_bisnis <- data_bisnis %>%
  mutate(Quantity = as.numeric(Quantity))

# ==============================
# 3. Create Histogram of Quantity with Custom Font Sizes
# ==============================
ggplot(data_bisnis, aes(x = Quantity)) +
  geom_histogram(binwidth = 1,
                 fill = "skyblue",
                 color = "gray",
                 alpha = 0.7) +
  labs(
    title = "Histogram of Quantity Distribution",
    x = "Quantity",
    y = "Frequency"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 10, face = "bold"),  # Title size and bold
    axis.title.x = element_text(size = 10),               # X label size
    axis.title.y = element_text(size = 10),               # Y label size
    axis.text.x = element_text(size = 10),                # X axis numbers size
    axis.text.y = element_text(size = 10)                 # Y axis numbers size
  )

8.2.2 Density Plot

# ==============================
# 1. Load Required Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# 2. Prepare Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv")

# Ensure Quantity is numeric and remove NAs
data_bisnis <- data_bisnis %>%
  mutate(Quantity = as.numeric(Quantity)) %>%
  filter(!is.na(Quantity))

# Calculate mean of Quantity
mean_quantity <- mean(data_bisnis$Quantity, na.rm = TRUE)

# Estimate density to get y-position for label
density_data <- density(data_bisnis$Quantity)
max_y <- max(density_data$y)

# ==============================
# 3. Create Density Plot with Mean Line and Label
# ==============================
ggplot(data_bisnis, aes(x = Quantity)) +
  geom_density(fill = "skyblue", alpha = 0.6) +
  geom_vline(xintercept = mean_quantity, color = "red", 
             linetype = "dashed", linewidth = 1) +
  geom_text(
    data = data.frame(x = mean_quantity, y = max_y * 0.8),
    aes(x = x, y = y),
    label = paste("Mean =", round(mean_quantity, 2)),
    color = "black",
    angle = 90,
    vjust = -0.5,
    size = 3,
    fontface = "bold",
    inherit.aes = FALSE
  ) +
  labs(
    title = "Density Plot of Quantity with Mean",
    x = "Quantity",
    y = "Density"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 15, face = "bold"),
    axis.title = element_text(size = 15),
    axis.text = element_text(size = 10)
  )

8.2.3 Box Plot

# ==============================
# 1. Load Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# 2. Load and Prepare Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

# Convert Quantity to numeric and filter missing
data_bisnis <- data_bisnis %>%
  mutate(Quantity = as.numeric(Quantity)) %>%
  filter(!is.na(Quantity))

# Compute IQR-based outlier bounds
Q1 <- quantile(data_bisnis$Quantity, 0.25)
Q3 <- quantile(data_bisnis$Quantity, 0.75)
IQR_value <- IQR(data_bisnis$Quantity)
lower_whisker <- Q1 - 1.5 * IQR_value
upper_whisker <- Q3 + 1.5 * IQR_value

# ==============================
# 3. Summarize Statistics
# ==============================
stats <- data_bisnis %>%
  summarise(
    Mean = mean(Quantity),
    Q1 = Q1,
    Median = median(Quantity),
    Q3 = Q3,
    Min = min(Quantity),
    Max = max(Quantity),
    Outliers = sum(Quantity < lower_whisker | Quantity > upper_whisker)
  )

# ==============================
# 4. Basic Boxplot with Jitter and Annotations
# ==============================
ggplot(data_bisnis, aes(x = factor(1), y = Quantity)) +
  # Basic boxplot
  geom_boxplot(fill = "skyblue", outlier.shape = NA) +
  
  # Add jittered points, highlight outliers in red
  geom_jitter(aes(color = Quantity < lower_whisker | Quantity > upper_whisker),
              width = 0.1, size = 1, alpha = 0.5) +
  scale_color_manual(values = c("FALSE" = "black", "TRUE" = "red"), guide = "none") +
  
  # Highlight max point if not an outlier
  geom_point(data = data_bisnis %>% filter(Quantity == stats$Max[[1]] & Quantity <= upper_whisker),
             aes(x = factor(1), y = Quantity),
             color = "red", size = 0.21) +
  
  # Annotations
  ggplot2::annotate("text", x = 1.2, y = stats$Mean[[1]], 
           label = paste("Mean:", round(stats$Mean[[1]], 2)), 
           hjust = 0, fontface = "bold", color = "blue") +
  ggplot2::annotate("text", x = 1.2, y = stats$Q1[[1]], 
           label = paste("Q1:", round(stats$Q1[[1]], 2)), 
           hjust = 0, color = "darkgreen") +
  ggplot2::annotate("text", x = 1.2, y = stats$Median[[1]], 
           label = paste("Median:", round(stats$Median[[1]], 2)), 
           hjust = 0, color = "purple") +
  ggplot2::annotate("text", x = 1.2, y = stats$Q3[[1]], 
           label = paste("Q3:", round(stats$Q3[[1]], 2)), 
           hjust = 0, color = "darkgreen") +
  ggplot2::annotate("text", x = 1.2, y = stats$Min[[1]], 
           label = paste("Min:", round(stats$Min[[1]], 2)), 
           hjust = 0, color = "orange") +
  ggplot2::annotate("text", x = 1.2, y = stats$Max[[1]], 
           label = paste("Max:", round(stats$Max[[1]], 2)), 
           hjust = 0, color = "orange") +
  ggplot2::annotate("text", x = 1, y = stats$Max[[1]] + 0.05 * stats$Max[[1]], 
           label = paste("Outliers:", stats$Outliers[[1]]), 
           color = "red", fontface = "italic", hjust = 0.5) +

  # Plot formatting
  labs(
    title = "Boxplot of Quantity with Jitter and Annotations",
    x = NULL,
    y = "Quantity"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    plot.title = element_text(size = 15, face = "bold"),
    axis.title = element_text(size = 10),
    axis.text = element_text(size = 10)
  )

8.2.4 Violin Plot

# ==============================
# 1. Load Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# 2. Load and Prepare Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

# Clean and convert Quantity to numeric
data_bisnis <- data_bisnis %>%
  mutate(Quantity = as.numeric(Quantity)) %>%
  filter(!is.na(Quantity))

# Calculate quartiles and IQR for outlier detection
Q1 <- quantile(data_bisnis$Quantity, 0.25)
Q3 <- quantile(data_bisnis$Quantity, 0.75)
IQR_value <- IQR(data_bisnis$Quantity)
upper_whisker <- Q3 + 1.5 * IQR_value
lower_whisker <- Q1 - 1.5 * IQR_value

# Mark outliers
data_bisnis <- data_bisnis %>%
  mutate(
    is_outlier = ifelse(Quantity < lower_whisker | Quantity > upper_whisker, "Outlier", "Normal")
  )

# ==============================
# 3. Summarize Statistics
# ==============================
stats <- data_bisnis %>%
  summarise(
    Mean = mean(Quantity),
    Q1 = Q1,
    Median = median(Quantity),
    Q3 = Q3,
    Min = min(Quantity),
    Max = max(Quantity),
    Outliers = sum(is_outlier == "Outlier")
  )

# ==============================
# 4. Create Violin Plot with Colored Jitter and Annotations
# ==============================
ggplot(data_bisnis, aes(x = factor(1), y = Quantity)) +
  geom_violin(fill = "skyblue", trim = FALSE) +
  geom_boxplot(width = 0.1, outlier.shape = NA, color = "black") +
  geom_jitter(aes(color = is_outlier), width = 0.1, alpha = 0.6, size = 2) +
  geom_point(data = data_bisnis %>%
               filter(Quantity == stats$Max[[1]] & Quantity <= upper_whisker),
             aes(x = factor(1), y = Quantity),
             color = "red", size = 8) +

  # Annotations via geom_text
  geom_text(data = stats, aes(x = 1.2, y = Mean, label = paste("Mean:", round(Mean, 2))),
            hjust = 0, color = "blue", fontface = "bold") +
  geom_text(data = stats, aes(x = 1.2, y = Q1, label = paste("Q1:", round(Q1, 2))),
            hjust = 0, color = "darkgreen") +
  geom_text(data = stats, aes(x = 1.2, y = Median, label = paste("Median:", round(Median, 2))),
            hjust = 0, color = "purple") +
  geom_text(data = stats, aes(x = 1.2, y = Q3, label = paste("Q3:", round(Q3, 2))),
            hjust = 0, color = "darkgreen") +
  geom_text(data = stats, aes(x = 1.2, y = Min, label = paste("Min:", round(Min, 2))),
            hjust = 0, color = "orange") +
  geom_text(data = stats, aes(x = 1.2, y = Max, label = paste("Max:", round(Max, 2))),
            hjust = 0, color = "orange") +
  geom_text(data = stats, aes(x = 1, y = Max + 0.05 * Max,
                             label = paste("Outliers:", Outliers)),
            color = "red", fontface = "italic", hjust = 0.5) +

  scale_color_manual(values = c("Normal" = "black", "Outlier" = "red")) +

  labs(
    title = "Violin Plot of Quantity with Outlier Highlighted",
    x = NULL,
    y = "Quantity",
    color = "Point Type"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    plot.title = element_text(size = 10, face = "bold"),
    axis.title = element_text(size = 10),
    axis.text = element_text(size = 10),
    legend.position = "right",
    legend.title = element_text(size = 10),
    legend.text = element_text(size = 10)
  )

8.3 Combo

8.3.1 Grouped Bar Chart

# ==============================
# 1. Load Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# 2. Load Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

# ==============================
# 3. Data Summarization
# ==============================
sales_summary <- data_bisnis %>%
  group_by(Product_Category, Region) %>%
  summarise(Total_Sales = sum(Total_Price, na.rm = TRUE), .groups = "drop")

# ==============================
# 4. Plot Grouped Bar Chart
# ==============================
ggplot(sales_summary, aes(x = Product_Category, y = Total_Sales, fill = Region)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  labs(
    title = "Total Sales by Product Category and Region",
    x = "Product Category",
    y = "Total Sales (USD)",
    fill = "Region"
  ) +
  theme_minimal(base_size = 10) +
  theme(
    axis.text.x = element_text(angle = 20, hjust = 1),
    plot.title = element_text(face = "bold", hjust = 0.5)
  )

8.3.2 Ridgeline Plot

# ==============================
# 1. Load Libraries
# ==============================
library(ggridges)
## Warning: package 'ggridges' was built under R version 4.4.3
library(ggplot2)
library(dplyr)
library(scales)

# ==============================
# 2. Filter Valid Data
# ==============================
# Filter out rows where Price_per_Unit is NA, Inf, or NaN
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

data_bisnis_filtered <- data_bisnis %>%
  filter(is.finite(Price_per_Unit))

# ==============================
# 3. Create Ridgeline Plot
# ==============================
ggplot(data_bisnis_filtered, aes(x = Price_per_Unit, y = Region, fill = Region)) +
  geom_density_ridges(alpha = 0.7, scale = 1.2) +
  scale_x_continuous(labels = dollar_format(prefix = "Rp", big.mark = ".", decimal.mark = ",")) +
  labs(
    title = "Distribution of Price per Unit by Region",
    x = "Price per Unit",
    y = "Region"
  ) +
  theme_minimal() +
  theme(legend.position = "none")
## Picking joint bandwidth of 1.7

8.3.3 Boxplot by Category

# ==============================
# 1. Load Required Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# 2. Prepare Data
# ==============================
# Convert Quantity to numeric and remove NA
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)
data_bisnis <- data_bisnis %>%
  mutate(Quantity = as.numeric(Quantity)) %>%
  filter(!is.na(Quantity))

# ==============================
# 3. Create Boxplot
# ==============================
ggplot(data_bisnis, aes(x = Product_Category, y = Quantity, fill = Product_Category)) +
  geom_boxplot(outlier.colour = "red", outlier.shape = 16, outlier.size = 1) +  # Boxplot with red outliers
  labs(
    title = "Boxplot of Quantity by Product Category",
    x = "Product Category",
    y = "Quantity"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 10, face = "bold"),
    axis.title = element_text(size = 10),
    axis.text = element_text(size = 10),
    legend.position = "none"
  )

8.3.4 Lolipop Chart

# ==============================
# 1. Load Required Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# 2. Prepare Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

# Summarize total sales by Product_Category and Region
sales_grouped <- data_bisnis %>%
  group_by(Product_Category, Region) %>%
  summarise(Total_Sales = sum(Total_Price, na.rm = TRUE), .groups = "drop")

# ==============================
# 3. Grouped Lollipop Chart
# ==============================
ggplot(sales_grouped, aes(x = Total_Sales, y = reorder(Product_Category, Total_Sales), color = Region)) +
  geom_segment(aes(x = 0, xend = Total_Sales, y = Product_Category, yend = Product_Category), size = 0.75) +
  geom_point(size = 2) +
  labs(
    title = "Grouped Lollipop Chart",
    x = "Total Sales",
    y = "Product Category"
  ) +
  theme_minimal() +
  theme(
    axis.text = element_text(size = 9),
    axis.title = element_text(size = 9),
    plot.title = element_text(size = 9, face = "bold")
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

8.3.5 Heatmap

library(dplyr)
library(ggplot2)

# Hitung agregat total sales
agg_data <- data_bisnis %>%
  group_by(Region, Product_Category) %>%
  summarise(Total_Sales = sum(Total_Price, na.rm = TRUE)) %>%
  ungroup()
## `summarise()` has grouped output by 'Region'. You can override using the
## `.groups` argument.
# Heatmap 
ggplot(agg_data, aes(x = Product_Category, y = Region, fill = Total_Sales)) +
  geom_tile(color = "white", linewidth = 0.7) +
  geom_text(aes(label = round(Total_Sales, 0)), color = "black", size = 4) +
  scale_fill_gradient(
    low = "#cce5ff",   # soft peach
    high = "#003f5c",  # deep coral
    name = "Total Sales"
  ) +
  labs(
    title = "Heatmap Penjualan dengan Penanda Outlier",
    x = "Kategori Produk",
    y = "Wilayah"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    panel.grid = element_blank()
  )


8.4 Relationship

8.4.1 Scatter Plot

# ==============================
# Load Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# Load Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

# ==============================
# Scatter Plot
# ==============================
ggplot(data_bisnis, aes(x = Quantity, y = Total_Price, color = Product_Category)) +
  geom_point(alpha = 0.7, size = 3) +
  labs(
    title = "Relationship between Quantity and Total Price",
    x = "Quantity Sold",
    y = "Total Price (USD)",
    color = "Product Category"
  ) +
  theme_minimal(base_size = 10) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5)
  )

8.4.2 Bubble Chart

# ==============================
# Load Libraries
# ==============================
library(ggplot2)
library(dplyr)

# ==============================
# Load Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

# ==============================
# Bubble Chart
# ==============================
# Bubble chart
ggplot(data_bisnis, aes(x = Unit_Price, y = Total_Price,
                 size = Quantity, color = Product_Category)) +
  geom_point(alpha = 0.5) +
  scale_size_continuous(range = c(3, 7)) +
  labs(title = "Bubble Chart: Harga Satuan, Total Harga, dan Kuantitas",
       x = "Harga Satuan (Unit_Price)",
       y = "Total Harga (Total_Price)",
       color = "Kategori Produk",
       size = "Jumlah Produk") +
 theme_minimal()

8.4.3 Correlation Matrix

# ==============================
# Load Libraries
# ==============================
library(ggplot2)
library(dplyr)
library(tidyr)
## Warning: package 'tidyr' was built under R version 4.4.2
# ==============================
# Load Data
# ==============================
data_bisnis <- read.csv("data_bisnis.csv", stringsAsFactors = FALSE)

# ==============================
# Hitung Korelasi (Numerik Saja)
# ==============================
data_numerik <- data_bisnis %>% select(where(is.numeric))
cor_matrix <- round(cor(data_numerik, use = "complete.obs"), 2)
## Warning in cor(data_numerik, use = "complete.obs"): the standard deviation is
## zero
# Ubah ke format long untuk ggplot
cor_long <- as.data.frame(as.table(cor_matrix))
colnames(cor_long) <- c("Var1", "Var2", "Correlation")

# ==============================
# Plot Correlation Matrix dengan ggplot
# ==============================
ggplot(cor_long, aes(x = Var1, y = Var2, fill = Correlation)) +
  geom_tile(color = "blue") +
  scale_fill_gradient2(
    low = "#d73027", high = "#1a9850", mid = "pink",
    midpoint = 0, limit = c(-1, 1), space = "Lab", 
    name = "Correlation"
  ) +
  geom_text(aes(label = Correlation), color = "red", size = 3.0) +
  labs(title = "Correlation Matrix") +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
    plot.title = element_text(face = "bold", hjust = 0.5)
  )
## Warning: Removed 28 rows containing missing values or values outside the scale range
## (`geom_text()`).

8.5 Time Series

8.5.1 Line

library(dplyr)
library(ggplot2)
library(lubridate)
## Warning: package 'lubridate' was built under R version 4.4.3
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
# Step 1: Hitung Total Sales dan ubah tanggal ke format Date
data_bisnis <- data_bisnis %>%
  mutate(
    Transaction_Date = as.Date(Transaction_Date),
    Total_Sales = Unit_Price * Quantity
  )

# Step 2: Ringkas total sales per tanggal
sales_by_date <- data_bisnis %>%
  group_by(Transaction_Date) %>%
  summarise(Total_Sales = sum(Total_Sales, na.rm = TRUE), .groups = "drop")

# Step 3: Buat line chart
ggplot(sales_by_date, aes(x = Transaction_Date, y = Total_Sales)) +
  geom_line(color = "steelblue", size = 1) +
  labs(
    title = "Line Chart of Total Sales Over Time",
    x = "Transaction Date",
    y = "Total Sales"
  ) +
  theme_minimal(base_size = 10)

8.5.2 Area

library(dplyr)
library(ggplot2)
library(lubridate)

# Step 1: Tambahkan kolom Total Sales dan ubah tanggal ke format Date
data_bisnis <- data_bisnis %>%
  mutate(
    Transaction_Date = as.Date(Transaction_Date),
    Total_Sales = Unit_Price * Quantity
  )

# Step 2: Ringkas total sales per tanggal
sales_by_date <- data_bisnis %>%
  group_by(Transaction_Date) %>%
  summarise(Total_Sales = sum(Total_Sales, na.rm = TRUE), .groups = "drop")

# Step 3: Buat area chart
ggplot(sales_by_date, aes(x = Transaction_Date, y = Total_Sales)) +
  geom_area(fill = "skyblue", alpha = 0.6) +
  labs(
    title = "Area Chart of Total Sales Over Time",
    x = "Transaction Date",
    y = "Total Sales"
  ) +
  theme_minimal(base_size = 10)

sales_by_date_cat <- data_bisnis %>%
  group_by(Transaction_Date, Product_Category) %>%
  summarise(Total_Sales = sum(Total_Sales, na.rm = TRUE), .groups = "drop")

ggplot(sales_by_date_cat, aes(x = Transaction_Date, y = Total_Sales, fill = Product_Category)) +
  geom_area(alpha = 0.6, position = "stack") +
  labs(
    title = "Stacked Area Chart of Total Sales by Product Category",
    x = "Transaction Date",
    y = "Total Sales",
    fill = "Product Category"
  ) +
  theme_minimal(base_size = 10)