Kursus
Pendahuluan
Menurut Wikipedia, histogram adalah representasi grafis yang akurat dari distribusi data numerik. Ini adalah perkiraan distribusi probabilitas dari variabel kontinu (variabel kuantitatif) dan pertama kali diperkenalkan oleh Karl Pearson. Histogram merupakan jenis grafik batang. Untuk membangun histogram, langkah pertama adalah melakukan “binning” pada rentang nilai — yakni membagi seluruh rentang nilai menjadi serangkaian interval — lalu menghitung berapa banyak nilai yang jatuh ke tiap interval. Bin biasanya ditentukan sebagai interval berurutan yang tidak saling tumpang tindih dari suatu variabel. Bin (interval) harus saling berdampingan dan sering kali (meskipun tidak wajib) berukuran sama.
Selain untuk data numerik, histogram juga dapat digunakan untuk memvisualisasikan distribusi citra, karena citra tidak lain adalah gabungan elemen gambar (piksel) yang nilainya berkisar dari $0$ hingga $255$. Sumbu-x histogram menunjukkan jumlah bin sementara sumbu-y merepresentasikan frekuensi dari suatu bin tertentu. Jumlah bin adalah parameter yang dapat diubah sesuai dengan cara Anda ingin memvisualisasikan distribusi data.
Contoh: Misalkan Anda ingin membuat histogram dari citra RGB yang memiliki nilai piksel antara $0$ hingga $255$. Jumlah bin maksimum yang dapat dimiliki citra ini adalah $255$. Jika Anda menetapkan x_axis (jumlah bin) sebagai $255$, maka y_axis akan menunjukkan frekuensi tiap piksel pada citra tersebut.
Histogram mirip secara prinsip dengan grafik bar. Mari lihat satu contoh gambar histogram:

