Data Analytics Bootcamp

Intro Visualisasi Data

Bakti Siregar, M.Sc., CDSS

LinkedIn | GitHub | Email

Praktisi dan akademisi Data Analytics & Data Science, tersertifikasi Data Scientist (BNSP) dan Certified Data Science Specialist (CDSS) internasional, dengan fokus pada eksplorasi data, analisis terapan, dan pemanfaatan data untuk pengambilan keputusan.


1 Dataset Sampel

1.1 Data 1

1.2 Data 2

2 Bar-Chart

2.1 Don’ts

2.1.1 Basic

library(readxl)   # untuk import Excel

# =====================================================
# Import Data
# =====================================================

# df_csv <- read.csv("data_penjualan.csv", sep = ",", dec = ".", stringsAsFactors = FALSE)
# df_excel <- read_excel("data_penjualan.xlsx", sheet = "Sheet1",skip = 1) # melewatkan baris 1

# =====================================================
# Agregasi total penjualan per produk (36 bulan)
# =====================================================
data1 <- aggregate(Value ~ Produk, data = df1, sum, na.rm = TRUE)

# =====================================================
# Bar chart dasar
# =====================================================
# Membuat warna bar
warna <- c("#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A")

# Membuat barplot
bp <- barplot(
  data1$Value,
  names.arg = data1$Produk,
  col = warna,
  ylim = c(0, max(data1$Value) * 1.2), # beri ruang untuk label
  main = "Total Penjualan per Produk",
  xlab = "Produk",
  ylab = "Total Penjualan"
)

# Menambahkan label nilai di atas bar
text(
  x = bp,
  y = data1$Value,
  labels = round(data1$Value, 0),
  pos = 3, # posisi di atas bar
  cex = 0.8
)

2.1.2 ggplot2

library(ggplot2)
library(dplyr)
library(scales) # untuk format angka

# =====================================================
# Agregasi total penjualan per produk (36 bulan)
# =====================================================
data1 <- df1 %>%
  group_by(Produk) %>%
  summarise(Total_Sales = sum(Value, na.rm = TRUE)) %>%
  ungroup()

# =====================================================
# Bar chart menggunakan ggplot2
# =====================================================
ggplot(data1, aes(x = Produk, y = Total_Sales, fill = Produk)) +
  geom_col(show.legend = FALSE) +
  geom_text(aes(label = scales::comma(round(Total_Sales,0))),
            vjust = -0.5, size = 4) +  # posisi label di atas bar
  scale_fill_manual(values = c("#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A")) +
  labs(title = "Total Penjualan per Produk",
       x = "Produk",
       y = "Total Penjualan") +
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(hjust = 0.5),
    axis.text.x = element_text(angle = 0, hjust = 0.5)
  )

2.1.3 Plotly

library(plotly)
library(dplyr)

# =====================================================
# Pastikan Struktur datanya dalah dataframe
# =====================================================
# df1 <- df_csv %>% as.data.frame() %>% select(-1)   # hapus kolom pertama
# df1 <- df_excel %>% as.data.frame() %>% select(-1)   # hapus kolom pertama


# =====================================================
# Agregasi total penjualan per produk (36 bulan)
# =====================================================
data1 <- df1 %>%
  group_by(Produk) %>%
  summarise(Total_Sales = sum(Value, na.rm = TRUE)) %>%
  ungroup()

# =====================================================
# Revisi Bar Chart dengan warna soft dan label nilai
# =====================================================
barchart <- plot_ly(
  data1,
  x = ~Produk,
  y = ~Total_Sales,
  type = 'bar',
  text = ~round(Total_Sales,0),
  textposition = 'outside',
  marker = list(color = c("#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A"))
) %>%
  layout(
    title = list(text = "Total Penjualan per Produk", x = 0.5),
    xaxis = list(title = "Produk"),
    yaxis = list(title = "Total Penjualan"),
    showlegend = FALSE,
    uniformtext=list(minsize=10, mode='hide')
  )

barchart

2.2 Do’s

2.3 Do’s vs Don’ts (Bar-chart)

