Data Science + Python: Membuat Heat Map total Deposit Tokopedia per Kabupaten / Kota
Data science + Geographic Information System (GIS) - Membuat Heat Map total deposit Tokopedia per kabupaten / kota dengan Python - GeoPandas
Tutorial #1:
- Membuat grafik garis (line chart) menggunakan Matplotlib dan Seaborn.
- Plotting data geometry di atas peta dasar (basemap).
- Membuat heat map pada peta NKRI menggunakan data wilayah administrasi kab/kota seluruh Indonesia, diintegrasikan dengan data jumlah pengguna Tokopedia yang memiliki deposit per-kab/kota beserta jumlah total deposit per-kab/kota.
Import modules yang diperlukan.
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import contextily as cx
from sqlalchemy.engine import create_engine
import seaborn as sns
sns.set_style('darkgrid')
Load shapefile seluruh wilayah Indonesia pada level negara.
adm0 = gpd.read_file('../geoBoundaries-IDN-ADM0-all/geoBoundaries-IDN-ADM0_simplified.shp', encoding='UTF-8')
Load shapefile seluruh wilayah Indonesia pada level daerah tingkat 2 (kabupaten / kota)
adm2 = gpd.read_file('../geoBoundaries-IDN-ADM2-all/geoBoundaries-IDN-ADM2_simplified.shp', encoding='UTF-8')
Copy geodataframe adm2 ke tk2.
tk2 = adm2.copy(deep=True)
Tampilkan konten geodataframe tk2
tk2.head(3)
shapeName | shapeISO | shapeID | shapeGroup | shapeType | geometry | |
---|---|---|---|---|---|---|
0 | Aceh Barat | None | 22746128B65593111718524 | IDN | ADM2 | POLYGON ((96.49109 4.62277, 96.49445 4.60325, ... |
1 | Aceh Barat Daya | None | 22746128B227561513795 | IDN | ADM2 | MULTIPOLYGON (((96.80559 3.71758, 96.80286 3.7... |
2 | Aceh Besar | None | 22746128B90547447297479 | IDN | ADM2 | MULTIPOLYGON (((95.20544 5.28072, 95.20757 5.2... |
Membuta kolom baru 'kab_kota' dengan mengkopi kolom 'shapeName' dan mengubahnya menjadi huruf kecil saja
tk2['kab_kota'] = tk2['shapeName'].str.lower()
Cek konten tk2
tk2.head(2)
shapeName | shapeISO | shapeID | shapeGroup | shapeType | geometry | kab_kota | |
---|---|---|---|---|---|---|---|
0 | Aceh Barat | None | 22746128B65593111718524 | IDN | ADM2 | POLYGON ((96.49109 4.62277, 96.49445 4.60325, ... | aceh barat |
1 | Aceh Barat Daya | None | 22746128B227561513795 | IDN | ADM2 | MULTIPOLYGON (((96.80559 3.71758, 96.80286 3.7... | aceh barat daya |
Test pencarian nama kota di kolom 'kab_kota'.
for index, row in tk2.iterrows():
if 'bandung' in row['kab_kota']:
print(row['kab_kota'])
bandung bandung barat kota bandung
Membuat fungsi 'city_search()' untuk mencari data pengguna Tokopedia yang memiliki deposit berdasar alamat (kab/kota) dari database tokpe2020.
def city_search(city_name):
names = city_name.split(' ')
if names[0] == 'kota' and names[1] == 'jakarta':
city_name = city_name.replace('kota', '').strip()
print('__'+city_name+'__')
db_url = 'postgresql://localhost:5432/tokped2020'
con = create_engine(db_url).connect()
tokped = pd.read_sql("""SELECT * FROM tokopedia_users_deposit WHERE ts @@ phraseto_tsquery('indonesian', '""" + city_name +"""') """, con)
con.close()
return tokped
Test fungsi pencarian data pengguna tokopedia.
city = city_search('kota bandung')
Menampilkan pengguna Tokopedia dari kota Bandung dan memiliki deposit.
city[['location', 'deposit']].head(3)
location | deposit | |
---|---|---|
0 | KOTA BANDUNG , JAWA BARAT , Ujungberung, Indon... | 15551200.0 |
1 | Kota Bandung, Jawa Barat, Bandung, indonesia | 3932955.0 |
2 | KOTA BANDUNG , JAWA BARAT , Astanaanyar, Indon... | 2574000.0 |
Membuat fungsi untuk menghitung jumlah user dan total deposit per kab/kota.
def count_user_and_depo(df):
usr_depo = 0
usr_num = len(df)
for index, row in df.iterrows():
usr_depo += row['deposit']
# print(usr_num, f'{usr_depo:,}')
return usr_num, usr_depo
Test dengan city='kota bandung'
Hasilnya ada 133 users yang memiliki deposit, dengan total deposit Rp 50.701.470,-
num, depo = count_user_and_depo(city)
print(num, f'{depo:,}')
133 50,701,470.0
Menghitung jumlah user Tokopedia yang memiliki deposit per-kab/kota dan total deposit per-kab/kota tersebut untuk seluruh kab/kota di Indonesia.
for index, row in tk2.iterrows():
kab = row['kab_kota']
kab_tokped = city_search(kab)
num, depo = count_user_and_depo(kab_tokped)
tk2.loc[index, ['tokped_user_num']] = num
tk2.loc[index, ['tokped_user_depo_total']] = depo
__jakarta barat__ __jakarta pusat__ __jakarta selatan__ __jakarta timur__ __jakarta utara__
Tampilkan data kota yang ada user Tokopedia-nya saja.
tk2.loc[tk2.tokped_user_num > 0].head(3)
shapeName | shapeISO | shapeID | shapeGroup | shapeType | geometry | kab_kota | tokped_user_num | tokped_user_depo_total | |
---|---|---|---|---|---|---|---|---|---|
13 | Asahan | None | 22746128B26461090721788 | IDN | ADM2 | MULTIPOLYGON (((99.78860 3.11457, 99.78956 3.1... | asahan | 1.0 | 157430.0 |
15 | Badung | None | 22746128B76986430159502 | IDN | ADM2 | POLYGON ((115.25103 -8.31434, 115.24712 -8.317... | badung | 7.0 | 707990.0 |
16 | Balangan | None | 22746128B67876608948387 | IDN | ADM2 | POLYGON ((115.84992 -2.38862, 115.84662 -2.394... | balangan | 1.0 | 201611.0 |
Membuat grafik untuk menampilkan kab/kota yang memiliki total deposit Tokopedia lebih besar atau sama dengan Rp 5.000.000,- :
Paling banyak kota Jakarta Barat dengan total deposit Tokped lebih dari 100 juta Rupiah.
Kemudian, disusul Bandung hampir 80 juta Rupiah dan kota Surabaya 70-an juta Rupiah.
ax = sns.relplot(x='shapeName', y='tokped_user_depo_total', data=tk2.loc[tk2.tokped_user_depo_total >= 5000000], kind='line', height=8, aspect=1.8)
ax.tick_params(axis='x', rotation=70)
<seaborn.axisgrid.FacetGrid at 0x17b4b89d0>
Menampilkan jumlah user dari Kab/Kota yang memiliki total deposit lebih dari 5 juta Rupiah.
Bandung paling banyak dengan 250 user, disusul Jakarta Barat 200-an user, dan Jakarta Selatan sekitar 160 users.
ax = sns.relplot(x='shapeName', y='tokped_user_num', data=tk2.loc[tk2.tokped_user_depo_total >= 5000000], kind='line', height=8, aspect=1.8)
ax.tick_params(axis='x', rotation=70)
<seaborn.axisgrid.FacetGrid at 0x17999d2d0>
Lanjut hitung rata-rata deposit per-kab/kota untuk kab/kota yang memiliki total deposit lebih dari atau sama dengan 5 juta Rupiah.
Ternyata yang paling tinggi adalah Kota Bengkulu, woooow.
tk2['depo_avg'] = tk2['tokped_user_depo_total']/tk2['tokped_user_num']
ax = sns.relplot(x='shapeName', y='depo_avg', data=tk2.loc[tk2.tokped_user_depo_total >= 5000000], kind='line', height=8, aspect=1.8)
ax.tick_params(axis='x', rotation=70)
<seaborn.axisgrid.FacetGrid at 0x1798cb790>
Menampilkan distribusi total deposit per-kab/kota.
sns.displot(tk2['tokped_user_depo_total'], kind='kde')
<seaborn.axisgrid.FacetGrid at 0x17b69e790>
Selanjutnya kita akan membuat Heat Map untuk menggambarkan besaran deposit Tokped yang dimiliki tiap kab/kota di Indonesia. Tiap wilayah kab/kota diberi warna yang sesuai dengan besaran depositnya.
Fungsi untuk plot geometry kabupaten / kota diatas geometry NKRI
def gplot(tk2, nkri, cmap):
fig, ax = plt.subplots(figsize=(15, 5))
tk2.plot(
ax=ax,
# column='tokped_user_depo_total',
linewidth=0.5,
cmap=cmap,
legend=True,
zorder=3
)
nkri.plot(
ax=ax,
color='white',
edgecolor='skyblue',
linewidth=0.1,
zorder=1)
ax.tick_params(labelsize = 14)
cx.add_basemap(ax, crs=tk2.crs.to_string(), source=cx.providers.Esri.NatGeoWorldMap, zoom=8)
Test menampilkan wilayah kab/kota seluruh NKRI.
gplot(tk2, adm0, 'Set1')
Plot geometry kabupaten / kota dengan argument:
- tk2 : geometry kabupaten / kota
- col : kolom yang digunakan untuk menentukan warna per-kab/kota
- cmap: colormap Matplotlib yang dipilih
- zoom: level zoom basemap
def gplot(tk2, col, cmap, zoom):
fig, ax = plt.subplots(figsize=(15, 5))
tk2.plot(
ax=ax,
column=col,
linewidth=0,
cmap=cmap,
legend=True
)
ax.tick_params(labelsize = 8)
ax.grid(False)
# cx.add_basemap(ax, crs=tk2.crs.to_string(), source=cx.providers.Esri.NatGeoWorldMap, zoom=zoom)
# cx.add_basemap(ax, crs=tk2.crs.to_string(), source=cx.providers.CartoDB.DarkMatter, zoom=zoom)
cx.add_basemap(ax, crs=tk2.crs.to_string(), source=cx.providers.CartoDB.Positron, zoom=zoom)
# gplot(tk2.loc[tk2.tokped_user_depo_total >= 0], adm1, adm0, 'viridis')
gplot(tk2.loc[tk2.tokped_user_depo_total >= 0], 'tokped_user_depo_total', 'gnuplot_r', 8)
gplot(tk2.loc[tk2.tokped_user_depo_total >= 5000000], 'tokped_user_num', 'gnuplot_r', 8)
gplot(tk2.loc[tk2.tokped_user_depo_total >= 1000000], 'tokped_user_depo_total', 'gnuplot2_r', 8)
gplot(tk2.loc[tk2.tokped_user_depo_total >= 10000000], 'tokped_user_depo_total', 'cool', 8)
gplot(tk2.loc[tk2.tokped_user_depo_total >= 50000000],'tokped_user_depo_total', 'cool', 8)
Demikian.
Semoga bermanfaat.
Comments