Histogram adalah alat yang sangat baik untuk memvisualisasikan dan memahami distribusi probabilistik dari data numerik atau data citra yang dapat dipahami secara intuitif oleh hampir semua orang. Python memiliki banyak opsi untuk membangun dan memplot histogram. Python memiliki beberapa pustaka bawaan untuk membuat grafik, dan salah satunya adalah matplotlib.
Dalam tutorial hari ini, Anda akan terutama menggunakan matplotlib untuk membuat dan memvisualisasikan histogram pada berbagai jenis set data.
Jadi tanpa berlama-lama, mari kita mulai.
Memplot Histogram menggunakan NumPy dan Matplotlib
import numpy as np
Demi reprodusibilitas, Anda akan menggunakan fungsi seed dari numPy, yang akan memberikan keluaran yang sama setiap kali dijalankan.
Anda akan memplot histogram dari gaussian (normal) distribution, yang memiliki mean $0$ dan simpangan baku $1$.
np.random.seed(100)
np_hist = np.random.normal(loc=0, scale=1, size=1000)
np_hist[:10]
array([-1.74976547, 0.3426804 , 1.1530358 , -0.25243604, 0.98132079,
0.51421884, 0.22117967, -1.07004333, -0.18949583, 0.25500144])
Mari verifikasi mean dan simpangan baku dari distribusi di atas.
np_hist.mean(),np_hist.std()
(-0.016772157343909157, 1.0458427194167)
Selanjutnya, Anda akan menggunakan fungsi histogram dari numPy, yang akan mengembalikan hist dan bin_edges.
hist,bin_edges = np.histogram(np_hist)
hist
array([ 7, 37, 111, 207, 275, 213, 105, 31, 10, 4])
bin_edges
array([-3.20995538, -2.50316588, -1.79637637, -1.08958687, -0.38279736,
0.32399215, 1.03078165, 1.73757116, 2.44436066, 3.15115017,
3.85793967])
Berikutnya, mari plot histogram menggunakan fungsi plt.bar dari matplotlib, di mana sumbu-x dan sumbu-y Anda masing-masing adalah bin_edges dan hist.
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=[10,8])
plt.bar(bin_edges[:-1], hist, width = 0.5, color='#0504aa',alpha=0.7)
plt.xlim(min(bin_edges), max(bin_edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Normal Distribution Histogram',fontsize=15)
plt.show()

Mari membulatkan bin_edges ke bilangan bulat.
bin_edges = np.round(bin_edges,0)
plt.figure(figsize=[10,8])
plt.bar(bin_edges[:-1], hist, width = 0.5, color='#0504aa',alpha=0.7)
plt.xlim(min(bin_edges), max(bin_edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Normal Distribution Histogram',fontsize=15)
plt.show()

Sekarang grafiknya terlihat jauh lebih baik, bukan?
Untuk memahami hist dan bin_edges, mari lihat sebuah contoh:
Anda akan mendefinisikan array dengan nilai sembarang dan mendefinisikan bin dengan rentang $5$.
hist, bin_edges = np.histogram([1, 1, 2, 2, 2, 2, 3],bins=range(5))
hist
array([0, 2, 4, 1])
Pada keluaran di atas, hist menunjukkan ada $0$ item pada bin $0$, $2$ pada bin $1$, $4$ pada bin $3$, $1$ pada bin $4$.
bin_edges
array([0, 1, 2, 3, 4])
Demikian pula, keluaran bin_edges di atas berarti bin $0$ berada pada interval $[0,1)$, bin $1$ pada interval $[1,2)$, bin $2$ pada interval $[2,3)$, bin $3$ pada interval $[3,4)$.
Memplot Histogram hanya dengan Matplotlib
Memplot histogram menggunakan matplotlib sangat mudah. Yang perlu Anda lakukan hanyalah menggunakan fungsi plt.hist() dari matplotlib dan memberikan data beserta jumlah bin dan beberapa parameter opsional.
Di plt.hist(), memberikan bins='auto' akan memberi Anda jumlah bin yang “ideal”. Idenya adalah memilih lebar bin yang menghasilkan representasi paling setia dari data Anda.
Itu saja. Jadi, mari plot histogram dari normal_distribution yang Anda buat menggunakan numpy.
plt.figure(figsize=[10,8])
n, bins, patches = plt.hist(x=np_hist, bins=8, color='#0504aa',alpha=0.7, rwidth=0.85)
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Normal Distribution Histogram',fontsize=15)
plt.show()

Memplot dua histogram sekaligus
plt.figure(figsize=[10,8])
x = 0.3*np.random.randn(1000)
y = 0.3*np.random.randn(1000)
n, bins, patches = plt.hist([x, y])

Memplot Histogram Data Iris menggunakan Pandas
Anda akan menggunakan sklearn untuk memuat dataset bernama iris. Di sklearn, ada pustaka bernama datasets yang berisi dataset Iris yang dapat dimuat secara langsung. Jadi, mari cepat muat dataset iris.
from sklearn.datasets import load_iris
import pandas as pd
data = load_iris().data
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width']
Selanjutnya, Anda akan membuat dataframe dari dataset iris.
dataset = pd.DataFrame(data,columns=names)
dataset.head()
| sepal-length | sepal-width | petal-length | petal-width | |
|---|---|---|---|---|
| 0 | 5.1 | 3.5 | 1.4 | 0.2 |
| 1 | 4.9 | 3.0 | 1.4 | 0.2 |
| 2 | 4.7 | 3.2 | 1.3 | 0.2 |
| 3 | 4.6 | 3.1 | 1.5 | 0.2 |
| 4 | 5.0 | 3.6 | 1.4 | 0.2 |
dataset.columns[0]
'sepal-length'
Terakhir, Anda akan menggunakan fungsi bawaan pandas .hist() yang akan memplot histogram untuk semua fitur yang ada dalam dataset.
Bukankah itu luar biasa?
fig = plt.figure(figsize = (8,8))
ax = fig.gca()
dataset.hist(ax=ax)
plt.show()

Petal-length, petal-width, dan sepal-length menunjukkan distribusi unimodal, sedangkan sepal-width mencerminkan kurva Gaussian. Semua ini merupakan analisis yang berguna karena Anda kemudian dapat mempertimbangkan menggunakan algoritme yang bekerja baik dengan jenis distribusi seperti ini.
Plot Histogram dengan Matplotlib
plt.figure(figsize=[10,10])
f,a = plt.subplots(2,2)
a = a.ravel()
for idx,ax in enumerate(a):
ax.hist(dataset.iloc[:,idx], bins='auto', color='#0504aa',alpha=0.7, rwidth=0.85)
ax.set_title(dataset.columns[idx])
plt.tight_layout()
<Figure size 720x720 with 0 Axes>

Memplot Histogram Citra Biner dan RGB
Pada segmen terakhir tutorial, Anda akan memvisualisasikan dua domain citra yang berbeda: citra biner (dokumen) dan citra natural. Citra biner adalah citra yang nilai pikselnya sebagian besar $0$ atau $255$, sedangkan citra saluran warna dapat memiliki nilai piksel di rentang mana pun antara $0$ hingga $255$.
Menganalisis distribusi piksel dengan memplot histogram nilai intensitas dari sebuah citra adalah cara yang tepat untuk mengukur kemunculan setiap piksel pada citra tertentu. Untuk citra skala abu-abu 8-bit, ada 256 kemungkinan nilai intensitas. Oleh karena itu, untuk mempelajari perbedaan antara citra dokumen dan citra natural dalam domain distribusi piksel, Anda akan memplot dua histogram masing-masing untuk citra dokumen dan citra natural. Mengingat bahwa dokumen yang dapat dibaca memiliki tingkat kejarangan (sparsity), distribusi piksel pada citra dokumen ini umumnya akan condong (skewed).
Anda akan menggunakan modul opencv untuk memuat kedua citra, mengonversinya ke skala abu-abu dengan memberikan parameter $0$ saat membacanya, dan akhirnya mengubah ukurannya menjadi ukuran yang sama.
import cv2
lena_rgb = cv2.imread('lena.png')
lena_gray = cv2.cvtColor(lena_rgb,cv2.COLOR_BGR2GRAY)
lena_gray.shape
(512, 512)
binary = cv2.imread('binary.png')
binary.shape
(1394, 2190, 3)
binary = cv2.resize(binary,(512,512),cv2.INTER_CUBIC)
binary.shape
(512, 512, 3)
binary_gray = cv2.cvtColor(binary,cv2.COLOR_BGR2GRAY)
binary_gray.shape
(512, 512)
Mari visualisasikan kedua citra natural dan dokumen.
plt.figure(figsize=[10,10])
plt.subplot(121)
plt.imshow(lena_rgb[:,:,::-1])
plt.title("Natural Image")
plt.subplot(122)
plt.imshow(binary[:,:,::-1])
plt.title("Document Image")
plt.show()

Catatan: Anda akan menggunakan bins sama dengan $255$, karena total ada $255$ piksel dalam sebuah citra dan Anda ingin memvisualisasikan frekuensi setiap nilai piksel dari $0$ hingga $255$.
hist, edges = np.histogram(binary_gray,bins=range(255))
plt.figure(figsize=[10,8])
plt.bar(edges[:-1], hist, width = 0.8, color='#0504aa')
plt.xlim(min(edges), max(edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Document Image Histogram',fontsize=15)
plt.show()

hist, edges = np.histogram(lena_gray,bins=range(260))
plt.figure(figsize=[10,8])
plt.bar(edges[:-1], hist, width = 0.5, color='#0504aa')
plt.xlim(min(edges), max(edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Pixels',fontsize=15)
plt.ylabel('Frequency of Pixels',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Natural Image Histogram',fontsize=15)
plt.show()

Dari gambar di atas, Anda dapat mengamati bahwa citra natural tersebar di seluruh 256 intensitas dengan distribusi yang acak, sedangkan citra dokumen menunjukkan distribusi unimodal dan sebagian besar condong antara nilai piksel $0$ hingga $255$.
Kesimpulan
Selamat telah menyelesaikan tutorial ini.
Tutorial ini merupakan titik awal yang baik tentang bagaimana Anda dapat membuat histogram menggunakan matplotlib dengan bantuan numpy dan pandas.
Anda juga mempelajari bagaimana memanfaatkan kekuatan histogram untuk membedakan antara dua domain citra yang berbeda, yaitu citra dokumen dan citra natural.
Jika Anda ingin mempelajari lebih lanjut tentang teknik visualisasi data, pertimbangkan untuk mengikuti kursus Data Visualization with Matplotlib dari DataCamp.
Jangan ragu untuk mengajukan pertanyaan terkait tutorial ini di kolom komentar di bawah.