Aspek Don’ts Do’s
Jumlah Kategori Jangan tampilkan terlalu banyak kategori (lebih dari 10-15). Gunakan 5-10 kategori untuk menjaga chart tetap jelas dan terfokus.
Urutan Bar Jangan biarkan bar tidak terurut atau acak. Urutkan bar dari yang terbesar ke terkecil (atau sesuai logika data).
Warna Hindari penggunaan warna yang berlebihan atau tidak konsisten. Gunakan warna yang konsisten dan sederhana untuk membedakan kategori.
Label Sumbu Jangan tinggalkan sumbu X dan Y tanpa label atau deskripsi yang jelas. Sertakan label yang jelas pada sumbu X dan Y untuk pemahaman yang lebih baik.
Judul Jangan biarkan chart tanpa judul yang menggambarkan data dengan tepat. Berikan judul yang informatif dan menggambarkan isi chart.
Skala Sumbu Y Hindari penggunaan skala yang tidak konsisten atau tidak dimulai dari nol. Pastikan skala sumbu Y konsisten dan dimulai dari nol untuk akurasi.
Label Nilai pada Bar Jangan lupa menambahkan label atau nilai pada bar jika diperlukan. Sertakan nilai atau label pada bar untuk memudahkan interpretasi.

3 Pie-Chart

3.1 Don’ts

3.1.1 Basic

# =====================================================
# Agregasi total penjualan per produk
# =====================================================
data1 <- aggregate(Value ~ Produk, data = df1, sum, na.rm = TRUE)
data1$Fraction <- data1$Value / sum(data1$Value)
data1$Percent <- round(data1$Fraction * 100, 1)
data1$Label <- paste0(data1$Produk, "\n", data1$Percent, "%")

# =====================================================
# Warna lembut (mirip Plotly)
# =====================================================
colors_soft <- c("#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A")

# =====================================================
# Donut chart dasar tanpa library
# =====================================================
# Buat pie chart
pie(
  data1$Value,
  labels = data1$Label,
  col = colors_soft,
  border = "white",
  clockwise = TRUE,
  main = "Persentasi Penjualan Produk Terlaris di E-commerce",
  cex = 0.8
)

# Tambahkan lubang di tengah untuk efek donut
# Caranya: gambar lingkaran putih di tengah
symbols(0, 0, circles = 0.5, inches = FALSE, add = TRUE, bg = "white")

3.1.2 ggplotl2

library(dplyr)
library(ggplot2)
library(scales)

# =====================================================
# Agregasi total penjualan per produk
# =====================================================
data1 <- df1 %>%
  group_by(Produk) %>%
  summarise(Total_Sales = sum(Value, na.rm = TRUE)) %>%
  ungroup() %>%
  mutate(
    Fraction = Total_Sales / sum(Total_Sales),
    Percent = Fraction * 100
  )

# Warna lembut (sama seperti Plotly)
colors_soft <- c("#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A")

# =====================================================
# Donut chart ggplot2 mirip Plotly
# =====================================================
ggplot(data1, aes(x = 2, y = Fraction, fill = Produk)) +
  geom_bar(stat = "identity", color = "white", width = 1) +
  coord_polar(theta = "y") +
  xlim(0.5, 2.5) +  # buat lubang donut (hole = 0.4 kira-kira)
  geom_text(aes(label = paste0(Produk, "\n", round(Percent,1), "%")),
            position = position_stack(vjust = 0.5), size = 4, color = "white", fontface = "bold") +
  scale_fill_manual(values = colors_soft) +
  labs(title = "Persentasi Penjualan Produk Terlaris di E-commerce") +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5),
    legend.title = element_blank(),
    legend.position = "right"
  )

3.1.3 plotly

library(plotly)
library(dplyr)

# =====================================================
# Donut chart Plotly dengan warna soft dan label persentase
# =====================================================
colors_soft <- c("#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A")

fig <- plot_ly(
  data1,
  labels = ~Produk,
  values = ~Total_Sales,
  type = 'pie',
  hole = 0.4,  # ukuran lubang donut
  textinfo = 'label+percent',
  insidetextorientation = 'radial',
  marker = list(colors = colors_soft, line = list(color = '#FFFFFF', width = 2))
) %>%
  layout(
    title = list(text = "Persentasi Penjualan Produk Terlaris di E-commerce", x = 0.5),
    showlegend = TRUE
  )

fig

3.2 Do’s

3.3 Do’s vs Don’ts (Pie Chart)

