Visualisasi Data dengan Matplotlib
Selain statistik, visualisasi data juga memiliki peran penting dalam kegiatan analisis. Untuk keperluan tersebut, pada chapter ini kita akan belajar menggunakan module eksternal matplotlib untuk membuat berbagai macam visualisasi data.
Untuk melakukan instalasi module Matplotlib, buka program CMD.exe Prompt
lewat Anaconda Navigator, lalu jalankan perintah di bawah ini:
conda install matplotlib
Setelah itu, jalankan aplikasi Spyder dari Anaconda Navigator dan tulis kode di bawah ini untuk melakukan impor module Matplotlib:
import matplotlib.pyplot as plt
Pada chapter ini, kita akan menggunakan data jumlah COVID-19 di negara-negara EU per hari tahun 2020-20221. Data dapat di akses melalui website resmi European Centre for Disease Prevention and Control.
Line plot
Diagram garis atau line plot adalah salah satu bentuk visualisasi untuk data yang memiliki tren atau berkaitan dengan waktu. Contoh berikut adalah kode untuk membuat visualisasi tren jumlah kasus COVID-19 per bulan pada tahun 2020 di negara Belgium
dalam bentuk line plot:
# Contoh 1.1
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
# Step 1: filtering data
df_filtered = df[(df['countriesAndTerritories'] == 'Belgium') & (df['year'] == 2020)]
# Step 2: grouping 'month' dan aggregate
cases_bymonth = df_filtered.groupby(['month']).agg(cases = ('cases', 'sum')).reset_index()
# Step 3: inisialisasi plot
fig, ax = plt.subplots()
ax.plot(cases_bymonth['month'], cases_bymonth['cases'])
# Step 4: penambahan label x dan y axis
ax.set_xlabel('Month')
ax.set_ylabel('Cases')
# Step 5: penambahan judul plot
ax.set_title('Trend of COVID-19 cases in Belgium (2020)')
Ada beberapa step yang terlihat pada Contoh 1.1. Pembahasan per step adalah sebagai berikut:
- Step 1: Kita membatasi visualisasi hanya untuk negara
Belgium
dan tahun2020
saja. Sehingga pada step ini, kita melakukan filtering terhadap data aslinya. - Step 2: Karena data kasus COVID-19 masih dalam format per hari, maka kita perlu menjumlahkan tiap kasus per hari (agg sum) pada tiap bulan (groupby month).
- Step 3: Inisialisasi plot. Fungsi
plot
menerima parameter pertama berupa list pada x axis, dan parameter kedua berupa list pada y axis. - Step 4: Penambahan label untuk
x
axis dany
axis. - Step 5: Penambahan judul plot dapat menggunakan fungsi
set_title
.
Plot yang dihasilkan dari Contoh 1.1 akan terlihat seperti gambar di bawah ini:
Apabila diperhatikan, angka ‘Month’ pada x axis tidak dimunculkan semua pada plot. Kita bisa memodifikasi kode pada Contoh 1.1 untuk menampilkan semua angka ‘Month’ pada x axis menjadi seperti contoh berikut:
# Contoh 1.2
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker # penambahan impor module `matplotlib.ticker`
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[(df['countriesAndTerritories'] == 'Belgium') & (df['year'] == 2020)]
cases_bymonth = df_filtered.groupby(['month']).agg(cases = ('cases', 'sum')).reset_index()
fig, ax = plt.subplots()
ax.plot(cases_bymonth['month'], cases_bymonth['cases'])
ax.set_xlabel('Month')
ax.set_ylabel('Cases')
ax.set_title('Trend of COVID-19 cases in Belgium (2020)')
# Penambahan FixedLocator dengan parameter list yang sama dengan parameter x axis pada inisiasi plot
ax.xaxis.set_major_locator(ticker.FixedLocator(cases_bymonth['month']))
Plot yang dihasilkan dari Contoh 1.2 akan terlihat seperti gambar di bawah ini:
Scatter plot 2D
Scatter plot biasanya digunakan untuk memvisualisasikan hubungan antar variable pada data. Berbeda dengan line plot, visualisasi data pada scatter plot sifatnya lebih general, tidak selalu berorientasi terhadap waktu.
Masih menggunakan data COVID-19, Contoh 2.1 memperlihatkan pembuatan scatter plot 2 dimensi. Perbedaan dengan sebelumnya, scatter plot pada Matplotlib diinisialisasi menggunakan fungsi scatter
.
# Contoh 2.1
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[(df['countriesAndTerritories'] == 'Belgium') & (df['year'] == 2020)]
cases_bymonth = df_filtered.groupby(['month']).agg(cases = ('cases', 'sum')).reset_index()
fig, ax = plt.subplots()
# Inisialisasi scatter plot
ax.scatter(cases_bymonth['month'], cases_bymonth['cases'])
ax.set_xlabel('Month')
ax.set_ylabel('Cases')
ax.set_title('Trend of COVID-19 cases in Belgium (2020)')
ax.xaxis.set_major_locator(ticker.FixedLocator(cases_bymonth['month']))
Plot yang dihasilkan Contoh 2.1 akan terlihat seperti gambar di bawah ini:
Bar plot
Seperti halnya scatter plot, Bar plot juga digunakan untuk memvisualisasikan hubungan antar variable. Bedanya, pada bar plot visualisasi dibuat menjadi bentuk balok-balok. Contoh di bawah ini memperlihatkan cara membuat bar plot dengan menggunakan fungsi bar
:
# Contoh 3.1
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[(df['countriesAndTerritories'] == 'Belgium') & (df['year'] == 2020)]
cases_bymonth = df_filtered.groupby(['month']).agg(cases = ('cases', 'sum')).reset_index()
fig, ax = plt.subplots()
# Inisialisasi bar plot
ax.bar(cases_bymonth['month'], cases_bymonth['cases'])
ax.set_xlabel('Month')
ax.set_ylabel('Cases')
ax.set_title('Trend of COVID-19 cases in Belgium (2020)')
ax.xaxis.set_major_locator(ticker.FixedLocator(cases_bymonth['month']))
Plot yang dihasilkan Contoh 3.1 akan terlihat seperti gambar di bawah ini:
Histogram
Histogram adalah salah satu bentuk visualisasi yang sering digunakan untuk menggambarkan distribusi dari suatu data. Kode berikut memperlihatkan cara membuat visualisasi histogram dari data COVID-19.
# Contoh 4.1
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[df['countriesAndTerritories'] == 'Belgium']
fig, ax = plt.subplots()
ax.hist(df_filtered['cases'])
Histogram yang dihasilkan Contoh 4.1 akan terlihat seperti gambar di bawah ini:
Histogram di atas memperlihatkan distribusi yang skewed. Untuk melihat bentuk dari distribusi secara lebih detail, kita juga bisa melakukan pengaturan terhadap parameter bins
. Perhatikan Contoh 4.1 dan hasil outputnya:
# Contoh 4.2
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[df['countriesAndTerritories'] == 'Belgium']
fig, ax = plt.subplots()
ax.hist(df_filtered['cases'], bins = 20)
Selain itu, kita juga bisa melakukan kontrol terhadap batas tampilan histogram pada x dan y axis seperti Contoh 4.3:
# Contoh 4.3
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[df['countriesAndTerritories'] == 'Belgium']
fig, ax = plt.subplots()
ax.hist(df_filtered['cases'], bins = 30)
ax.set(xlim=(0, 20000), ylim=(0, 500))
Box plot
Selain histogram, analisis distribusi data juga dapat dilakukan melalui visualisasi box plot.
# Contoh 5.1
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[df['countriesAndTerritories'].isin(['Luxembourg', 'Belgium', 'Netherlands'])]
fig, ax = plt.subplots()
ax.boxplot(df_filtered['cases'])
Pada output Contoh 5.1, terlalu banyak data outliers sehingga distribusinya kurang terlihat dengan jelas. Untuk memperbaiki visualisasi, kita juga bisa mengatur limit pada y axis seperti di bawah ini:
# Contoh 5.2
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[df['countriesAndTerritories'].isin(['Luxembourg', 'Belgium', 'Netherlands'])]
fig, ax = plt.subplots()
ax.boxplot(df_filtered['cases'])
ax.set(ylim=(0, 20000))
Selain itu, kita juga bisa menampilkan boxplot per kategori (negara). Perhatikan contoh di bawah ini:
# Contoh 5.3
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[df['countriesAndTerritories'].isin(['Luxembourg', 'Belgium', 'Netherlands'])]
fig, ax = plt.subplots()
df_filtered.boxplot(column=['cases'], by='countriesAndTerritories', ax=ax)
ax.set(ylim=(0, 20000))
Pada Contoh 5.3, kita melakukan pemanggilan fungsi boxplot
dari object DataFrame
, bukan dari object ax
. Hal ini digunakan agar kita bisa mengontrol grouping boxplot melalui parameter by
.
Membuat beberapa plot dalam satu diagram
Sebelumnya kita sudah sempat belajar membuat beberapa boxplot dalam satu diagram. Kita juga bisa menghasilkan hal yang serupa untuk tipe plot yang lain. Misalkan, kita bisa menampilkan beberapa line plot pada satu diagram seperti pada contoh berikut:
# Contoh 6.1
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[(df['countriesAndTerritories'].isin(['Luxembourg', 'Belgium', 'Netherlands'])) & (df['year'] == 2020)]
cases_bymonth = df_filtered.groupby(['countriesAndTerritories', 'month']).agg(cases = ('cases', 'sum')).reset_index()
df_lux = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Luxembourg']
df_bel = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Belgium']
df_nld = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Netherlands']
fig, ax = plt.subplots()
ax.plot(df_lux['month'], df_lux['cases'], label = 'Luxembourg')
ax.plot(df_bel['month'], df_bel['cases'], label = 'Belgium')
ax.plot(df_nld['month'], df_nld['cases'], label = 'Netherlands')
ax.set_xlabel('Month')
ax.set_ylabel('Cases')
ax.set_title('Trend of COVID-19 cases in Belgium (2020)')
ax.legend()
Pada Contoh 6.1, kita melakukan filtering untuk memperoleh DataFrame
per negara. Setelah mendapatkan DataFrame
yang diinginkan, seperti biasa kita menggunakan fungsi plot
untuk membuat visualisasi line plot. Bedanya, kita melakukan pemanggilan fungsi plot
berkali-kali dengan DataFrame
yang berbeda untuk tiap negara.
Tentu saja, kita juga bisa membuat visualisasi yang serupa untuk scatter plot dengan menggunakan fungsi scatter
seperti contoh berikut:
# Contoh 6.2
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[(df['countriesAndTerritories'].isin(['Luxembourg', 'Belgium', 'Netherlands'])) & (df['year'] == 2020)]
cases_bymonth = df_filtered.groupby(['countriesAndTerritories', 'month']).agg(cases = ('cases', 'sum')).reset_index()
df_lux = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Luxembourg']
df_bel = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Belgium']
df_nld = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Netherlands']
fig, ax = plt.subplots()
ax.(df_lux['month'], df_lux['cases'], label = 'Luxembourg')
ax.scatter(df_bel['month'], df_bel['cases'], label = 'Belgium')
ax.scatter(df_nld['month'], df_nld['cases'], label = 'Netherlands')
ax.set_xlabel('Month')
ax.set_ylabel('Cases')
ax.set_title('Trend of COVID-19 cases in Belgium (2020)')
ax.legend()
Apabila kita ingin membuat tiap plot menjadi diagram yang terpisah, kita bisa mengikuti contoh di bawah ini:
# Contoh 6.3
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('https://opendata.ecdc.europa.eu/covid19/nationalcasedeath_eueea_daily_ei/csv/data.csv', delimiter = ',')
df_filtered = df[(df['countriesAndTerritories'].isin(['Luxembourg', 'Belgium', 'Netherlands'])) & (df['year'] == 2020)]
cases_bymonth = df_filtered.groupby(['countriesAndTerritories', 'month']).agg(cases = ('cases', 'sum')).reset_index()
# 1. Filter berdasarkan negara
df_lux = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Luxembourg']
df_bel = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Belgium']
df_nld = cases_bymonth[cases_bymonth['countriesAndTerritories'] == 'Netherlands']
# 2. Inisiasi plot dengan 3 baris
fig, axs = plt.subplots(nrows=3, sharex=True, sharey=True)
# 3. Membuat plot untuk tiap data negara + label
axs[0].plot(df_lux['month'], df_lux['cases'], label = 'Luxembourg')
axs[1].plot(df_bel['month'], df_bel['cases'], label = 'Belgium')
axs[2].plot(df_nld['month'], df_nld['cases'], label = 'Netherlands')
# 4. Setup label x dan y axis + legend
for ax in axs.flat:
ax.set_xlabel('Month')
ax.set_ylabel('Cases')
ax.label_outer()
ax.legend()
# 5. Set title
fig.suptitle('Trend of COVID-19 cases in Belgium (2020)')
Ada beberapa hal yang perlu diperhatikan pada Contoh 6.3:
- Setelah melakukan agregasi, kita perlu memisahkan
DataFrame
berdasarkan negara. Pada contoh, setiap negara dibuatkan variableDataFrame
-nya sendiri, sehingga menghasilkan 3 variable baru. - Pemanggilan fungsi
subplots
perlu ditambahkan parameter, yaitunrows=3
untuk menentukan berapa baris plot yang kita inginkan, lalusharex=True
dansharey=True
untuk mengeset skala axis agar seragam untuk semua plot. - Setelah inisiasi, variable
axs
akan berubah menjadi list. Kita bisa mengeset plot dengan semua variableDataFrame
yang sudah kita buat sebelumnya pada list tersebut. Parameterlabel
dibutuhkan untuk membedakan antara plot yang satu dengan plot yang lainnya (dalam hal ini kita beri nama sesuai dengan negaranya). - Karena fungsi
set_xlabel
danset_ylabel
akan menggunakan label yang sama untuk semua plot (berulang), di sini kita gunakan looping. Fungsilabel_outer
digunakan untuk membuat label x dan y axis akan tampil hanya satu kali saja, sedangkan fungsilegend
digunakan untuk menampilkan legenda pada plot. - Untuk menambahkan judul untuk kumpulan plot, kita dapat menggunakan fungsi
suptitle
pada objekfig
.
Hasil akhirnya dapat dilihat pada gambar di bawah ini:
Footnotes
-
European Centre for Disease Prevention and Control. Data on the daily number of new reported COVID-19 cases and deaths by EU/EEA country (link to website) ↩