This is the fullcode. I give ************** sign to highlight which part that causes the problem.
import pandas as pd
import numpy as np
import json
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
from dash.dependencies import Input, Output
from django_plotly_dash import DjangoDash
from django.db.models import Count
from schools.models import Provinsi, KotaKab, Kecamatan, Kelurahan
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css', dbc.themes.BOOTSTRAP]
app = DjangoDash('VisualisasiStatistikSekolah', external_stylesheets=external_stylesheets)
# ------------------------------------------------------------------------------
# Import and clean data
# print('kepanggil')
global data_provinsi, data_kokab, data_kec, data_kel, df_choropleth, geodata
data_provinsi = pd.DataFrame.from_records(Provinsi.objects.values('id', 'nama', 'institusi__sekolah__tingkat_sekolah__teks').annotate(Count('institusi__sekolah')).order_by('nama')).rename(
columns={
'institusi__sekolah__count': 'jumlah_sekolah',
'institusi__sekolah__tingkat_sekolah__teks': 'tingkat_sekolah'
}
)
data_kokab = pd.DataFrame.from_records(KotaKab.objects.values('id', 'provinsi_id', 'nama', 'institusi__sekolah__tingkat_sekolah__teks').annotate(Count('institusi__sekolah')).order_by('nama')).rename(
columns={
'institusi__sekolah__count': 'jumlah_sekolah',
'institusi__sekolah__tingkat_sekolah__teks': 'tingkat_sekolah'
}
)
data_kec = pd.DataFrame.from_records(Kecamatan.objects.values('id', 'kokab_id', 'nama', 'institusi__sekolah__tingkat_sekolah__teks').annotate(Count('institusi__sekolah')).order_by('nama')).rename(
columns={
'institusi__sekolah__count': 'jumlah_sekolah',
'institusi__sekolah__tingkat_sekolah__teks': 'tingkat_sekolah'
}
)
data_kel = pd.DataFrame.from_records(Kelurahan.objects.values('id', 'kecamatan_id', 'nama', 'institusi__sekolah__tingkat_sekolah__teks').annotate(Count('institusi__sekolah')).order_by('nama')).rename(
columns={
'institusi__sekolah__count': 'jumlah_sekolah',
'institusi__sekolah__tingkat_sekolah__teks': 'tingkat_sekolah'
}
)
with open('./dashboard/geodata/IDN_adm_1_province.json') as f:
geodata = json.load(f)
df_choropleth = data_provinsi.groupby(['nama']).sum().reset_index()
def get_sekolah_nasional():
df_jumlah_sekolah = data_provinsi.groupby(['tingkat_sekolah']).sum().reset_index()
custom_dict = {'SD': 0, 'SMP': 1, 'SMA': 2}
df_jumlah_sekolah.sort_values(by=['tingkat_sekolah'], key=lambda x: x.map(custom_dict), inplace=True)
return df_jumlah_sekolah
def get_axis_data(df_sekolah_per_wilayah):
data = df_sekolah_per_wilayah.fillna('tmp').groupby(['nama', 'tingkat_sekolah']).sum().reset_index().replace('tmp', np.nan)
x = data['nama'].unique()
y_sd = data.fillna('SD').groupby(['nama', 'tingkat_sekolah']).sum().reset_index()
y_smp = data.fillna('SMP').groupby(['nama', 'tingkat_sekolah']).sum().reset_index()
y_sma = data.fillna('SMA').groupby(['nama', 'tingkat_sekolah']).sum().reset_index()
y_sd = y_sd['jumlah_sekolah'].loc[y_sd['tingkat_sekolah'] == 'SD'].tolist()
y_smp = y_smp['jumlah_sekolah'].loc[y_smp['tingkat_sekolah'] == 'SMP'].tolist()
y_sma = y_sma['jumlah_sekolah'].loc[y_sma['tingkat_sekolah'] == 'SMA'].tolist()
return x, y_sd, y_smp, y_sma
def get_choropleth_data(tingkat_sekolah):
data_choropleth = data_provinsi.fillna(tingkat_sekolah)
data_choropleth = data_choropleth.loc[data_choropleth['tingkat_sekolah'] == tingkat_sekolah].groupby(['nama']).sum().reset_index()
return data_choropleth
# ------------------------------------------------------------------------------
# App layout
app.layout = html.Div([
dcc.Tabs([
dbc.Tab(label='Grafik Batang', children=[
dbc.Container([
dcc.Loading([
dbc.Row([
html.Div([
html.Label(['Tampilkan data per:',
dcc.Dropdown(id='select_filter',
options=[
{'label': 'Nasional', 'value': 'Nasional'},
{'label': 'Provinsi', 'value': 'Provinsi'},
{'label': 'Kota / Kabupaten', 'value': 'Kota / Kabupaten'},
{'label': 'Kecamatan', 'value': 'Kecamatan'},
{'label': 'Kelurahan', 'value': 'Kelurahan'}],
multi=False,
clearable=False,
value='Nasional',
placeholder='Pilih wilayah',
style={'font-weight': 'normal'})]),
], style={'width': '165px'}),
html.Div([
html.Label(id='select_provinsi',
children=['Pilih Provinsi:',
dcc.Dropdown(id='dropdown_provinsi',
multi=False,
clearable=False,
placeholder='Pilih Provinsi',
value=None,
disabled=True,
style={'font-weight': 'normal'})]),
], style={'width': '300px'}),
html.Div([
html.Label(id='select_kokab',
children=['Pilih Kota / Kabupaten:',
dcc.Dropdown(id='dropdown_kokab',
multi=False,
clearable=False,
placeholder='Pilih Kota / Kabupaten',
value=None,
disabled=True,
style={'font-weight': 'normal'})]),
], style={'width': '300px'}),
html.Div([
html.Label(id='select_kecamatan',
children=['Pilih Kecamatan:',
dcc.Dropdown(id='dropdown_kec',
multi=False,
clearable=False,
placeholder='Pilih Kecamatan:',
value=None,
disabled=True,
style={'font-weight': 'normal'})]),
], style={'width': '300px'}),
],
style={'display': 'flex', 'justify-content': 'space-evenly', 'padding': '20px'})
], type='default', color='#EAC763'),
html.Br(),
*******html.Div(id='output_container', children=[]),******************** # what I want to remove
], style={'background': 'white',
'border-radius': '5px',
'border': '1px solid #BEC2C4',
'box-shadow': '3px 3px 5px #EAC763',
'width': '1200px',
'height': '100px',
'margin-top': '20px'}
),
html.Br(),
dbc.Container([
dcc.Loading([
dbc.Col([
html.Div([
**************dcc.Graph(id='grafik_jlh_sekolah', figure={},****************
style={'backgroundColor': '#1a2d46', 'color': '#ffffff'}),
],
style={'padding': '10px'}),
],
style={'background': 'white',
'border-radius': '5px',
'border': '1px solid #BEC2C4',
'box-shadow': '3px 3px 5px #EAC763',
'width': '1200px',
'height': '500px'}
)
], type='graph', color='#EAC763')
])
]),
dbc.Tab(label='Peta Choropleth', children=[
dbc.Container([
dbc.Row([
dbc.Col([
dcc.RadioItems(id='radio_button_choropleth',
options=[{'label': 'Semua Tingkat', 'value': 'Semua Tingkat'},
{'label': 'SD', 'value': 'SD'},
{'label': 'SMP', 'value': 'SMP'},
{'label': 'SMA', 'value': 'SMA'}],
value='Semua Tingkat',
labelStyle={'display': 'block', 'padding': '5px'},
)],
style={'display': 'flex', 'align-items': 'center', 'margin-left': '50px'}
),
dbc.Col([
***********dcc.Graph(id='choropleth_sekolah',**************** # what I want to add
figure=dict(data=[go.Choropleth(geojson=geodata,
locations=df_choropleth.nama,
z=df_choropleth.jumlah_sekolah,
featureidkey='properties.NAME_1',
marker_line_color='black',
colorscale='YlGnBu',
colorbar_title='<b>Jumlah Sekolah<b>')],
layout=go.Layout(title='<b>Peta Persebaran Jumlah Sekolah</b>',
font=dict(color='black',
family='Nunito, sans-serif'),
geo_scope='asia',
geo_projection_scale=3,
geo_center_lat=0,
geo_center_lon=118,
margin={"r": 5, "t": 100, "l": 5, "b": 50}))
),
], style={'flex-grow': '1'}),
],
style={'background': 'white',
'border-radius': '5px',
'border': '1px solid #BEC2C4',
'box-shadow': '3px 3px 5px #EAC763',
'width': '1200px',
'height': '450px',
'margin-top': '20px',
'display': 'flex',
'justify-content': 'space-between'}
)
])
]),
])], style={'font-family': 'Nunito, sans-serif', 'font-weight': 'bold'}
)
# ------------------------------------------------------------------------------
# Connect the Plotly graphs with Dash Components
@app.callback(
[Output(component_id='dropdown_provinsi', component_property='options'),
Output(component_id='dropdown_provinsi', component_property='value'),
Output(component_id='dropdown_provinsi', component_property='disabled')],
[Input(component_id='select_filter', component_property='value')]
)
def update_dropdown_provinsi(selected_filter):
disabled = True
pilihan_provinsi = []
default_value = None
if (selected_filter != 'Nasional') and (selected_filter != 'Provinsi'):
pilihan_provinsi = []
daftar_provinsi = data_provinsi.drop_duplicates(subset='id', keep='first').reset_index()
default_value = '31'
disabled = False
for provinsi in daftar_provinsi.itertuples():
pilihan_provinsi.append({'label': provinsi.nama, 'value': provinsi.id})
return pilihan_provinsi, default_value, disabled
@app.callback(
[Output(component_id='dropdown_kokab', component_property='options'),
Output(component_id='dropdown_kokab', component_property='value'),
Output(component_id='dropdown_kokab', component_property='disabled')],
[Input(component_id='select_filter', component_property='value'),
Input(component_id='dropdown_provinsi', component_property='value')]
)
def update_dropdown_kokab(selected_filter, selected_provinsi):
disabled = True
pilihan_kokab = []
default_value = None
if (selected_filter == 'Kecamatan') or (selected_filter == 'Kelurahan'):
pilihan_kokab = []
daftar_kokab = data_kokab.loc[data_kokab['provinsi_id'] == selected_provinsi].drop_duplicates(subset='id', keep='first').reset_index()
default_value = daftar_kokab['id'][0]
disabled = False
for kokab in daftar_kokab.itertuples():
pilihan_kokab.append({'label': kokab.nama, 'value': kokab.id})
return pilihan_kokab, default_value, disabled
@app.callback(
[Output(component_id='dropdown_kec', component_property='options'),
Output(component_id='dropdown_kec', component_property='value'),
Output(component_id='dropdown_kec', component_property='disabled')],
[Input(component_id='select_filter', component_property='value'),
Input(component_id='dropdown_kokab', component_property='value')]
)
def update_dropdown_kec(selected_filter, selected_kokab):
disabled = True
pilihan_kecamatan = []
default_value = None
if (selected_filter == 'Kelurahan'):
pilihan_kecamatan = []
daftar_kecamatan = data_kec.loc[data_kec['kokab_id'] == selected_kokab].drop_duplicates(subset='id', keep='first').reset_index()
default_value = daftar_kecamatan['id'][0]
disabled = False
for kecamatan in daftar_kecamatan.itertuples():
pilihan_kecamatan.append({'label': kecamatan.nama, 'value': kecamatan.id})
return pilihan_kecamatan, default_value, disabled
**************
@app.callback(
[Output(component_id='output_container', component_property='children'), # what I want to remove
Output(component_id='grafik_jlh_sekolah', component_property='figure')],
[Input(component_id='select_filter', component_property='value'),
Input(component_id='dropdown_provinsi', component_property='value'),
Input(component_id='dropdown_kokab', component_property='value'),
Input(component_id='dropdown_kec', component_property='value')]
)**************
def update_graph(selected_filter, selected_provinsi, selected_kokab, selected_kec):
children = 'Filter yang dipilih: {}'.format(selected_filter)
figure = go.Figure()
figure.update_layout(
paper_bgcolor='white',
plot_bgcolor='rgba(0,0,0,0)',
font=dict(color='black',
family='Nunito, sans-serif'),
xaxis={'showgrid': False, 'title': '<b>' + selected_filter + '</b>', 'automargin': True},
yaxis={'showgrid': False, 'tickformat': ',d', 'automargin': True},
barmode='group',
title={
'text': '<b>JUMLAH SEKOLAH DI TINGKAT NASIONAL</b>',
'y': 0.9,
'x': 0.5,
'xanchor': 'center',
'yanchor': 'top'},
uniformtext_minsize=8,
uniformtext_mode='hide'
)
# Plotly Go
if selected_filter == 'Nasional':
data = get_sekolah_nasional()
figure.add_trace(
go.Bar(
x=data['tingkat_sekolah'],
y=data['jumlah_sekolah'],
marker_color='#EAC763',
text=data['jumlah_sekolah'],
textposition='auto',
name='Grafik Jumlah Sekolah',
)
)
elif selected_filter == 'Provinsi':
x, y_sd, y_smp, y_sma = get_axis_data(data_provinsi)
figure.add_trace(
go.Bar(
x=x,
y=y_sd,
marker_color='#942B25',
text=y_sd,
textposition='auto',
name='SD',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_smp,
marker_color='#081E43',
text=y_smp,
textposition='auto',
name='SMP',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_sma,
marker_color='#566D8D',
text=y_sma,
textposition='auto',
name='SMA',
)
)
figure.update_layout(title_text='<b>JUMLAH SEKOLAH PER PROVINSI</b>', xaxis={'tickangle': 45},)
elif selected_filter == 'Kota / Kabupaten':
nama_provinsi = data_provinsi.loc[data_provinsi['id'] == selected_provinsi]['nama'].unique()[0]
x, y_sd, y_smp, y_sma = get_axis_data(data_kokab.loc[data_kokab['provinsi_id'] == selected_provinsi])
if set(y_sd) == {0} and set(y_smp) == {0} and set(y_sma) == {0}:
figure.update_layout(
xaxis={'visible': False},
yaxis={'visible': False},
annotations=[dict(
text='Tidak ada sekolah<br>yang mengikuti NGTS<br>di wilayah ini',
xref='paper',
yref='paper',
showarrow=False,
font={'size': 28, 'color': '#786630'}
)]
)
else:
figure.add_trace(
go.Bar(
x=x,
y=y_sd,
marker_color='#942B25',
text=y_sd,
textposition='auto',
name='SD',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_smp,
marker_color='#081E43',
text=y_smp,
textposition='auto',
name='SMP',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_sma,
marker_color='#566D8D',
text=y_sma,
textposition='auto',
name='SMA',
)
)
figure.update_layout(title_text='<b>JUMLAH SEKOLAH PER KOTA / KABUPATEN<br>DI PROVINSI </b><b>' + nama_provinsi.upper() + '</b>')
elif selected_filter == 'Kecamatan':
nama_kokab = data_kokab.loc[data_kokab['id'] == selected_kokab]['nama'].unique()[0]
x, y_sd, y_smp, y_sma = get_axis_data(data_kec.loc[data_kec['kokab_id'] == selected_kokab])
if set(y_sd) == {0} and set(y_smp) == {0} and set(y_sma) == {0}:
figure.update_layout(
xaxis={'visible': False},
yaxis={'visible': False},
annotations=[dict(
text='Tidak ada sekolah<br>yang mengikuti NGTS<br>di wilayah ini',
xref='paper',
yref='paper',
showarrow=False,
font={'size': 28, 'color': '#786630'}
)]
)
else:
figure.add_trace(
go.Bar(
x=x,
y=y_sd,
marker_color='#942B25',
text=y_sd,
textposition='auto',
name='SD',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_smp,
marker_color='#081E43',
text=y_smp,
textposition='auto',
name='SMP',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_sma,
marker_color='#566D8D',
text=y_sma,
textposition='auto',
name='SMA',
)
)
figure.update_layout(title_text='<b>JUMLAH SEKOLAH PER KECAMATAN<br>DI </b><b>' + nama_kokab.upper() + '</b>')
else:
nama_kec = data_kec.loc[data_kec['id'] == selected_kec]['nama'].unique()[0]
x, y_sd, y_smp, y_sma = get_axis_data(data_kel.loc[data_kel['kecamatan_id'] == selected_kec])
if set(y_sd) == {0} and set(y_smp) == {0} and set(y_sma) == {0}:
figure.update_layout(
xaxis={'visible': False},
yaxis={'visible': False},
annotations=[dict(
text='Tidak ada sekolah<br>yang mengikuti NGTS<br>di wilayah ini',
xref='paper',
yref='paper',
showarrow=False,
font={'size': 28, 'color': '#786630'}
)]
)
else:
figure.add_trace(
go.Bar(
x=x,
y=y_sd,
marker_color='#942B25',
text=y_sd,
textposition='auto',
name='SD',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_smp,
marker_color='#081E43',
text=y_smp,
textposition='auto',
name='SMP',
)
)
figure.add_trace(
go.Bar(
x=x,
y=y_sma,
marker_color='#566D8D',
text=y_sma,
textposition='auto',
name='SMA',
)
)
figure.update_layout(title_text='<b>JUMLAH SEKOLAH PER KELURAHAN<br>DI KECAMATAN </b><b>' + nama_kec.upper() + '</b>')
return children, figure
**************
@app.callback(
[Output(component_id='choropleth_sekolah', component_property='figure')], # what I want to add
[Input(component_id='radio_button_choropleth', component_property='value')]
)**************
def update_choropleth(selected_button):
# print(selected_button)
figure = go.Figure()
figure.update_layout(
title='<b>Peta Persebaran Jumlah Sekolah</b>',
font=dict(color='black',
family='Nunito, sans-serif'),
geo_scope='asia',
geo_projection_scale=3,
geo_center_lat=0,
geo_center_lon=118,
margin={"r": 5, "t": 100, "l": 5, "b": 50}
)
if selected_button == 'Semua Tingkat':
figure.add_trace(
go.Choropleth(
geojson=geodata,
locations=df_choropleth.nama,
z=df_choropleth.jumlah_sekolah,
featureidkey='properties.NAME_1',
marker_line_color='black',
colorscale='YlGnBu',
colorbar_title='<b>Jumlah Sekolah<b>'
)
)
elif selected_button == 'SD':
data_choropleth = get_choropleth_data('SD')
# print(data_choropleth)
figure.add_trace(
go.Choropleth(
geojson=geodata,
locations=data_choropleth.nama,
z=data_choropleth.jumlah_sekolah,
featureidkey='properties.NAME_1',
marker_line_color='black',
colorscale='YlGnBu',
colorbar_title='<b>Jumlah Sekolah<b>'
)
)
elif selected_button == 'SMP':
data_choropleth = get_choropleth_data('SMP')
print(data_choropleth)
figure.add_trace(
go.Choropleth(
geojson=geodata,
locations=data_choropleth.nama,
z=data_choropleth.jumlah_sekolah,
featureidkey='properties.NAME_1',
marker_line_color='black',
colorscale='YlGnBu',
colorbar_title='<b>Jumlah Sekolah<b>'
)
)
else:
data_choropleth = get_choropleth_data('SMA')
# print(data_choropleth)
figure.add_trace(
go.Choropleth(
geojson=geodata,
locations=data_choropleth.nama,
z=data_choropleth.jumlah_sekolah,
featureidkey='properties.NAME_1',
marker_line_color='black',
colorscale='YlGnBu',
colorbar_title='<b>Jumlah Sekolah<b>'
)
)
return figure