Aspek Don’ts Do’s
Jumlah Kategori Hindari lebih dari 6 kategori. Gunakan 4-6 kategori agar chart tetap jelas dan mudah dipahami.
Warna Jangan gunakan warna yang terlalu mencolok atau tidak kontras. Pilih warna yang cukup kontras tetapi harmonis agar mudah dibedakan.
Label dan Persentase Jangan tinggalkan label atau persentase pada potongan. Selalu beri label dan persentase agar audiens tahu kontribusi setiap kategori.
Urutan Kategori Hindari kategori yang tidak terurut atau tidak logis. Urutkan kategori sesuai logika atau ukuran untuk memudahkan perbandingan.
Potongan Terlalu Kecil Jangan tampilkan kategori dengan kontribusi sangat kecil sebagai potongan terpisah. Gabungkan kategori kecil ke dalam kategori “Lainnya” jika perlu.
Efek 3D dan Elemen Berlebihan Hindari efek 3D atau elemen dekoratif yang tidak perlu. Gunakan desain yang sederhana dan jelas untuk menghindari gangguan visual.

4 Line-chart

4.1 Don’ts

4.1.1 Basic

# -----------------------------
# 3. Filter baris untuk Produk E
# -----------------------------
produk_target <- "Produk_E"

df_e <- df1 %>%
  filter(Produk == produk_target) %>%
  arrange(Tanggal)

# Cek ada data atau tidak
if(nrow(df_e) == 0) stop(paste("Data untuk", produk_target, "tidak ditemukan!"))

tanggal_list <- df_e$Tanggal
value_matrix <- matrix(df_e$Value, ncol = 1)
warna <- "#636EFA"

# -----------------------------
# 4. Plot kosong
# -----------------------------
par(mar = c(7, 4, 4, 2) + 0.1)  # margin bawah lebih besar

ymax <- max(value_matrix, na.rm = TRUE) * 1.1
xmin <- min(tanggal_list)
xmax <- max(tanggal_list)

plot(NA, NA, xlim = c(xmin, xmax), ylim = c(0, ymax),
     xlab = "", ylab = "Penjualan",
     main = "Analisis Pola Penjualan Produk E",
     xaxt = "n")

# -----------------------------
# 5. Garis + marker perkecil 0.8
# -----------------------------
matplot(tanggal_list, value_matrix, type = "b", pch = 19, col = warna,
        lty = 1, lwd = 2, cex = 0.8, add = TRUE)

# -----------------------------
# 6. Label X miring 45°
# -----------------------------
labels <- format(tanggal_list, "%b-%Y")
ypos <- par("usr")[3] - 0.05 * diff(par("usr")[3:4])
text(x = tanggal_list, y = ypos, labels = labels, srt = 45, adj = 1, xpd = TRUE)
abline(h = par("usr")[3], col = "black")
mtext("Tanggal", side = 1, line = 5, cex = 1)

# -----------------------------
# 7. Legend
# -----------------------------
legend("topleft",
       legend = "Produk E",
       col = warna,
       lty = 1,
       lwd = 2,
       pch = 19,
       pt.cex = 1.5,
       bty = "n")

# =====================================================
# Atur margin agar label X cukup ruang
# =====================================================
par(mar = c(7, 4, 4, 2) + 0.1)  # bottom, left, top, right

# Daftar produk unik dan warna
produk_list <- unique(df1$Produk)
warna <- c("#636EFA", "#EF553B", "#00CC96", "#AB63FA", "#FFA15A")

# Range plot
ymax <- max(df1$Value, na.rm = TRUE) * 1.1
xmin <- min(df1$Tanggal)
xmax <- max(df1$Tanggal)

# Buat plot kosong tanpa sumbu X
plot(NA, NA, xlim = c(xmin, xmax), ylim = c(0, ymax),
     xlab = "", ylab = "Penjualan",
     main = "Analisis Pola Penjualan Produk",
     xaxt = "n")

# =====================================================
# Tambahkan garis + marker per produk
# =====================================================
for (i in seq_along(produk_list)) {
  prod <- produk_list[i]
  data_prod <- df1[df1$Produk == prod, ]
  data_prod <- data_prod[order(data_prod$Tanggal), ]
  
  # Garis
  lines(data_prod$Tanggal, data_prod$Value, type = "l", col = warna[i], lwd = 2)
  # Marker
  points(data_prod$Tanggal, data_prod$Value, col = warna[i], pch = 19, cex = 1.5)
}

# =====================================================
# Tambahkan sumbu X manual dengan label miring 45°
# =====================================================
dates <- df1$Tanggal
labels <- format(dates, "%b-%Y")

# posisi sumbu Y untuk label
ypos <- par("usr")[3] - 0.05 * diff(par("usr")[3:4])  # sedikit di bawah plot

# Tambahkan label miring
text(x = dates, y = ypos, labels = labels, srt = 45, adj = 1, xpd = TRUE)

# Tambahkan garis horizontal sumbu X
abline(h = par("usr")[3], col = "black")

# Tambahkan xlabel “Tanggal” lebih rendah
mtext("Tanggal", side = 1, line = 5, cex = 1)

# =====================================================
# Tambahkan legenda
# =====================================================
legend("topleft", legend = produk_list, col = warna[1:length(produk_list)],
       lty = 1, lwd = 2, pch = 19, pt.cex = 1.5, bty = "n")

4.1.2 ggplot2

library(dplyr)
library(ggplot2)

# =====================================================
# Data: df1 dengan kolom Tanggal, Value, Produk
# =====================================================

# Buat ggplot2 line + marker
ggplot(df1, aes(x = Tanggal, y = Value, color = Produk, group = Produk)) +
  geom_line(size = 1) +           # garis
  geom_point(size = 1.5) +        # marker, bisa disesuaikan
  scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +  # y mulai dari 0
  labs(
    title = "Analisis Pola Penjualan Produk",
    x = "Tanggal",
    y = "Penjualan",
    color = "Produk"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(hjust = 0.5),
    axis.text.x = element_text(angle = -60, hjust = 0)
  )
## 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.

4.1.3 plotly

library(plotly)   # visualisasi data
library(dplyr)    # untuk manipulasi data
# Plot interaktif menggunakan Plotly
fig <- plot_ly(
  df1,
  x = ~Tanggal,
  y = ~Value,
  color = ~Produk,
  type = 'scatter',
  mode = 'lines+markers',
  text = ~paste(
    "Produk:", Produk,
    "<br>Tanggal:", format(Tanggal, "%b-%Y"),
    "<br>Penjualan:", round(Value, 2)
  ),
  hoverinfo = "text"
) %>%
  layout(
    title = list(text = "Analisis Pola Penjualan Produk", x = 0.5),
    xaxis = list(
      title = "Tanggal",
      tickformat = "%b-%y",
      tickangle = -60
    ),
    yaxis = list(
      title = "Penjualan",
      rangemode = "tozero"   # <- ini membuat Y-axis mulai dari 0
    ),
    legend = list(title = list(text = "<b>Produk</b>"))
  )

fig

4.2 Do’s

4.3 Do’s vs Don’ts (Line Chart)

Aspek Don’ts Do’s
Jumlah Seri Jangan menampilkan terlalu banyak garis sekaligus (>5–6), membuat plot membingungkan. Batasi 2–5 seri utama, atau pisahkan menjadi beberapa plot agar jelas.
Warna Garis Jangan gunakan warna yang terlalu mirip atau terlalu mencolok. Gunakan warna kontras yang harmonis untuk membedakan setiap garis.
Marker/Titik Jangan biarkan marker terlalu besar atau hilang sepenuhnya. Gunakan marker kecil tapi terlihat, cukup untuk menandai data penting.
Label Sumbu & Judul Jangan tinggalkan sumbu atau judul, atau gunakan label yang ambigu. Berikan label sumbu jelas, judul plot informatif, dan satuan jika perlu.
Skala Sumbu Jangan biarkan skala Y tidak dimulai dari nol jika relevan, atau tidak proporsional. Sesuaikan skala Y agar data mudah dibandingkan, gunakan “rangemode = tozero” bila perlu.
Grid & Garis Bantu Jangan hilangkan grid sepenuhnya jika data sulit dibaca. Gunakan grid ringan untuk membantu membaca nilai tanpa mengganggu visual.
Line Style & Ketebalan Jangan gunakan semua garis tebal atau tipis sama; semua lurus polos tanpa variasi. Variasikan ketebalan/linetype jika perlu menekankan seri tertentu.
Overplotting Jangan tumpuk terlalu banyak titik/garis sehingga sulit dibedakan. Gunakan marker hanya pada titik penting, atau gunakan transparansi/warna untuk membedakan.